mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 00:20:32 +00:00
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.
This commit is contained in:
parent
ba3afd1e35
commit
f8c3ec4be7
@ -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,12 @@ 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());
|
||||||
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());
|
||||||
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()),
|
||||||
getNonTorrentStreams(info.getVideoOnlyStreams()), false, true);
|
getPlayableStreams(info.getVideoOnlyStreams()), false, true);
|
||||||
final int index;
|
final int index;
|
||||||
if (videoStreamsList.isEmpty()) {
|
if (videoStreamsList.isEmpty()) {
|
||||||
index = -1;
|
index = -1;
|
||||||
@ -100,7 +100,7 @@ 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());
|
||||||
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
|
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
|
||||||
ListHelper.getDefaultAudioFormat(context, audioStreams));
|
ListHelper.getDefaultAudioFormat(context, audioStreams));
|
||||||
|
|
||||||
|
@ -42,6 +42,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 +136,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 +151,28 @@ 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 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
|
* @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) {
|
||||||
return getFilteredStreamList(streamList,
|
return getFilteredStreamList(streamList,
|
||||||
stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT);
|
stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT
|
||||||
|
&& (stream.getItagItem() == null
|
||||||
|
|| SUPPORTED_ITAG_IDS.contains(stream.getItagItem().id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +219,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 +230,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);
|
||||||
|
Loading…
Reference in New Issue
Block a user