Skip to content

Commit

Permalink
chore: support preferred languages on HLS redundant stream. (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
guoen21 authored Oct 25, 2023
1 parent 5b1351a commit 1461fb6
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 14 deletions.
7 changes: 7 additions & 0 deletions demos/main/src/main/assets/media.exolist.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@
"name": "WWE live, wwe",
"uri": "https://dummy.imggaming.com/video?id=111449&live=true&dash=&realm=dce.wwe&usr=&pwd="
},
{
"name": "WWE vod, wwe",
"uri": "https://dummy.imggaming.com/video?id=530182&live=&dash=&realm=dce.wwe&usr=&pwd=",
"subtitle_uri": "https://dve-subtitles.imggaming.com/530182/741299/vtt/subtitle-en-US-199647-1697490152197.vtt",
"subtitle_mime_type": "text/vtt",
"subtitle_language": "en"
},
{
"name": "450830 DRM, adjara",
"uri": "https://dummy.imggaming.com/video?id=450830&live=&dash=true&realm=dce.adjara&usr=&pwd="
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ public boolean onChildClick(
List<MediaItem> mediaItems = playlistHolder.mediaItems;
if (result != null && result.localConfiguration != null) {
Log.i(TAG, "fetch video from backend - " + originUri.getQuery() + " >> " + result.localConfiguration.uri);
if (playlistHolder.mediaItems.get(0).localConfiguration.subtitleConfigurations != null) {
result = result.buildUpon()
.setSubtitleConfigurations(playlistHolder.mediaItems.get(0).localConfiguration.subtitleConfigurations)
.build();
}
mediaItems = Collections.singletonList(result);
}
IntentUtil.addToIntent(mediaItems, intent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import androidx.media3.common.endeavor.WebUtil;
import androidx.media3.common.util.Log;
import androidx.media3.exoplayer.source.TrackGroupArray;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import androidx.media3.exoplayer.trackselection.MappingTrackSelector;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import com.google.common.collect.ImmutableList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
Expand Down Expand Up @@ -43,6 +45,7 @@ public TrackCollector(TrackSelector callback) {
// May update status for the blacklistUntilTimes, videoTrackSelection, preferredAudioName and so on.
public void onMappedTrackInfoChanged(
MappingTrackSelector.MappedTrackInfo mappedTrackInfo,
DefaultTrackSelector.Parameters parameters,
ExoTrackSelection.Definition[] overrideDefinitions) {
this.noGroupConstraint = true;
this.videoUseFixedSelection = false;
Expand Down Expand Up @@ -72,25 +75,22 @@ public void onMappedTrackInfoChanged(
Format format = overrideDefinitions[i].group.getFormat(overrideDefinitions[i].tracks[0]);
preferredAudioName = getFormatName(format);
} else if (preferredAudioName == null) {
preferredAudioName = "";
for (int j = 0; j < trackGroups.length; j++) {
TrackGroup track = trackGroups.get(j);
for (int k = 0; k < track.length; k++) {
Format format = track.getFormat(k);
if ((format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0) {
preferredAudioName = getFormatName(format);
break;
}
}
preferredAudioName = getParametersPreferred(trackGroups, parameters.preferredAudioLanguages);
if (preferredAudioName == null) {
preferredAudioName = getDefaultPreferred(trackGroups);
}
}
} else if (C.TRACK_TYPE_TEXT == mappedTrackInfo.getRendererType(i)) {
// Init the preferred text name.
if (overrideDefinitions[i] != null) {
Format format = overrideDefinitions[i].group.getFormat(overrideDefinitions[i].tracks[0]);
preferredTextName = getFormatName(format);
} else {
preferredTextName = "";
} else if (preferredTextName == null) {
TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(i);
preferredTextName = getParametersPreferred(trackGroups, parameters.preferredTextLanguages);
if (preferredTextName == null) {
preferredTextName = "";
}
}
}
}
Expand Down Expand Up @@ -305,6 +305,55 @@ private TrackGroupArray getTrackGroups(int trackType) {
return new TrackGroupArray();
}

private String getParametersPreferred(
TrackGroupArray trackGroups,
ImmutableList<String> preferredLanguages) {
if (preferredLanguages.size() == 0) {
return null;
}

int bestLanguageScore = 0;
int bestLanguageIndex = Integer.MAX_VALUE;
String preferredName = null;
for (int i = 0; i < trackGroups.length; i++) {
TrackGroup trackGroup = trackGroups.get(i);
if (trackGroup.length == 0) {
continue;
}
Format format = trackGroup.getFormat(0);
for (int j = 0; j < preferredLanguages.size(); j++) {
int score = DefaultTrackSelector.getFormatLanguageScore(
format,
preferredLanguages.get(j),
/* allowUndeterminedFormatLanguage= */ false);
if (score > 0) {
if (j < bestLanguageIndex || (j == bestLanguageIndex && score > bestLanguageScore)) {
bestLanguageIndex = j;
bestLanguageScore = score;
preferredName = getFormatName(format);
}
break;
}
}
}
return preferredName;
}

private String getDefaultPreferred(TrackGroupArray trackGroups) {
String preferredName = "";
for (int i = 0; i < trackGroups.length; i++) {
TrackGroup trackGroup = trackGroups.get(i);
for (int j = 0; j < trackGroup.length; j++) {
Format format = trackGroup.getFormat(j);
if ((format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0) {
preferredName = getFormatName(format);
break;
}
}
}
return preferredName;
}

private static int getMetadataEntrySize(Format format) {
return (format == null || format.metadata == null ? 0 : format.metadata.length());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2388,7 +2388,7 @@ private void setParametersInternal(Parameters parameters) {
}
int rendererCount = mappedTrackInfo.getRendererCount();
// May update status of track collector for the preferredAudioName, blacklistUntilTimes and so on.
trackCollector.onMappedTrackInfoChanged(mappedTrackInfo, getOverrideDefinitions(mappedTrackInfo, parameters));
trackCollector.onMappedTrackInfoChanged(mappedTrackInfo, parameters, getOverrideDefinitions(mappedTrackInfo, parameters));
ExoTrackSelection.@NullableType Definition[] definitions =
selectAllTracks(
mappedTrackInfo,
Expand Down Expand Up @@ -3161,7 +3161,7 @@ protected static String normalizeUndeterminedLanguageToNull(@Nullable String lan
* 1 if the format language is undetermined and such a match is allowed, and a score of 0 if
* the languages don't match at all.
*/
protected static int getFormatLanguageScore(
public static int getFormatLanguageScore(
Format format, @Nullable String language, boolean allowUndeterminedFormatLanguage) {
if (!TextUtils.isEmpty(language) && language.equals(format.language)) {
// Full literal match of non-empty languages, including matches of an explicit "und" query.
Expand Down

0 comments on commit 1461fb6

Please sign in to comment.