|
2 | 2 |
|
3 | 3 | import com.grack.nanojson.JsonArray; |
4 | 4 | import com.grack.nanojson.JsonObject; |
| 5 | +import com.grack.nanojson.JsonWriter; |
| 6 | + |
5 | 7 | import org.schabi.newpipe.extractor.Page; |
6 | 8 | import org.schabi.newpipe.extractor.StreamingService; |
7 | 9 | import org.schabi.newpipe.extractor.channel.ChannelExtractor; |
8 | 10 | import org.schabi.newpipe.extractor.downloader.Downloader; |
| 11 | +import org.schabi.newpipe.extractor.downloader.Response; |
9 | 12 | import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; |
10 | 13 | import org.schabi.newpipe.extractor.exceptions.ExtractionException; |
11 | 14 | import org.schabi.newpipe.extractor.exceptions.ParsingException; |
|
15 | 18 | import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; |
16 | 19 | import org.schabi.newpipe.extractor.stream.StreamInfoItem; |
17 | 20 | import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; |
| 21 | +import org.schabi.newpipe.extractor.utils.JsonUtils; |
18 | 22 | import org.schabi.newpipe.extractor.utils.Utils; |
19 | 23 |
|
20 | 24 | import javax.annotation.Nonnull; |
21 | 25 | import java.io.IOException; |
22 | 26 |
|
23 | | -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.*; |
| 27 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl; |
| 28 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getClientVersion; |
| 29 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonResponse; |
| 30 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; |
| 31 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getKey; |
| 32 | +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getValidJsonResponseBody; |
24 | 33 | import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING; |
| 34 | +import static org.schabi.newpipe.extractor.utils.Utils.UTF_8; |
25 | 35 | import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; |
26 | 36 |
|
27 | 37 | /* |
@@ -226,7 +236,7 @@ public boolean isVerified() throws ParsingException { |
226 | 236 |
|
227 | 237 | @Nonnull |
228 | 238 | @Override |
229 | | - public InfoItemsPage<StreamInfoItem> getInitialPage() throws ExtractionException { |
| 239 | + public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException { |
230 | 240 | final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); |
231 | 241 |
|
232 | 242 | Page nextPage = null; |
@@ -254,27 +264,44 @@ public InfoItemsPage<StreamInfoItem> getPage(final Page page) throws IOException |
254 | 264 | // as they don't deliver enough information on their own (the channel name, for example). |
255 | 265 | fetchPage(); |
256 | 266 |
|
| 267 | + // @formatter:off |
| 268 | + byte[] json = JsonWriter.string() |
| 269 | + .object() |
| 270 | + .object("context") |
| 271 | + .object("client") |
| 272 | + .value("clientName", "1") |
| 273 | + .value("clientVersion", getClientVersion()) |
| 274 | + .end() |
| 275 | + .end() |
| 276 | + .value("continuation", page.getId()) |
| 277 | + .end() |
| 278 | + .done() |
| 279 | + .getBytes(UTF_8); |
| 280 | + // @formatter:on |
| 281 | + |
257 | 282 | StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); |
258 | | - final JsonArray ajaxJson = getJsonResponse(page.getUrl(), getExtractorLocalization()); |
| 283 | + final Response response = getDownloader().post(page.getUrl(), null, json, getExtractorLocalization()); |
| 284 | + |
| 285 | + final JsonObject ajaxJson = JsonUtils.toJsonObject(getValidJsonResponseBody(response)); |
259 | 286 |
|
260 | | - JsonObject sectionListContinuation = ajaxJson.getObject(1).getObject("response") |
261 | | - .getArray("onResponseReceivedActions").getObject(0).getObject("appendContinuationItemsAction"); |
| 287 | + JsonObject sectionListContinuation = ajaxJson.getArray("onResponseReceivedActions") |
| 288 | + .getObject(0) |
| 289 | + .getObject("appendContinuationItemsAction"); |
262 | 290 |
|
263 | 291 | final JsonObject continuation = collectStreamsFrom(collector, sectionListContinuation.getArray("continuationItems")); |
264 | 292 |
|
265 | 293 | return new InfoItemsPage<>(collector, getNextPageFrom(continuation)); |
266 | 294 | } |
267 | 295 |
|
268 | | - private Page getNextPageFrom(final JsonObject continuations) { |
| 296 | + private Page getNextPageFrom(final JsonObject continuations) throws IOException, ExtractionException { |
269 | 297 | if (isNullOrEmpty(continuations)) { |
270 | 298 | return null; |
271 | 299 | } |
272 | 300 |
|
273 | 301 | final JsonObject continuationEndpoint = continuations.getObject("continuationEndpoint"); |
274 | 302 | final String continuation = continuationEndpoint.getObject("continuationCommand").getString("token"); |
275 | | - final String clickTrackingParams = continuationEndpoint.getString("clickTrackingParams"); |
276 | | - return new Page("https://www.youtube.com/browse_ajax?ctoken=" + continuation |
277 | | - + "&continuation=" + continuation + "&itct=" + clickTrackingParams); |
| 303 | + return new Page("https://www.youtube.com/youtubei/v1/browse?key=" + getKey(), |
| 304 | + continuation); |
278 | 305 | } |
279 | 306 |
|
280 | 307 | /** |
|
0 commit comments