88import org .schabi .newpipe .extractor .exceptions .ExtractionException ;
99import org .schabi .newpipe .extractor .exceptions .ParsingException ;
1010import org .schabi .newpipe .extractor .linkhandler .ListLinkHandler ;
11+ import org .schabi .newpipe .extractor .localization .DateWrapper ;
1112import org .schabi .newpipe .extractor .localization .TimeAgoParser ;
1213import org .schabi .newpipe .extractor .playlist .PlaylistExtractor ;
1314import org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper ;
15+ import org .schabi .newpipe .extractor .services .youtube .linkHandler .YoutubeStreamLinkHandlerFactory ;
1416import org .schabi .newpipe .extractor .stream .StreamInfoItem ;
17+ import org .schabi .newpipe .extractor .stream .StreamInfoItemExtractor ;
1518import org .schabi .newpipe .extractor .stream .StreamInfoItemsCollector ;
19+ import org .schabi .newpipe .extractor .stream .StreamType ;
1620import org .schabi .newpipe .extractor .utils .Utils ;
1721
1822import java .io .IOException ;
1923
2024import javax .annotation .Nonnull ;
25+ import javax .annotation .Nullable ;
2126
2227import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .fixThumbnailUrl ;
2328import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getJsonResponse ;
@@ -152,34 +157,47 @@ public long getStreamCount() throws ParsingException {
152157
153158 @ Nonnull
154159 @ Override
155- public String getSubChannelName () throws ParsingException {
160+ public String getSubChannelName () {
156161 return "" ;
157162 }
158163
159164 @ Nonnull
160165 @ Override
161- public String getSubChannelUrl () throws ParsingException {
166+ public String getSubChannelUrl () {
162167 return "" ;
163168 }
164169
165170 @ Nonnull
166171 @ Override
167- public String getSubChannelAvatarUrl () throws ParsingException {
172+ public String getSubChannelAvatarUrl () {
168173 return "" ;
169174 }
170175
171176 @ Nonnull
172177 @ Override
173178 public InfoItemsPage <StreamInfoItem > getInitialPage () {
174- StreamInfoItemsCollector collector = new StreamInfoItemsCollector (getServiceId ());
179+ final StreamInfoItemsCollector collector = new StreamInfoItemsCollector (getServiceId ());
175180
176- JsonArray videos = initialData .getObject ("contents" ).getObject ("twoColumnBrowseResultsRenderer" )
181+ final JsonArray contents = initialData .getObject ("contents" ).getObject ("twoColumnBrowseResultsRenderer" )
177182 .getArray ("tabs" ).getObject (0 ).getObject ("tabRenderer" ).getObject ("content" )
178183 .getObject ("sectionListRenderer" ).getArray ("contents" ).getObject (0 )
179- .getObject ("itemSectionRenderer" ).getArray ("contents" ).getObject (0 )
180- .getObject ("playlistVideoListRenderer" ).getArray ("contents" );
184+ .getObject ("itemSectionRenderer" ).getArray ("contents" );
185+
186+ if (contents .getObject (0 ).has ("playlistSegmentRenderer" )) {
187+ for (final Object segment : contents ) {
188+ if (((JsonObject ) segment ).getObject ("playlistSegmentRenderer" ).has ("trailer" )) {
189+ collectTrailerFrom (collector , ((JsonObject ) segment ));
190+ } else if (((JsonObject ) segment ).getObject ("playlistSegmentRenderer" ).has ("videoList" )) {
191+ collectStreamsFrom (collector , ((JsonObject ) segment ).getObject ("playlistSegmentRenderer" )
192+ .getObject ("videoList" ).getObject ("playlistVideoListRenderer" ).getArray ("contents" ));
193+ }
194+ }
195+ } else if (contents .getObject (0 ).has ("playlistVideoListRenderer" )) {
196+ final JsonArray videos = contents .getObject (0 )
197+ .getObject ("playlistVideoListRenderer" ).getArray ("contents" );
198+ collectStreamsFrom (collector , videos );
199+ }
181200
182- collectStreamsFrom (collector , videos );
183201 return new InfoItemsPage <>(collector , getNextPageUrl ());
184202 }
185203
@@ -189,18 +207,18 @@ public InfoItemsPage<StreamInfoItem> getPage(final String pageUrl) throws IOExce
189207 throw new ExtractionException (new IllegalArgumentException ("Page url is empty or null" ));
190208 }
191209
192- StreamInfoItemsCollector collector = new StreamInfoItemsCollector (getServiceId ());
210+ final StreamInfoItemsCollector collector = new StreamInfoItemsCollector (getServiceId ());
193211 final JsonArray ajaxJson = getJsonResponse (pageUrl , getExtractorLocalization ());
194212
195- JsonObject sectionListContinuation = ajaxJson .getObject (1 ).getObject ("response" )
213+ final JsonObject sectionListContinuation = ajaxJson .getObject (1 ).getObject ("response" )
196214 .getObject ("continuationContents" ).getObject ("playlistVideoListContinuation" );
197215
198216 collectStreamsFrom (collector , sectionListContinuation .getArray ("contents" ));
199217
200218 return new InfoItemsPage <>(collector , getNextPageUrlFrom (sectionListContinuation .getArray ("continuations" )));
201219 }
202220
203- private String getNextPageUrlFrom (JsonArray continuations ) {
221+ private String getNextPageUrlFrom (final JsonArray continuations ) {
204222 if (isNullOrEmpty (continuations )) {
205223 return "" ;
206224 }
@@ -212,9 +230,7 @@ private String getNextPageUrlFrom(JsonArray continuations) {
212230 + "&itct=" + clickTrackingParams ;
213231 }
214232
215- private void collectStreamsFrom (StreamInfoItemsCollector collector , JsonArray videos ) {
216- collector .reset ();
217-
233+ private void collectStreamsFrom (final StreamInfoItemsCollector collector , final JsonArray videos ) {
218234 final TimeAgoParser timeAgoParser = getTimeAgoParser ();
219235
220236 for (Object video : videos ) {
@@ -228,4 +244,72 @@ public long getViewCount() {
228244 }
229245 }
230246 }
247+
248+ private void collectTrailerFrom (final StreamInfoItemsCollector collector ,
249+ final JsonObject segment ) {
250+ collector .commit (new StreamInfoItemExtractor () {
251+ @ Override
252+ public String getName () throws ParsingException {
253+ return getTextFromObject (segment .getObject ("playlistSegmentRenderer" )
254+ .getObject ("title" ));
255+ }
256+
257+ @ Override
258+ public String getUrl () throws ParsingException {
259+ return YoutubeStreamLinkHandlerFactory .getInstance ()
260+ .fromId (segment .getObject ("playlistSegmentRenderer" ).getObject ("trailer" )
261+ .getObject ("playlistVideoPlayerRenderer" ).getString ("videoId" ))
262+ .getUrl ();
263+ }
264+
265+ @ Override
266+ public String getThumbnailUrl () {
267+ return null ;
268+ }
269+
270+ @ Override
271+ public StreamType getStreamType () {
272+ return StreamType .VIDEO_STREAM ;
273+ }
274+
275+ @ Override
276+ public boolean isAd () {
277+ return false ;
278+ }
279+
280+ @ Override
281+ public long getDuration () throws ParsingException {
282+ return YoutubeParsingHelper .parseDurationString (
283+ getTextFromObject (segment .getObject ("playlistSegmentRenderer" )
284+ .getObject ("segmentAnnotation" )).split ("•" )[0 ]);
285+ }
286+
287+ @ Override
288+ public long getViewCount () {
289+ return -1 ;
290+ }
291+
292+ @ Override
293+ public String getUploaderName () throws ParsingException {
294+ return YoutubePlaylistExtractor .this .getUploaderName ();
295+ }
296+
297+ @ Override
298+ public String getUploaderUrl () throws ParsingException {
299+ return YoutubePlaylistExtractor .this .getUploaderUrl ();
300+ }
301+
302+ @ Nullable
303+ @ Override
304+ public String getTextualUploadDate () {
305+ return null ;
306+ }
307+
308+ @ Nullable
309+ @ Override
310+ public DateWrapper getUploadDate () {
311+ return null ;
312+ }
313+ });
314+ }
231315}
0 commit comments