Skip to content

Commit fec89a2

Browse files
committed
[YouTube] Fix extraction of continuations in initial playlist responses
1 parent 61059b1 commit fec89a2

1 file changed

Lines changed: 30 additions & 5 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,22 +374,47 @@ private Page getNextPageFrom(final JsonArray contents)
374374

375375
final JsonObject lastElement = contents.getObject(contents.size() - 1);
376376
if (lastElement.has("continuationItemRenderer")) {
377-
final String continuation = lastElement
377+
final JsonObject continuationEndpoint = lastElement
378378
.getObject("continuationItemRenderer")
379-
.getObject("continuationEndpoint")
380-
.getObject("continuationCommand")
379+
.getObject("continuationEndpoint");
380+
381+
final JsonObject continuationObject;
382+
if (continuationEndpoint.has("commandExecutorCommand")) {
383+
// This structure is only used at the time this code is written in initial playlist
384+
// responses. continuationItemRenderer objects return multiple commands: one
385+
// containing the continuation we need and one a playlistVotingRefreshPopupCommand
386+
continuationObject = continuationEndpoint.getObject("commandExecutorCommand")
387+
.getArray("commands")
388+
.stream()
389+
.filter(JsonObject.class::isInstance)
390+
.map(JsonObject.class::cast)
391+
.filter(command -> command.has("continuationCommand"))
392+
.findFirst()
393+
.orElse(new JsonObject());
394+
} else {
395+
// At the time this code is written, this "classic" continuation structure is only
396+
// returned in browse responses of continuation requests
397+
continuationObject = continuationEndpoint;
398+
}
399+
400+
final String continuation = continuationObject.getObject("continuationCommand")
381401
.getString("token");
382402

403+
if (isNullOrEmpty(continuation)) {
404+
// Invalid continuation or no continuation found
405+
return null;
406+
}
407+
383408
final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(
384409
getExtractorLocalization(), getExtractorContentCountry())
385410
.value("continuation", continuation)
386411
.done())
387412
.getBytes(StandardCharsets.UTF_8);
388413

389414
return new Page(YOUTUBEI_V1_URL + "browse?" + DISABLE_PRETTY_PRINT_PARAMETER, body);
390-
} else {
391-
return null;
392415
}
416+
417+
return null;
393418
}
394419

395420
private void collectStreamsFrom(@Nonnull final StreamInfoItemsCollector collector,

0 commit comments

Comments
 (0)