forked from TeamNewPipe/NewPipeExtractor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parse all the playlists of a channel
- Loading branch information
Showing
6 changed files
with
268 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
...g/schabi/newpipe/extractor/services/youtube/extractors/GridPlaylistRendererExtractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.schabi.newpipe.extractor.services.youtube.extractors; | ||
|
||
import org.schabi.newpipe.extractor.exceptions.ParsingException; | ||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor; | ||
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; | ||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory; | ||
|
||
import com.grack.nanojson.JsonObject; | ||
|
||
public class GridPlaylistRendererExtractor implements PlaylistInfoItemExtractor { | ||
|
||
private final JsonObject playlistInfoItem; | ||
|
||
GridPlaylistRendererExtractor(final JsonObject playlistInfoItem) { | ||
this.playlistInfoItem = playlistInfoItem; | ||
} | ||
|
||
@Override | ||
public String getName() throws ParsingException { | ||
return playlistInfoItem.getObject("title").getArray("runs").getObject(0).getString("text"); | ||
} | ||
|
||
@Override | ||
public String getUrl() throws ParsingException { | ||
try { | ||
final String id = playlistInfoItem.getString("playlistId"); | ||
return YoutubePlaylistLinkHandlerFactory.getInstance().getUrl(id); | ||
} catch (final Exception e) { | ||
throw new ParsingException("Could not get url", e); | ||
} | ||
} | ||
|
||
@Override | ||
public String getThumbnailUrl() throws ParsingException { | ||
return playlistInfoItem.getObject("thumbnailRenderer") | ||
.getObject("playlistVideoThumbnailRenderer").getObject("thumbnail") | ||
.getArray("thumbnails").getObject(0).getString("url"); | ||
} | ||
|
||
@Override | ||
public String getUploaderName() throws ParsingException { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getUploaderUrl() throws ParsingException { | ||
return null; | ||
} | ||
|
||
public boolean isUploaderVerified() throws ParsingException { | ||
try { | ||
return YoutubeParsingHelper.isVerified(playlistInfoItem.getArray("ownerBadges")); | ||
} catch (final Exception e) { | ||
throw new ParsingException("Could not get uploader verification info", e); | ||
} | ||
} | ||
|
||
@Override | ||
public long getStreamCount() throws ParsingException { | ||
return Long.parseLong( | ||
playlistInfoItem.getObject("videoCountShortText").getString("simpleText")); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelPlaylistExtractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package org.schabi.newpipe.extractor.services.youtube.extractors; | ||
|
||
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonPostResponse; | ||
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareDesktopJsonBuilder; | ||
import static org.schabi.newpipe.extractor.utils.Utils.UTF_8; | ||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; | ||
|
||
import java.io.IOException; | ||
import java.io.UnsupportedEncodingException; | ||
|
||
import org.schabi.newpipe.extractor.ListExtractor; | ||
import org.schabi.newpipe.extractor.Page; | ||
import org.schabi.newpipe.extractor.StreamingService; | ||
import org.schabi.newpipe.extractor.downloader.Downloader; | ||
import org.schabi.newpipe.extractor.exceptions.ExtractionException; | ||
import org.schabi.newpipe.extractor.exceptions.ParsingException; | ||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; | ||
import org.schabi.newpipe.extractor.localization.Localization; | ||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; | ||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemsCollector; | ||
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; | ||
|
||
import com.grack.nanojson.JsonArray; | ||
import com.grack.nanojson.JsonObject; | ||
import com.grack.nanojson.JsonWriter; | ||
|
||
public class YoutubeChannelPlaylistExtractor extends ListExtractor<PlaylistInfoItem> { | ||
|
||
private final String browseId; | ||
private final String params; | ||
private final String canonicalBaseUrl; | ||
private JsonObject browseResponse; | ||
private JsonObject playlistTab; | ||
|
||
YoutubeChannelPlaylistExtractor(final StreamingService service, | ||
final ListLinkHandler linkHandler, final JsonObject browseEndpoint) { | ||
super(service, linkHandler); | ||
this.browseId = browseEndpoint.getString("browseId"); | ||
this.params = browseEndpoint.getString("params"); | ||
this.canonicalBaseUrl = browseEndpoint.getString("canonicalBaseUrl"); | ||
} | ||
|
||
@Override | ||
public InfoItemsPage<PlaylistInfoItem> getInitialPage() | ||
throws IOException, ExtractionException { | ||
final PlaylistInfoItemsCollector pic = new PlaylistInfoItemsCollector(getServiceId()); | ||
|
||
final JsonArray playlistItems = playlistTab.getObject("content") | ||
.getObject("sectionListRenderer").getArray("contents").getObject(0) | ||
.getObject("itemSectionRenderer").getArray("contents").getObject(0) | ||
.getObject("gridRenderer").getArray("items"); | ||
final var continuation = collectPlaylistsFrom(playlistItems, pic); | ||
return new InfoItemsPage<>(pic, continuation); | ||
} | ||
|
||
private Page collectPlaylistsFrom(final JsonArray playlistItems, | ||
final PlaylistInfoItemsCollector collector) | ||
throws UnsupportedEncodingException, IOException, ExtractionException { | ||
Page continuation = null; | ||
for (final var item : playlistItems) { | ||
if (item instanceof JsonObject) { | ||
final JsonObject jsonItem = (JsonObject) item; | ||
if (jsonItem.has("gridPlaylistRenderer")) { | ||
collector.commit(new GridPlaylistRendererExtractor( | ||
jsonItem.getObject("gridPlaylistRenderer"))); | ||
} else if (jsonItem.has("continuationItemRenderer")) { | ||
continuation = YoutubeParsingHelper.getNextPageFromItem(jsonItem, | ||
getExtractorLocalization(), getExtractorContentCountry()); | ||
} | ||
} | ||
} | ||
return continuation; | ||
} | ||
|
||
@Override | ||
public InfoItemsPage<PlaylistInfoItem> getPage(final Page page) | ||
throws IOException, ExtractionException { | ||
if (page == null || isNullOrEmpty(page.getUrl())) { | ||
throw new IllegalArgumentException("Page doesn't contain an URL"); | ||
} | ||
final PlaylistInfoItemsCollector collector = new PlaylistInfoItemsCollector(getServiceId()); | ||
|
||
final JsonObject ajaxJson = getJsonPostResponse("browse", page.getBody(), | ||
getExtractorLocalization()); | ||
|
||
final JsonArray continuation = ajaxJson.getArray("onResponseReceivedActions").getObject(0) | ||
.getObject("appendContinuationItemsAction").getArray("continuationItems"); | ||
|
||
final var cont = collectPlaylistsFrom(continuation, collector); | ||
|
||
return new InfoItemsPage<>(collector, cont); | ||
} | ||
|
||
@Override | ||
public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException { | ||
final Localization localization = getExtractorLocalization(); | ||
final byte[] body = JsonWriter | ||
.string(prepareDesktopJsonBuilder(localization, getExtractorContentCountry()) | ||
.value("browseId", browseId) | ||
.value("params", params) | ||
.value("canonicalBaseUrl", canonicalBaseUrl).done()) | ||
.getBytes(UTF_8); | ||
|
||
browseResponse = getJsonPostResponse("browse", body, localization); | ||
playlistTab = YoutubeParsingHelper.getPlaylistsTab(browseResponse); | ||
|
||
YoutubeParsingHelper.defaultAlertsCheck(browseResponse); | ||
} | ||
|
||
@Override | ||
public String getName() throws ParsingException { | ||
return browseResponse.getObject("metadata").getObject("channelMetadataRenderer") | ||
.getString("title"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters