mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	Merge pull request #9748 from TeamNewPipe/feat/av1-tags
Add whitelist to only retrieve supported YouTube itags/streams
This commit is contained in:
		| @@ -1,6 +1,6 @@ | |||||||
| package org.schabi.newpipe.player.resolver; | package org.schabi.newpipe.player.resolver; | ||||||
|  |  | ||||||
| import static org.schabi.newpipe.util.ListHelper.getNonTorrentStreams; | import static org.schabi.newpipe.util.ListHelper.getPlayableStreams; | ||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| @@ -68,12 +68,14 @@ public class AudioPlaybackResolver implements PlaybackResolver { | |||||||
|      */ |      */ | ||||||
|     @Nullable |     @Nullable | ||||||
|     private Stream getAudioSource(@NonNull final StreamInfo info) { |     private Stream getAudioSource(@NonNull final StreamInfo info) { | ||||||
|         final List<AudioStream> audioStreams = getNonTorrentStreams(info.getAudioStreams()); |         final List<AudioStream> audioStreams = getPlayableStreams( | ||||||
|  |                 info.getAudioStreams(), info.getServiceId()); | ||||||
|         if (!audioStreams.isEmpty()) { |         if (!audioStreams.isEmpty()) { | ||||||
|             final int index = ListHelper.getDefaultAudioFormat(context, audioStreams); |             final int index = ListHelper.getDefaultAudioFormat(context, audioStreams); | ||||||
|             return getStreamForIndex(index, audioStreams); |             return getStreamForIndex(index, audioStreams); | ||||||
|         } else { |         } else { | ||||||
|             final List<VideoStream> videoStreams = getNonTorrentStreams(info.getVideoStreams()); |             final List<VideoStream> videoStreams = getPlayableStreams( | ||||||
|  |                     info.getVideoStreams(), info.getServiceId()); | ||||||
|             if (!videoStreams.isEmpty()) { |             if (!videoStreams.isEmpty()) { | ||||||
|                 final int index = ListHelper.getDefaultResolutionIndex(context, videoStreams); |                 final int index = ListHelper.getDefaultResolutionIndex(context, videoStreams); | ||||||
|                 return getStreamForIndex(index, videoStreams); |                 return getStreamForIndex(index, videoStreams); | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ import java.util.Optional; | |||||||
|  |  | ||||||
| import static com.google.android.exoplayer2.C.TIME_UNSET; | import static com.google.android.exoplayer2.C.TIME_UNSET; | ||||||
| import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams; | import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams; | ||||||
| import static org.schabi.newpipe.util.ListHelper.getNonTorrentStreams; | import static org.schabi.newpipe.util.ListHelper.getPlayableStreams; | ||||||
|  |  | ||||||
| public class VideoPlaybackResolver implements PlaybackResolver { | public class VideoPlaybackResolver implements PlaybackResolver { | ||||||
|     private static final String TAG = VideoPlaybackResolver.class.getSimpleName(); |     private static final String TAG = VideoPlaybackResolver.class.getSimpleName(); | ||||||
| @@ -72,8 +72,8 @@ public class VideoPlaybackResolver implements PlaybackResolver { | |||||||
|  |  | ||||||
|         // Create video stream source |         // Create video stream source | ||||||
|         final List<VideoStream> videoStreamsList = ListHelper.getSortedStreamVideosList(context, |         final List<VideoStream> videoStreamsList = ListHelper.getSortedStreamVideosList(context, | ||||||
|                 getNonTorrentStreams(info.getVideoStreams()), |                 getPlayableStreams(info.getVideoStreams(), info.getServiceId()), | ||||||
|                 getNonTorrentStreams(info.getVideoOnlyStreams()), false, true); |                 getPlayableStreams(info.getVideoOnlyStreams(), info.getServiceId()), false, true); | ||||||
|         final int index; |         final int index; | ||||||
|         if (videoStreamsList.isEmpty()) { |         if (videoStreamsList.isEmpty()) { | ||||||
|             index = -1; |             index = -1; | ||||||
| @@ -100,7 +100,8 @@ public class VideoPlaybackResolver implements PlaybackResolver { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Create optional audio stream source |         // Create optional audio stream source | ||||||
|         final List<AudioStream> audioStreams = getNonTorrentStreams(info.getAudioStreams()); |         final List<AudioStream> audioStreams = getPlayableStreams( | ||||||
|  |                 info.getAudioStreams(), info.getServiceId()); | ||||||
|         final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get( |         final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get( | ||||||
|                 ListHelper.getDefaultAudioFormat(context, audioStreams)); |                 ListHelper.getDefaultAudioFormat(context, audioStreams)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| package org.schabi.newpipe.util; | package org.schabi.newpipe.util; | ||||||
|  |  | ||||||
|  | import static org.schabi.newpipe.extractor.ServiceList.YouTube; | ||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.content.SharedPreferences; | import android.content.SharedPreferences; | ||||||
| import android.net.ConnectivityManager; | import android.net.ConnectivityManager; | ||||||
| @@ -42,6 +44,21 @@ public final class ListHelper { | |||||||
|     // 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"); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * List of supported YouTube Itag ids. | ||||||
|  |      * The original order is kept. | ||||||
|  |      * @see {@link org.schabi.newpipe.extractor.services.youtube.ItagItem#ITAG_LIST} | ||||||
|  |      */ | ||||||
|  |     private static final List<Integer> SUPPORTED_ITAG_IDS = | ||||||
|  |             List.of( | ||||||
|  |                     17, 36, // video v3GPP | ||||||
|  |                     18, 34, 35, 59, 78, 22, 37, 38, // video MPEG4 | ||||||
|  |                     43, 44, 45, 46, // video webm | ||||||
|  |                     171, 172, 139, 140, 141, 249, 250, 251, // audio | ||||||
|  |                     160, 133, 134, 135, 212, 136, 298, 137, 299, 266, // video only | ||||||
|  |                     278, 242, 243, 244, 245, 246, 247, 248, 271, 272, 302, 303, 308, 313, 315 | ||||||
|  |             ); | ||||||
|  |  | ||||||
|     private ListHelper() { } |     private ListHelper() { } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -121,7 +138,7 @@ public final class ListHelper { | |||||||
|      */ |      */ | ||||||
|     @NonNull |     @NonNull | ||||||
|     public static <S extends Stream> List<S> getStreamsOfSpecifiedDelivery( |     public static <S extends Stream> List<S> getStreamsOfSpecifiedDelivery( | ||||||
|             final List<S> streamList, |             @Nullable final List<S> streamList, | ||||||
|             final DeliveryMethod deliveryMethod) { |             final DeliveryMethod deliveryMethod) { | ||||||
|         return getFilteredStreamList(streamList, |         return getFilteredStreamList(streamList, | ||||||
|                 stream -> stream.getDeliveryMethod() == deliveryMethod); |                 stream -> stream.getDeliveryMethod() == deliveryMethod); | ||||||
| @@ -136,23 +153,31 @@ public final class ListHelper { | |||||||
|      */ |      */ | ||||||
|     @NonNull |     @NonNull | ||||||
|     public static <S extends Stream> List<S> getUrlAndNonTorrentStreams( |     public static <S extends Stream> List<S> getUrlAndNonTorrentStreams( | ||||||
|             final List<S> streamList) { |             @Nullable final List<S> streamList) { | ||||||
|         return getFilteredStreamList(streamList, |         return getFilteredStreamList(streamList, | ||||||
|                 stream -> stream.isUrl() && stream.getDeliveryMethod() != DeliveryMethod.TORRENT); |                 stream -> stream.isUrl() && stream.getDeliveryMethod() != DeliveryMethod.TORRENT); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Return a {@link Stream} list which only contains non-torrent streams. |      * Return a {@link Stream} list which only contains streams which can be played by the player. | ||||||
|  |      * <br> | ||||||
|  |      * Some formats are not supported. For more info, see {@link #SUPPORTED_ITAG_IDS}. | ||||||
|  |      * Torrent streams are also removed, because they cannot be retrieved. | ||||||
|      * |      * | ||||||
|      * @param streamList the original stream list |  | ||||||
|      * @param <S>        the item type's class that extends {@link Stream} |      * @param <S>        the item type's class that extends {@link Stream} | ||||||
|      * @return a stream list which only contains non-torrent streams |      * @param streamList the original stream list | ||||||
|  |      * @param serviceId | ||||||
|  |      * @return a stream list which only contains streams that can be played the player | ||||||
|      */ |      */ | ||||||
|     @NonNull |     @NonNull | ||||||
|     public static <S extends Stream> List<S> getNonTorrentStreams( |     public static <S extends Stream> List<S> getPlayableStreams( | ||||||
|             final List<S> streamList) { |             @Nullable final List<S> streamList, final int serviceId) { | ||||||
|  |         final int youtubeServiceId = YouTube.getServiceId(); | ||||||
|         return getFilteredStreamList(streamList, |         return getFilteredStreamList(streamList, | ||||||
|                 stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT); |                 stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT | ||||||
|  |                         && (serviceId != youtubeServiceId | ||||||
|  |                         || stream.getItagItem() == null | ||||||
|  |                         || SUPPORTED_ITAG_IDS.contains(stream.getItagItem().id))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -199,7 +224,7 @@ public final class ListHelper { | |||||||
|      * @return a new stream list filtered using the given predicate |      * @return a new stream list filtered using the given predicate | ||||||
|      */ |      */ | ||||||
|     private static <S extends Stream> List<S> getFilteredStreamList( |     private static <S extends Stream> List<S> getFilteredStreamList( | ||||||
|             final List<S> streamList, |             @Nullable final List<S> streamList, | ||||||
|             final Predicate<S> streamListPredicate) { |             final Predicate<S> streamListPredicate) { | ||||||
|         if (streamList == null) { |         if (streamList == null) { | ||||||
|             return Collections.emptyList(); |             return Collections.emptyList(); | ||||||
| @@ -210,7 +235,7 @@ public final class ListHelper { | |||||||
|                 .collect(Collectors.toList()); |                 .collect(Collectors.toList()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static String computeDefaultResolution(final Context context, final int key, |     private static String computeDefaultResolution(@NonNull final Context context, final int key, | ||||||
|                                                    final int value) { |                                                    final int value) { | ||||||
|         final SharedPreferences preferences = |         final SharedPreferences preferences = | ||||||
|                 PreferenceManager.getDefaultSharedPreferences(context); |                 PreferenceManager.getDefaultSharedPreferences(context); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox