Use ListHelper to get secondary audio streams for video-only streams

Instead of searching for the first audio stream matching a compatible media
format, this change makes SecondaryStreamHelper.getAudioStreamFor use methods
isLimitingDataUsage, getAudioFormatComparator and getAudioIndexByHighestRank of
ListHelper to get an audio stream which can be muxed into a video-only stream,
if available.

This allows users to download videos with the highest audio quality available
if no resolution limit on mobile data usage has been set.

The order of formats used to search a compatible audio stream has been kept.
This commit is contained in:
AudricV 2023-09-24 18:23:00 +02:00
parent cdb79ef78a
commit 77bbbc88f8
No known key found for this signature in database
GPG key ID: DA92EC7905614198
2 changed files with 29 additions and 21 deletions

View file

@ -267,8 +267,8 @@ public class DownloadDialog extends DialogFragment
if (!videoStreams.get(i).isVideoOnly()) {
continue;
}
final AudioStream audioStream = SecondaryStreamHelper
.getAudioStreamFor(audioStreams.getStreamsList(), videoStreams.get(i));
final AudioStream audioStream = SecondaryStreamHelper.getAudioStreamFor(
context, audioStreams.getStreamsList(), videoStreams.get(i));
if (audioStream != null) {
secondaryStreams.append(i, new SecondaryStreamHelper<>(audioStreams, audioStream));

View file

@ -1,5 +1,7 @@
package org.schabi.newpipe.util;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -9,6 +11,7 @@ import org.schabi.newpipe.extractor.stream.Stream;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
import java.util.Comparator;
import java.util.List;
public class SecondaryStreamHelper<T extends Stream> {
@ -27,12 +30,14 @@ public class SecondaryStreamHelper<T extends Stream> {
/**
* Find the correct audio stream for the desired video stream.
*
* @param context Android context
* @param audioStreams list of audio streams
* @param videoStream desired video ONLY stream
* @return selected audio stream or null if a candidate was not found
*/
@Nullable
public static AudioStream getAudioStreamFor(@NonNull final List<AudioStream> audioStreams,
public static AudioStream getAudioStreamFor(@NonNull final Context context,
@NonNull final List<AudioStream> audioStreams,
@NonNull final VideoStream videoStream) {
final MediaFormat mediaFormat = videoStream.getFormat();
if (mediaFormat == null) {
@ -41,33 +46,36 @@ public class SecondaryStreamHelper<T extends Stream> {
switch (mediaFormat) {
case WEBM:
case MPEG_4:// ¿is mpeg-4 DASH?
case MPEG_4: // Is MPEG-4 DASH?
break;
default:
return null;
}
final boolean m4v = (mediaFormat == MediaFormat.MPEG_4);
final boolean m4v = mediaFormat == MediaFormat.MPEG_4;
final boolean isLimitingDataUsage = ListHelper.isLimitingDataUsage(context);
for (final AudioStream audio : audioStreams) {
if (audio.getFormat() == (m4v ? MediaFormat.M4A : MediaFormat.WEBMA)) {
return audio;
Comparator<AudioStream> comparator = ListHelper.getAudioFormatComparator(
m4v ? MediaFormat.M4A : MediaFormat.WEBMA, isLimitingDataUsage);
int preferredAudioStreamIndex = ListHelper.getAudioIndexByHighestRank(
audioStreams, comparator);
if (preferredAudioStreamIndex == -1) {
if (m4v) {
return null;
}
comparator = ListHelper.getAudioFormatComparator(
MediaFormat.WEBMA_OPUS, isLimitingDataUsage);
preferredAudioStreamIndex = ListHelper.getAudioIndexByHighestRank(
audioStreams, comparator);
if (preferredAudioStreamIndex == -1) {
return null;
}
}
if (m4v) {
return null;
}
// retry, but this time in reverse order
for (int i = audioStreams.size() - 1; i >= 0; i--) {
final AudioStream audio = audioStreams.get(i);
if (audio.getFormat() == MediaFormat.WEBMA_OPUS) {
return audio;
}
}
return null;
return audioStreams.get(preferredAudioStreamIndex);
}
public T getStream() {