Optimize track selection

pull/605/head
jhengazuki 5 months ago
parent c95e023932
commit 63249734a3
  1. 25
      app/schemas/com.fongmi.android.tv.db.AppDatabase/35.json
  2. 33
      app/src/main/java/com/fongmi/android/tv/bean/Track.java
  3. 3
      app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java
  4. 9
      app/src/main/java/com/fongmi/android/tv/db/Migrations.java
  5. 19
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  6. 32
      app/src/main/java/com/fongmi/android/tv/player/exo/ExoUtil.java
  7. 59
      app/src/main/java/com/fongmi/android/tv/player/exo/TrackUtil.java
  8. 7
      app/src/main/java/com/fongmi/android/tv/ui/dialog/TrackDialog.java

@ -1,8 +1,8 @@
{
"formatVersion": 1,
"database": {
"version": 34,
"identityHash": "f6dff07c7842200b0224662b90261e07",
"version": 35,
"identityHash": "8191bb223b1cde184fbb43d20d39d851",
"entities": [
{
"tableName": "Keep",
@ -120,7 +120,7 @@
},
{
"tableName": "Track",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `group` INTEGER NOT NULL, `track` INTEGER NOT NULL, `key` TEXT, `name` TEXT, `selected` INTEGER NOT NULL)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `key` TEXT, `name` TEXT, `format` TEXT, `selected` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
@ -134,18 +134,6 @@
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "group",
"columnName": "group",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "track",
"columnName": "track",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "key",
"columnName": "key",
@ -156,6 +144,11 @@
"columnName": "name",
"affinity": "TEXT"
},
{
"fieldPath": "format",
"columnName": "format",
"affinity": "TEXT"
},
{
"fieldPath": "selected",
"columnName": "selected",
@ -410,7 +403,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f6dff07c7842200b0224662b90261e07')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8191bb223b1cde184fbb43d20d39d851')"
]
}
}

