Skip to content

Commit f8c3ec4

Browse files
committed
Use a whitelist to filter all streams retrieved by the extractor.
NewPipe Extractor now extracts all YouTube Itags and therefore only those which can be handled by the player need to be retrieved from the list of all available streams.
1 parent ba3afd1 commit f8c3ec4

3 files changed

Lines changed: 36 additions & 16 deletions

File tree

app/src/main/java/org/schabi/newpipe/player/resolver/AudioPlaybackResolver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.schabi.newpipe.player.resolver;
22

3-
import static org.schabi.newpipe.util.ListHelper.getNonTorrentStreams;
3+
import static org.schabi.newpipe.util.ListHelper.getPlayableStreams;
44

55
import android.content.Context;
66
import android.util.Log;
@@ -68,12 +68,12 @@ public MediaSource resolve(@NonNull final StreamInfo info) {
6868
*/
6969
@Nullable
7070
private Stream getAudioSource(@NonNull final StreamInfo info) {
71-
final List<AudioStream> audioStreams = getNonTorrentStreams(info.getAudioStreams());
71+
final List<AudioStream> audioStreams = getPlayableStreams(info.getAudioStreams());
7272
if (!audioStreams.isEmpty()) {
7373
final int index = ListHelper.getDefaultAudioFormat(context, audioStreams);
7474
return getStreamForIndex(index, audioStreams);
7575
} else {
76-
final List<VideoStream> videoStreams = getNonTorrentStreams(info.getVideoStreams());
76+
final List<VideoStream> videoStreams = getPlayableStreams(info.getVideoStreams());
7777
if (!videoStreams.isEmpty()) {
7878
final int index = ListHelper.getDefaultResolutionIndex(context, videoStreams);
7979
return getStreamForIndex(index, videoStreams);

app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
import static com.google.android.exoplayer2.C.TIME_UNSET;
3131
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
32-
import static org.schabi.newpipe.util.ListHelper.getNonTorrentStreams;
32+
import static org.schabi.newpipe.util.ListHelper.getPlayableStreams;
3333

3434
public class VideoPlaybackResolver implements PlaybackResolver {
3535
private static final String TAG = VideoPlaybackResolver.class.getSimpleName();
@@ -72,8 +72,8 @@ public MediaSource resolve(@NonNull final StreamInfo info) {
7272

7373
// Create video stream source
7474
final List<VideoStream> videoStreamsList = ListHelper.getSortedStreamVideosList(context,
75-
getNonTorrentStreams(info.getVideoStreams()),
76-
getNonTorrentStreams(info.getVideoOnlyStreams()), false, true);
75+
getPlayableStreams(info.getVideoStreams()),
76+
getPlayableStreams(info.getVideoOnlyStreams()), false, true);
7777
final int index;
7878
if (videoStreamsList.isEmpty()) {
7979
index = -1;
@@ -100,7 +100,7 @@ public MediaSource resolve(@NonNull final StreamInfo info) {
100100
}
101101

102102
// Create optional audio stream source
103-
final List<AudioStream> audioStreams = getNonTorrentStreams(info.getAudioStreams());
103+
final List<AudioStream> audioStreams = getPlayableStreams(info.getAudioStreams());
104104
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
105105
ListHelper.getDefaultAudioFormat(context, audioStreams));
106106

app/src/main/java/org/schabi/newpipe/util/ListHelper.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ public final class ListHelper {
4242
// Use a Set for better performance
4343
private static final Set<String> HIGH_RESOLUTION_LIST = Set.of("1440p", "2160p");
4444

45+
/**
46+
* List of supported YouTube Itag ids.
47+
* The original order is kept.
48+
* @see {@link org.schabi.newpipe.extractor.services.youtube.ItagItem#ITAG_LIST}
49+
*/
50+
private static final List<Integer> SUPPORTED_ITAG_IDS =
51+
List.of(
52+
17, 36, // video v3GPP
53+
18, 34, 35, 59, 78, 22, 37, 38, // video MPEG4
54+
43, 44, 45, 46, // video webm
55+
171, 172, 139, 140, 141, 249, 250, 251, // audio
56+
160, 133, 134, 135, 212, 136, 298, 137, 299, 266, // video only
57+
278, 242, 243, 244, 245, 246, 247, 248, 271, 272, 302, 303, 308, 313, 315
58+
);
59+
4560
private ListHelper() { }
4661

4762
/**
@@ -121,7 +136,7 @@ public static int getDefaultAudioFormat(final Context context,
121136
*/
122137
@NonNull
123138
public static <S extends Stream> List<S> getStreamsOfSpecifiedDelivery(
124-
final List<S> streamList,
139+
@Nullable final List<S> streamList,
125140
final DeliveryMethod deliveryMethod) {
126141
return getFilteredStreamList(streamList,
127142
stream -> stream.getDeliveryMethod() == deliveryMethod);
@@ -136,23 +151,28 @@ public static <S extends Stream> List<S> getStreamsOfSpecifiedDelivery(
136151
*/
137152
@NonNull
138153
public static <S extends Stream> List<S> getUrlAndNonTorrentStreams(
139-
final List<S> streamList) {
154+
@Nullable final List<S> streamList) {
140155
return getFilteredStreamList(streamList,
141156
stream -> stream.isUrl() && stream.getDeliveryMethod() != DeliveryMethod.TORRENT);
142157
}
143158

144159
/**
145-
* Return a {@link Stream} list which only contains non-torrent streams.
160+
* Return a {@link Stream} list which only contains streams which can be played by the player.
161+
* <br>
162+
* Some formats are not supported. For more info, see {@link #SUPPORTED_ITAG_IDS}.
163+
* Torrent streams are also removed, because they cannot be retrieved.
146164
*
147165
* @param streamList the original stream list
148166
* @param <S> the item type's class that extends {@link Stream}
149-
* @return a stream list which only contains non-torrent streams
167+
* @return a stream list which only contains streams that can be played the player
150168
*/
151169
@NonNull
152-
public static <S extends Stream> List<S> getNonTorrentStreams(
153-
final List<S> streamList) {
170+
public static <S extends Stream> List<S> getPlayableStreams(
171+
@Nullable final List<S> streamList) {
154172
return getFilteredStreamList(streamList,
155-
stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT);
173+
stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT
174+
&& (stream.getItagItem() == null
175+
|| SUPPORTED_ITAG_IDS.contains(stream.getItagItem().id)));
156176
}
157177

158178
/**
@@ -199,7 +219,7 @@ public static List<VideoStream> getSortedStreamVideosList(
199219
* @return a new stream list filtered using the given predicate
200220
*/
201221
private static <S extends Stream> List<S> getFilteredStreamList(
202-
final List<S> streamList,
222+
@Nullable final List<S> streamList,
203223
final Predicate<S> streamListPredicate) {
204224
if (streamList == null) {
205225
return Collections.emptyList();
@@ -210,7 +230,7 @@ private static <S extends Stream> List<S> getFilteredStreamList(
210230
.collect(Collectors.toList());
211231
}
212232

213-
private static String computeDefaultResolution(final Context context, final int key,
233+
private static String computeDefaultResolution(@NonNull final Context context, final int key,
214234
final int value) {
215235
final SharedPreferences preferences =
216236
PreferenceManager.getDefaultSharedPreferences(context);

0 commit comments

Comments
 (0)