getFilteredAudioStreams: Use language and tracktype for grouping

Instead of the `trackId`, which is only ever set for the `youtube`
backend, we use the audio stream language and tracktype. These are
`null` for youtube videos without language selector, leading to a
single audio stream being selected.

For media.ccc.de, the language on audio tracks is always set
correctly, meaning for a video with German and English tracks we get
two groups, which are then sorted according to the preferences of
users.

I verified that youtube still works by playing
https://www.youtube.com/watch?v=8bDRVP9xSfc
and selecting the different audio streams, going to background etc.
and also tried with a video without multiple audio tracks.

For media.ccc.de, it will select the right audio track as well.

Unfortunately, media.ccc.de returns videos with multiple audio track
muxed into the video itself, which is still buggy because the wrong
track is selected by default. This is gonna be fixed/worked around in
the next commit.
This commit is contained in:
Profpatsch 2024-01-07 19:35:18 +01:00
parent 189c35e89f
commit e242ad42a8
1 changed files with 34 additions and 34 deletions

View File

@ -6,6 +6,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -282,41 +283,40 @@ public final class ListHelper {
@NonNull final Context context,
@NonNull final List<AudioStream> audioStreams) {
final HashMap<String, AudioStream> collectedStreams = new HashMap<>();
for (final AudioStream stream : audioStreams) {
if (// we cant play torrents
stream.getDeliveryMethod() == DeliveryMethod.TORRENT
// This format is not supported by ExoPlayer when returned as HLS streams,
// so we can't play streams using this format and this delivery method.
|| (stream.getDeliveryMethod() == DeliveryMethod.HLS
&& stream.getFormat() == MediaFormat.OPUS)) {
continue;
}
// TODO: since media.ccc.de does not have a trackId,
// only the first audio is ever returned here
String trackId = stream.getAudioTrackId();
if (trackId == null) {
trackId = "";
}
final AudioStream presentStream = collectedStreams.get(trackId);
if (presentStream == null
|| getAudioFormatComparator(context).compare(stream, presentStream) > 0) {
collectedStreams.put(trackId, stream);
}
}
// Filter unknown audio tracks if there are multiple tracks
if (collectedStreams.size() > 1) {
collectedStreams.remove("");
}
// Sort collected streams by name
return collectedStreams.values().stream().sorted(getAudioTrackNameComparator(context))
final List<AudioStream> result = audioStreams
.stream()
// remove torrents we cant play
.filter(stream ->
!(
// we cant play torrents
stream.getDeliveryMethod() == DeliveryMethod.TORRENT
// This format is not supported by ExoPlayer when returned as HLS streams,
// so we can't play streams using this format and this delivery method.
|| (stream.getDeliveryMethod() == DeliveryMethod.HLS
&& stream.getFormat() == MediaFormat.OPUS))
)
.collect(Collectors.groupingBy(
stream ->
// Streams grouped by their locale+audiotype
// (e.g. en+original, fr+dubbed)
new Pair<Locale, AudioTrackType>(
stream.getAudioLocale(),
stream.getAudioTrackType()
),
// from each list of grouped streams,
// we select the one that has the most fitting audio type & quality
Collectors.maxBy(getAudioFormatComparator(context))
))
.entrySet()
.stream()
// get streams and remove bins that dont contain streams
.flatMap(e -> e.getValue().stream())
// sort the preferred audio stream last
.sorted(getAudioTrackComparator(context))
.collect(Collectors.toList());
return result;
}
/**