diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 9e9909e85..2e0a421da 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -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)); diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index 534d4fddd..71071d997 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -46,10 +46,10 @@ public final class ListHelper { List.of(MediaFormat.MP3, MediaFormat.M4A, MediaFormat.WEBMA); // Use a Set for better performance private static final Set HIGH_RESOLUTION_LIST = Set.of("1440p", "2160p"); - // Audio track types in order of priotity. 0=lowest, n=highest + // Audio track types in order of priority. 0=lowest, n=highest private static final List AUDIO_TRACK_TYPE_RANKING = List.of(AudioTrackType.DESCRIPTIVE, AudioTrackType.DUBBED, AudioTrackType.ORIGINAL); - // Audio track types in order of priotity when descriptive audio is preferred. + // Audio track types in order of priority when descriptive audio is preferred. private static final List AUDIO_TRACK_TYPE_RANKING_DESCRIPTIVE = List.of(AudioTrackType.ORIGINAL, AudioTrackType.DUBBED, AudioTrackType.DESCRIPTIVE); @@ -696,7 +696,7 @@ public final class ListHelper { } } - private static boolean isLimitingDataUsage(final Context context) { + static boolean isLimitingDataUsage(@NonNull final Context context) { return getResolutionLimit(context) != null; } @@ -738,7 +738,7 @@ public final class ListHelper { /** * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate. * - *

The prefered stream will be ordered last.

+ *

The preferred stream will be ordered last.

* * @param context app context * @return Comparator @@ -753,7 +753,7 @@ public final class ListHelper { /** * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate. * - *

The prefered stream will be ordered last.

+ *

The preferred stream will be ordered last.

* * @param defaultFormat the default format to look for * @param limitDataUsage choose low bitrate audio stream @@ -795,7 +795,7 @@ public final class ListHelper { *
  • Language is English
  • * * - *

    The prefered track will be ordered last.

    + *

    The preferred track will be ordered last.

    * * @param context App context * @return Comparator @@ -832,7 +832,7 @@ public final class ListHelper { *
  • Language is English
  • * * - *

    The prefered track will be ordered last.

    + *

    The preferred track will be ordered last.

    * * @param preferredLanguage Preferred audio stream language * @param preferOriginalAudio Get the original audio track regardless of its language diff --git a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java index 9415135cf..75d9a3892 100644 --- a/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/SecondaryStreamHelper.java @@ -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 { @@ -25,14 +28,19 @@ public class SecondaryStreamHelper { } /** - * Find the correct audio stream for the desired video stream. + * Finds an audio stream compatible with the provided video-only stream, so that the two streams + * can be combined in a single file by the downloader. If there are multiple available audio + * streams, chooses either the highest or the lowest quality one based on + * {@link ListHelper#isLimitingDataUsage(Context)}. * + * @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 + * @param videoStream desired video-ONLY stream + * @return the selected audio stream or null if a candidate was not found */ @Nullable - public static AudioStream getAudioStreamFor(@NonNull final List audioStreams, + public static AudioStream getAudioStreamFor(@NonNull final Context context, + @NonNull final List audioStreams, @NonNull final VideoStream videoStream) { final MediaFormat mediaFormat = videoStream.getFormat(); if (mediaFormat == null) { @@ -41,33 +49,36 @@ public class SecondaryStreamHelper { 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 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() {