diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java index 93772608..042c5cd1 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java @@ -15,7 +15,6 @@ import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.StreamExtractor; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.SubtitlesStream; @@ -215,11 +214,6 @@ public class MediaCCCStreamExtractor extends StreamExtractor { return StreamType.VIDEO_STREAM; } - @Override - public StreamInfoItem getNextStream() { - return null; - } - @Override public StreamInfoItemsCollector getRelatedStreams() { return new StreamInfoItemsCollector(getServiceId()); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java index e4a3ac92..4fda7827 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java @@ -21,7 +21,6 @@ import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamExtractor; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.SubtitlesStream; @@ -242,11 +241,6 @@ public class PeertubeStreamExtractor extends StreamExtractor { return StreamType.VIDEO_STREAM; } - @Override - public StreamInfoItem getNextStream() { - return null; - } - @Override public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException { final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java index a8cc7e13..6aee297d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java @@ -19,7 +19,6 @@ import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.StreamExtractor; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.SubtitlesStream; @@ -261,11 +260,6 @@ public class SoundcloudStreamExtractor extends StreamExtractor { return StreamType.AUDIO_STREAM; } - @Override - public StreamInfoItem getNextStream() throws IOException, ExtractionException { - return null; - } - @Override public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException { StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index dca5e5fb..94d7b8e7 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -21,14 +21,14 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoPatternsManager; import org.schabi.newpipe.extractor.services.youtube.ItagItem; -import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; +import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Frameset; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamExtractor; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; +import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.SubtitlesStream; @@ -52,7 +52,10 @@ import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.*; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonResponse; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromNavigationEndpoint; import static org.schabi.newpipe.extractor.utils.JsonUtils.EMPTY_STRING; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; @@ -508,12 +511,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { return StreamType.VIDEO_STREAM; } - @Override - public StreamInfoItem getNextStream() throws ExtractionException { - assertPageFetched(); - - if (getAgeLimit() != NO_AGE_LIMIT) return null; - + private StreamInfoItemExtractor getNextStream() throws ExtractionException { try { final JsonObject firstWatchNextItem = initialData.getObject("contents") .getObject("twoColumnWatchNextResults").getObject("secondaryResults") @@ -527,11 +525,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { final JsonObject videoInfo = firstWatchNextItem.getObject("compactAutoplayRenderer") .getArray("contents").getObject(0).getObject("compactVideoRenderer"); - final TimeAgoParser timeAgoParser = getTimeAgoParser(); - StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); - - collector.commit(new YoutubeStreamInfoItemExtractor(videoInfo, timeAgoParser)); - return collector.getItems().get(0); + return new YoutubeStreamInfoItemExtractor(videoInfo, getTimeAgoParser()); } catch (Exception e) { throw new ParsingException("Could not get next video", e); } @@ -544,13 +538,19 @@ public class YoutubeStreamExtractor extends StreamExtractor { if (getAgeLimit() != NO_AGE_LIMIT) return null; try { - StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); - JsonArray results = initialData.getObject("contents").getObject("twoColumnWatchNextResults") + final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); + + final StreamInfoItemExtractor nextStream = getNextStream(); + if (nextStream != null) { + collector.commit(nextStream); + } + + final JsonArray results = initialData.getObject("contents").getObject("twoColumnWatchNextResults") .getObject("secondaryResults").getObject("secondaryResults").getArray("results"); final TimeAgoParser timeAgoParser = getTimeAgoParser(); - for (Object ul : results) { + for (final Object ul : results) { if (((JsonObject) ul).has("compactVideoRenderer")) { collector.commit(new YoutubeStreamInfoItemExtractor(((JsonObject) ul).getObject("compactVideoRenderer"), timeAgoParser)); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java index 2cc64ab7..f48bb913 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java @@ -30,13 +30,14 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.utils.Parser; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Locale; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Scrapes information from a video/audio streaming service (eg, YouTube). */ @@ -309,23 +310,12 @@ public abstract class StreamExtractor extends Extractor { */ public abstract StreamType getStreamType() throws ParsingException; - /** - * Should return the url of the next stream. NewPipe will automatically play - * the next stream if the user wants that. - * If the next stream is is not available simply return null - * - * @return the InfoItem of the next stream - * @throws IOException - * @throws ExtractionException - */ - public abstract StreamInfoItem getNextStream() throws IOException, ExtractionException; - /** * Should return a list of streams related to the current handled. Many services show suggested * streams. If you don't like suggested streams you should implement them anyway since they can - * be disabled by the user later in the frontend. - * This list MUST NOT contain the next available video as this should be return through getNextStream() - * If it is not available simply return null + * be disabled by the user later in the frontend. The first related stream might be what was + * previously known as a next stream. + * If related streams aren't available simply return {@code null}. * * @return a list of InfoItems showing the related videos/streams * @throws IOException @@ -337,11 +327,10 @@ public abstract class StreamExtractor extends Extractor { * Should return a list of Frameset object that contains preview of stream frames * * @return list of preview frames or empty list if frames preview is not supported or not found for specified stream - * @throws IOException * @throws ExtractionException */ @Nonnull - public List