diff --git a/lib/Innertube.js b/lib/Innertube.js index 3b664503..5fb46232 100644 --- a/lib/Innertube.js +++ b/lib/Innertube.js @@ -171,11 +171,12 @@ class Innertube { */ async getInfo(video_id) { Utils.throwIfMissing({ video_id }); - + const initial_info = this.actions.getVideoInfo(video_id); const continuation = this.actions.next({ video_id }); const response = await Promise.all([ initial_info, continuation ]); + return new VideoInfo(response, this.actions, this.#player); } diff --git a/lib/parser/contents/classes/ChipCloudChip.js b/lib/parser/contents/classes/ChipCloudChip.js index c92297e6..4c75d298 100644 --- a/lib/parser/contents/classes/ChipCloudChip.js +++ b/lib/parser/contents/classes/ChipCloudChip.js @@ -7,7 +7,7 @@ class ChipCloudChip { type = 'chipCloudChipRenderer'; constructor(data) { - this.text = new Text(data.text); + this.text = new Text(data.text).toString(); this.endpoint = new NavigationEndpoint(data.navigationEndpoint); this.is_selected = data.isSelected; } diff --git a/lib/parser/contents/classes/NavigationEndpoint.js b/lib/parser/contents/classes/NavigationEndpoint.js index 721af41b..0555c450 100644 --- a/lib/parser/contents/classes/NavigationEndpoint.js +++ b/lib/parser/contents/classes/NavigationEndpoint.js @@ -141,6 +141,10 @@ class NavigationEndpoint { const response = await actions.search({ ctoken: this.continuation.token }); return Parser.parseResponse(response.data); } + case 'CONTINUATION_REQUEST_TYPE_WATCH_NEXT': { + const response = await actions.next({ ctoken: this.continuation.token }); + return Parser.parseResponse(response.data); + } default: throw new Error(this.continuation.request + ' not implemented'); } diff --git a/lib/parser/contents/index.js b/lib/parser/contents/index.js index a5b71aa1..2bec603f 100644 --- a/lib/parser/contents/index.js +++ b/lib/parser/contents/index.js @@ -13,6 +13,15 @@ class AppendContinuationItemsAction { } } +class ReloadContinuationItemsCommand { + type = 'reloadContinuationItemsCommand'; + + constructor (data) { + this.target_id = data.targetId; + this.continuation_items = Parser.parse(data.continuationItems); + } +} + /** @namespace */ class Parser { static parseResponse(data) { @@ -60,10 +69,12 @@ class Parser { } static parseRR(actions) { - return actions.map((action) => { + return observe(actions.map((action) => { + if (action.reloadContinuationItemsCommand) + return new ReloadContinuationItemsCommand(action.reloadContinuationItemsCommand); if (action.appendContinuationItemsAction) return new AppendContinuationItemsAction(action.appendContinuationItemsAction); - }).filter((item) => item); + }).filter((item) => item)); } static parseFormats(formats) { diff --git a/lib/parser/youtube/VideoInfo.js b/lib/parser/youtube/VideoInfo.js index 65d5d56e..f6da1d23 100644 --- a/lib/parser/youtube/VideoInfo.js +++ b/lib/parser/youtube/VideoInfo.js @@ -26,7 +26,7 @@ class VideoInfo { if (info.playability_status.status === 'ERROR') throw new InnertubeError('This video is unavailable', info.playability_status); - + /** * @type {import('../contents/classes/VideoDetails')} */ @@ -45,27 +45,30 @@ class VideoInfo { } }; + const results = next.contents.results; + const secondary_results = next.contents.secondary_results; + /** * @type {import('../contents/classes/VideoPrimaryInfo')} */ - this.primary_info = next.contents.results.get({ type: 'videoPrimaryInfoRenderer' }); + this.primary_info = results.get({ type: 'videoPrimaryInfoRenderer' }); /** * @type {import('../contents/classes/VideoSecondaryInfo')} */ - this.secondary_info = next.contents.results.get({ type: 'videoSecondaryInfoRenderer' }); + this.secondary_info = results.get({ type: 'videoSecondaryInfoRenderer' }); /** * @type {import('../contents/classes/MerchandiseShelf')} */ - this.merchandise = next.contents.results?.get({ type: 'merchandiseShelfRenderer' }); + this.merchandise = results?.get({ type: 'merchandiseShelfRenderer' }); /** * @type {import('../contents/classes/ChipCloud')} */ - this.related_chip_cloud = next.contents.secondary_results?.get({ type: 'relatedChipCloudRenderer' }).content; + this.related_chip_cloud = secondary_results?.get({ type: 'relatedChipCloudRenderer' }).content; - this.watch_next_feed = next.contents.secondary_results?.get({ target_id: 'watch-next-feed' }).contents; + this.watch_next_feed = secondary_results?.get({ target_id: 'watch-next-feed' }).contents; this.watch_next_feed?.pop(); // get rid of the continuation item as it is of no use (for now). /** @@ -105,7 +108,7 @@ class VideoInfo { */ this.cards = info.cards; - const comments_entry_point = next.contents.results.get({ target_id: 'comments-entry-point' }); + const comments_entry_point = results.get({ target_id: 'comments-entry-point' }); /** * @type {import('../contents/classes/CommentsEntryPointHeader')} @@ -113,6 +116,15 @@ class VideoInfo { this.comments_entry_point_header = comments_entry_point?.contents.get({ type: 'commentsEntryPointHeaderRenderer' }) || {}; } + async selectFilter(chip) { + const response = await chip.endpoint.call(this.#actions); + + const data = response.on_response_received_endpoints.get({ target_id: 'watch-next-feed' }); + this.watch_next_feed = data.continuation_items; + + return this; + } + get page() { return this.#page; }