@ -2,7 +2,6 @@ package com.fongmi.android.tv.bean;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.PrimaryKey;
@ -18,15 +17,15 @@ public class Track {
@PrimaryKey(autoGenerate = true)
private int id;
private int type;
private int group;
private int track;
private String key;
private String name;
private String format;
private boolean selected;
public Track(int type, String name) {
public Track(int type, String name, String format) {
this.type = type;
this.name = name;
this.format = format;
}
public int getId() {
@ -45,27 +44,11 @@ public class Track {
this.type = type;
}
public int getGroup() {
return group;
}
public void setGroup(int group) {
this.group = group;
}
public int getTrack() {
return track;
}
public void setTrack(int track) {
this.track = track;
}
public String getKey() {
return key;
}
public void setKey(@NonNull String key) {
public void setKey(String key) {
this.key = key;
}
@ -77,6 +60,14 @@ public class Track {
this.name = name;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public boolean isSelected() {
return selected;
}

@ -35,7 +35,7 @@ import java.util.Locale;
@Database(entities = {Keep.class, Site.class, Live.class, Track.class, Config.class, Device.class, History.class}, version = AppDatabase.VERSION)
public abstract class AppDatabase extends RoomDatabase {
public static final int VERSION = 34;
public static final int VERSION = 35;
public static final String NAME = "tv";
public static final String SYMBOL = "@@@";
@ -95,6 +95,7 @@ public abstract class AppDatabase extends RoomDatabase {
.addMigrations(Migrations.MIGRATION_31_32)
.addMigrations(Migrations.MIGRATION_32_33)
.addMigrations(Migrations.MIGRATION_33_34)
.addMigrations(Migrations.MIGRATION_34_35)
.fallbackToDestructiveMigration(true)
.allowMainThreadQueries().build();
}

@ -40,4 +40,13 @@ public class Migrations {
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Track_key_type` ON `Track` (`key`, `type`)");
}
};
public static final Migration MIGRATION_34_35 = new Migration(34, 35) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("DROP TABLE Track");
database.execSQL("CREATE TABLE Track (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `type` INTEGER NOT NULL, `key` TEXT, `name` TEXT, `format` TEXT, `selected` INTEGER NOT NULL)");
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Track_key_type` ON `Track` (`key`, `type`)");
}
};
}

@ -53,6 +53,7 @@ import com.fongmi.android.tv.impl.SessionCallback;
import com.fongmi.android.tv.player.danmaku.DanPlayer;
import com.fongmi.android.tv.player.exo.ErrorMsgProvider;
import com.fongmi.android.tv.player.exo.ExoUtil;
import com.fongmi.android.tv.player.exo.TrackUtil;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.ImgUtil;
@ -104,6 +105,7 @@ public class Players implements Player.Listener, ParseCallback {
private Drm drm;
private Sub sub;
private boolean initTrack;
private int decode;
private int retry;
@ -203,6 +205,7 @@ public class Players implements Player.Listener, ParseCallback {
public void reset() {
removeTimeoutCheck();
initTrack = false;
retry = 0;
}
@ -252,7 +255,7 @@ public class Players implements Player.Listener, ParseCallback {
}
public boolean haveTrack(int type) {
return exoPlayer != null && ExoUtil.haveTrack(exoPlayer.getCurrentTracks(), type);
return exoPlayer != null && TrackUtil.count(exoPlayer.getCurrentTracks(), type) > 0;
}
public boolean haveDanmaku() {
@ -502,19 +505,13 @@ public class Players implements Player.Listener, ParseCallback {
}
public void resetTrack() {
if (exoPlayer != null) ExoUtil.resetTrack(exoPlayer);
if (exoPlayer != null) TrackUtil.reset(exoPlayer);
}
public void setTrack(List<Track> tracks) {
for (Track track : tracks) setTrack(track);
}
private void setTrack(Track item) {
if (item.isSelected()) {
ExoUtil.selectTrack(exoPlayer, item.getGroup(), item.getTrack());
} else {
ExoUtil.deselectTrack(exoPlayer, item.getGroup(), item.getTrack());
}
if (initTrack) return;
if (exoPlayer != null && !tracks.isEmpty()) TrackUtil.setTrackSelection(exoPlayer, tracks);
initTrack = true;
}
private void setPlaybackState(int state) {

@ -10,11 +10,8 @@ import android.view.accessibility.CaptioningManager;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.TrackSelectionOverride;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.DefaultLoadControl;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.LoadControl;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.source.MediaSource;
@ -70,16 +67,6 @@ public class ExoUtil {
return Setting.isCaption() ? CaptionStyleCompat.createFromCaptionStyle(((CaptioningManager) App.get().getSystemService(Context.CAPTIONING_SERVICE)).getUserStyle()) : new CaptionStyleCompat(Color.WHITE, Color.TRANSPARENT, Color.TRANSPARENT, CaptionStyleCompat.EDGE_TYPE_OUTLINE, Color.BLACK, null);
}
public static boolean haveTrack(Tracks tracks, int type) {
int count = 0;
for (Tracks.Group trackGroup : tracks.getGroups()) if (trackGroup.getType() == type) count += trackGroup.length;
return count > 0;
}
public static void resetTrack(ExoPlayer player) {
player.setTrackSelectionParameters(player.getTrackSelectionParameters().buildUpon().clearOverrides().build());
}
public static void setSubtitleView(PlayerView exo) {
exo.getSubtitleView().setStyle(getCaptionStyle());
exo.getSubtitleView().setApplyEmbeddedFontSizes(false);
@ -126,23 +113,4 @@ public class ExoUtil {
if (subs != null) for (Sub sub : subs) configs.add(sub.config());
return configs;
}
public static void selectTrack(ExoPlayer player, int groupIndex, int trackIndex) {
Tracks currentTracks = player.getCurrentTracks();
if (groupIndex >= currentTracks.getGroups().size()) return;
Tracks.Group trackGroupInfo = currentTracks.getGroups().get(groupIndex);
if (trackIndex < 0 || trackIndex >= trackGroupInfo.length) return;
TrackSelectionOverride override = new TrackSelectionOverride(trackGroupInfo.getMediaTrackGroup(), trackIndex);
player.setTrackSelectionParameters(player.getTrackSelectionParameters().buildUpon().setOverrideForType(override).build());
}
public static void deselectTrack(ExoPlayer player, int groupIndex, int trackIndex) {
Tracks currentTracks = player.getCurrentTracks();
if (groupIndex >= currentTracks.getGroups().size()) return;
Tracks.Group trackGroupInfo = currentTracks.getGroups().get(groupIndex);
List<Integer> trackIndices = new ArrayList<>();
for (int i = 0; i < trackGroupInfo.length; i++) if (i != trackIndex && trackGroupInfo.isTrackSelected(i)) trackIndices.add(i);
TrackSelectionOverride override = new TrackSelectionOverride(trackGroupInfo.getMediaTrackGroup(), trackIndices);
player.setTrackSelectionParameters(player.getTrackSelectionParameters().buildUpon().setOverrideForType(override).build());
}
}

@ -0,0 +1,59 @@
package com.fongmi.android.tv.player.exo;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.TrackSelectionOverride;
import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.Tracks;
import androidx.media3.exoplayer.ExoPlayer;
import com.fongmi.android.tv.bean.Track;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TrackUtil {
private record TrackInfo(Tracks.Group trackGroup, int trackIndex) {
}
public static int count(Tracks tracks, int type) {
return tracks.getGroups().stream().filter(trackGroup -> trackGroup.getType() == type).mapToInt(trackGroup -> trackGroup.length).sum();
}
public static void reset(ExoPlayer player) {
player.setTrackSelectionParameters(player.getTrackSelectionParameters().buildUpon().clearOverrides().build());
}
private static TrackInfo find(ExoPlayer player, Track track) {
Tracks currentTracks = player.getCurrentTracks();
for (Tracks.Group trackGroup : currentTracks.getGroups()) {
if (trackGroup.getType() != track.getType()) continue;
for (int i = 0; i < trackGroup.length; i++) {
if (track.getFormat().equals(trackGroup.getTrackFormat(i).id)) {
return new TrackInfo(trackGroup, i);
}
}
}
return null;
}
public static void setTrackSelection(ExoPlayer player, List<Track> tracks) {
Map<Integer, TrackGroup> mediaGroupMapByType = new HashMap<>();
Map<Integer, Integer> selectedIndexMapByType = new HashMap<>();
for (Track track : tracks) {
TrackInfo info = find(player, track);
if (info == null) continue;
int type = info.trackGroup.getType();
mediaGroupMapByType.put(type, info.trackGroup.getMediaTrackGroup());
if (track.isSelected()) selectedIndexMapByType.put(type, info.trackIndex);
}
TrackSelectionParameters.Builder builder = player.getTrackSelectionParameters().buildUpon();
mediaGroupMapByType.forEach((type, mediaGroup) -> {
Integer selectedIndex = selectedIndexMapByType.get(type);
List<Integer> indices = selectedIndex != null ? List.of(selectedIndex) : List.of();
builder.setOverrideForType(new TrackSelectionOverride(mediaGroup, indices));
});
player.setTrackSelectionParameters(builder.build());
}
}

@ -13,6 +13,7 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.Tracks;
import androidx.media3.ui.DefaultTrackNameProvider;
@ -115,10 +116,10 @@ public final class TrackDialog extends BaseDialog implements TrackAdapter.OnClic
Tracks.Group trackGroup = groups.get(i);
if (trackGroup.getType() != type) continue;
for (int j = 0; j < trackGroup.length; j++) {
Track item = new Track(type, provider.getTrackName(trackGroup.getTrackFormat(j)));
Format format = trackGroup.getTrackFormat(j);
String name = provider.getTrackName(format);
Track item = new Track(type, name, format.id);
item.setSelected(trackGroup.isTrackSelected(j));
item.setGroup(i);
item.setTrack(j);
items.add(item);
}
}

Loading…
Cancel
Save