Use the youtubei API for YouTube trends

This commit is contained in:
TiA4f8R 2021-04-11 17:01:43 +02:00
parent f461224b2b
commit 77c031a88a
No known key found for this signature in database
GPG key ID: E6D3E7F5949450DD
5 changed files with 241 additions and 55 deletions

View file

@ -663,8 +663,8 @@ public class YoutubeParsingHelper {
} }
public static JsonObject getJsonPostResponse(final String endpoint, public static JsonObject getJsonPostResponse(final String endpoint,
final byte[] body, final byte[] body,
final Localization localization) final Localization localization)
throws IOException, ExtractionException { throws IOException, ExtractionException {
final Response response = getDownloader().post("https://youtubei.googleapis.com/youtubei/v1/" final Response response = getDownloader().post("https://youtubei.googleapis.com/youtubei/v1/"

View file

@ -22,6 +22,7 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonWriter;
import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
@ -38,28 +39,39 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonResponse; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getClientVersion;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonPostResponse;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextAtKey; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextAtKey;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; import static org.schabi.newpipe.extractor.utils.Utils.UTF_8;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> { public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
private JsonObject initialData; private JsonObject initialData;
public YoutubeTrendingExtractor(StreamingService service, public YoutubeTrendingExtractor(final StreamingService service,
ListLinkHandler linkHandler, final ListLinkHandler linkHandler,
String kioskId) { final String kioskId) {
super(service, linkHandler, kioskId); super(service, linkHandler, kioskId);
} }
@Override @Override
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException { public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
final String url = getUrl() + "?pbj=1&gl=" // @formatter:off
+ getExtractorContentCountry().getCountryCode(); final byte[] body = JsonWriter.string()
.object()
.object("context")
.object("client")
.value("hl", "en")
.value("gl", getExtractorContentCountry().getCountryCode())
.value("clientName", "1")
.value("clientVersion", getClientVersion())
.end()
.end()
.value("browseId", "FEtrending")
.end().done().getBytes(UTF_8);
// @formatter:on
final JsonArray ajaxJson = getJsonResponse(url, getExtractorLocalization()); initialData = getJsonPostResponse("browse", body, getExtractorLocalization());
initialData = ajaxJson.getObject(1).getObject("response");
} }
@Override @Override
@ -89,15 +101,17 @@ public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
public InfoItemsPage<StreamInfoItem> getInitialPage() { public InfoItemsPage<StreamInfoItem> getInitialPage() {
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
final TimeAgoParser timeAgoParser = getTimeAgoParser(); final TimeAgoParser timeAgoParser = getTimeAgoParser();
JsonArray itemSectionRenderers = initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer") JsonArray itemSectionRenderers = initialData.getObject("contents")
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content") .getObject("twoColumnBrowseResultsRenderer").getArray("tabs").getObject(0)
.getObject("sectionListRenderer").getArray("contents"); .getObject("tabRenderer").getObject("content").getObject("sectionListRenderer")
.getArray("contents");
for (Object itemSectionRenderer : itemSectionRenderers) { for (final Object itemSectionRenderer : itemSectionRenderers) {
JsonObject expandedShelfContentsRenderer = ((JsonObject) itemSectionRenderer).getObject("itemSectionRenderer") JsonObject expandedShelfContentsRenderer = ((JsonObject) itemSectionRenderer)
.getArray("contents").getObject(0).getObject("shelfRenderer").getObject("content") .getObject("itemSectionRenderer").getArray("contents").getObject(0)
.getObject("shelfRenderer").getObject("content")
.getObject("expandedShelfContentsRenderer"); .getObject("expandedShelfContentsRenderer");
for (Object ul : expandedShelfContentsRenderer.getArray("items")) { for (final Object ul : expandedShelfContentsRenderer.getArray("items")) {
final JsonObject videoInfo = ((JsonObject) ul).getObject("videoRenderer"); final JsonObject videoInfo = ((JsonObject) ul).getObject("videoRenderer");
collector.commit(new YoutubeStreamInfoItemExtractor(videoInfo, timeAgoParser)); collector.commit(new YoutubeStreamInfoItemExtractor(videoInfo, timeAgoParser));
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long