mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-11-04 09:13:00 +00:00 
			
		
		
		
	Merge pull request #10446 from AudricV/dl_improve_video_audio_stream_selection
Improve audio stream selection for video-only streams in the downloader
This commit is contained in:
		@@ -267,8 +267,8 @@ public class DownloadDialog extends DialogFragment
 | 
				
			|||||||
            if (!videoStreams.get(i).isVideoOnly()) {
 | 
					            if (!videoStreams.get(i).isVideoOnly()) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            final AudioStream audioStream = SecondaryStreamHelper
 | 
					            final AudioStream audioStream = SecondaryStreamHelper.getAudioStreamFor(
 | 
				
			||||||
                    .getAudioStreamFor(audioStreams.getStreamsList(), videoStreams.get(i));
 | 
					                    context, audioStreams.getStreamsList(), videoStreams.get(i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (audioStream != null) {
 | 
					            if (audioStream != null) {
 | 
				
			||||||
                secondaryStreams.append(i, new SecondaryStreamHelper<>(audioStreams, audioStream));
 | 
					                secondaryStreams.append(i, new SecondaryStreamHelper<>(audioStreams, audioStream));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,10 +46,10 @@ public final class ListHelper {
 | 
				
			|||||||
            List.of(MediaFormat.MP3, MediaFormat.M4A, MediaFormat.WEBMA);
 | 
					            List.of(MediaFormat.MP3, MediaFormat.M4A, MediaFormat.WEBMA);
 | 
				
			||||||
    // Use a Set for better performance
 | 
					    // Use a Set for better performance
 | 
				
			||||||
    private static final Set<String> HIGH_RESOLUTION_LIST = Set.of("1440p", "2160p");
 | 
					    private static final Set<String> 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<AudioTrackType> AUDIO_TRACK_TYPE_RANKING =
 | 
					    private static final List<AudioTrackType> AUDIO_TRACK_TYPE_RANKING =
 | 
				
			||||||
            List.of(AudioTrackType.DESCRIPTIVE, AudioTrackType.DUBBED, AudioTrackType.ORIGINAL);
 | 
					            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<AudioTrackType> AUDIO_TRACK_TYPE_RANKING_DESCRIPTIVE =
 | 
					    private static final List<AudioTrackType> AUDIO_TRACK_TYPE_RANKING_DESCRIPTIVE =
 | 
				
			||||||
            List.of(AudioTrackType.ORIGINAL, AudioTrackType.DUBBED, AudioTrackType.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;
 | 
					        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.
 | 
					     * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * <p>The prefered stream will be ordered last.</p>
 | 
					     * <p>The preferred stream will be ordered last.</p>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param context app context
 | 
					     * @param context app context
 | 
				
			||||||
     * @return Comparator
 | 
					     * @return Comparator
 | 
				
			||||||
@@ -753,7 +753,7 @@ public final class ListHelper {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate.
 | 
					     * Get a {@link Comparator} to compare {@link AudioStream}s by their format and bitrate.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * <p>The prefered stream will be ordered last.</p>
 | 
					     * <p>The preferred stream will be ordered last.</p>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param defaultFormat  the default format to look for
 | 
					     * @param defaultFormat  the default format to look for
 | 
				
			||||||
     * @param limitDataUsage choose low bitrate audio stream
 | 
					     * @param limitDataUsage choose low bitrate audio stream
 | 
				
			||||||
@@ -795,7 +795,7 @@ public final class ListHelper {
 | 
				
			|||||||
     * <li>Language is English</li>
 | 
					     * <li>Language is English</li>
 | 
				
			||||||
     * </ol>
 | 
					     * </ol>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * <p>The prefered track will be ordered last.</p>
 | 
					     * <p>The preferred track will be ordered last.</p>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param context App context
 | 
					     * @param context App context
 | 
				
			||||||
     * @return Comparator
 | 
					     * @return Comparator
 | 
				
			||||||
@@ -832,7 +832,7 @@ public final class ListHelper {
 | 
				
			|||||||
     * <li>Language is English</li>
 | 
					     * <li>Language is English</li>
 | 
				
			||||||
     * </ol>
 | 
					     * </ol>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * <p>The prefered track will be ordered last.</p>
 | 
					     * <p>The preferred track will be ordered last.</p>
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param preferredLanguage      Preferred audio stream language
 | 
					     * @param preferredLanguage      Preferred audio stream language
 | 
				
			||||||
     * @param preferOriginalAudio    Get the original audio track regardless of its language
 | 
					     * @param preferOriginalAudio    Get the original audio track regardless of its language
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
package org.schabi.newpipe.util;
 | 
					package org.schabi.newpipe.util;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.NonNull;
 | 
					import androidx.annotation.NonNull;
 | 
				
			||||||
import androidx.annotation.Nullable;
 | 
					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.extractor.stream.VideoStream;
 | 
				
			||||||
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
 | 
					import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Comparator;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class SecondaryStreamHelper<T extends Stream> {
 | 
					public class SecondaryStreamHelper<T extends Stream> {
 | 
				
			||||||
@@ -25,14 +28,19 @@ public class SecondaryStreamHelper<T extends Stream> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 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 audioStreams list of audio streams
 | 
				
			||||||
     * @param videoStream  desired video ONLY stream
 | 
					     * @param videoStream  desired video-ONLY stream
 | 
				
			||||||
     * @return selected audio stream or null if a candidate was not found
 | 
					     * @return the selected audio stream or null if a candidate was not found
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @Nullable
 | 
					    @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) {
 | 
					                                                @NonNull final VideoStream videoStream) {
 | 
				
			||||||
        final MediaFormat mediaFormat = videoStream.getFormat();
 | 
					        final MediaFormat mediaFormat = videoStream.getFormat();
 | 
				
			||||||
        if (mediaFormat == null) {
 | 
					        if (mediaFormat == null) {
 | 
				
			||||||
@@ -41,33 +49,36 @@ public class SecondaryStreamHelper<T extends Stream> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        switch (mediaFormat) {
 | 
					        switch (mediaFormat) {
 | 
				
			||||||
            case WEBM:
 | 
					            case WEBM:
 | 
				
			||||||
            case MPEG_4:// ¿is mpeg-4 DASH?
 | 
					            case MPEG_4: // Is MPEG-4 DASH?
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                return null;
 | 
					                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) {
 | 
					        Comparator<AudioStream> comparator = ListHelper.getAudioFormatComparator(
 | 
				
			||||||
            if (audio.getFormat() == (m4v ? MediaFormat.M4A : MediaFormat.WEBMA)) {
 | 
					                m4v ? MediaFormat.M4A : MediaFormat.WEBMA, isLimitingDataUsage);
 | 
				
			||||||
                return audio;
 | 
					        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 audioStreams.get(preferredAudioStreamIndex);
 | 
				
			||||||
            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;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public T getStream() {
 | 
					    public T getStream() {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user