From 065e9a4e7c3fee90f68d06992cf979338f8e3aba Mon Sep 17 00:00:00 2001 From: Konstantin Date: Sun, 8 Jun 2025 13:25:54 +0200 Subject: [PATCH] feat(MediaInfo): Add `updateWatchTime` (#874) * feat: add watch time update function for VideoInfos classes * chore: Improve naming * chore: fix ts error --------- Co-authored-by: absidue <48293849+absidue@users.noreply.github.com> Co-authored-by: Luan --- src/core/mixins/MediaInfo.ts | 29 +++++++++++++++++++++++------ src/parser/youtube/VideoInfo.ts | 7 +++++++ src/parser/ytmusic/TrackInfo.ts | 7 +++++++ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/core/mixins/MediaInfo.ts b/src/core/mixins/MediaInfo.ts index 6ce2ba53..a25e91f6 100644 --- a/src/core/mixins/MediaInfo.ts +++ b/src/core/mixins/MediaInfo.ts @@ -139,7 +139,7 @@ export default class MediaInfo { manifest_options ); } - + /** * Get a cleaned up representation of the adaptive_formats */ @@ -207,10 +207,7 @@ export default class MediaInfo { return new TranscriptInfo(this.actions, response); } - /** - * Adds video to the watch history. - */ - async addToWatchHistory(client_name: string = Constants.CLIENTS.WEB.NAME, client_version: string = Constants.CLIENTS.WEB.VERSION, replacement = 'https://www.'): Promise { + async addToWatchHistory(client_name?: string, client_version?: string, replacement = 'https://www.'): Promise { if (!this.#playback_tracking) throw new InnertubeError('Playback tracking not available'); @@ -223,6 +220,26 @@ export default class MediaInfo { const url = this.#playback_tracking.videostats_playback_url.replace('https://s.', replacement); + return await this.#actions.stats(url, { + client_name: client_name || Constants.CLIENTS.WEB.NAME, + client_version: client_version || Constants.CLIENTS.WEB.VERSION + }, url_params); + } + + async updateWatchTime(startTime: number, client_name: string = Constants.CLIENTS.WEB.NAME, client_version: string = Constants.CLIENTS.WEB.VERSION, replacement = 'https://www.'): Promise { + if (!this.#playback_tracking) + throw new InnertubeError('Playback tracking not available'); + + const url_params = { + cpn: this.#cpn, + st: startTime.toFixed(3), + et: startTime.toFixed(3), + cmt: startTime.toFixed(3), + final: '1' + }; + + const url = this.#playback_tracking.videostats_watchtime_url.replace('https://s.', replacement); + return await this.#actions.stats(url, { client_name, client_version @@ -243,7 +260,7 @@ export default class MediaInfo { /** * Parsed InnerTube response. */ - get page(): [ IPlayerResponse, INextResponse? ] { + get page(): [IPlayerResponse, INextResponse?] { return this.#page; } } \ No newline at end of file diff --git a/src/parser/youtube/VideoInfo.ts b/src/parser/youtube/VideoInfo.ts index 4ea96331..f2dc5c4b 100644 --- a/src/parser/youtube/VideoInfo.ts +++ b/src/parser/youtube/VideoInfo.ts @@ -192,6 +192,13 @@ export default class VideoInfo extends MediaInfo { return super.addToWatchHistory(); } + /** + * Updates watch time for the video. + */ + async updateWatchTime(startTime: number): Promise { + return super.updateWatchTime(startTime); + } + /** * Retrieves watch next feed continuation. */ diff --git a/src/parser/ytmusic/TrackInfo.ts b/src/parser/ytmusic/TrackInfo.ts index 2dfda171..69ca3920 100644 --- a/src/parser/ytmusic/TrackInfo.ts +++ b/src/parser/ytmusic/TrackInfo.ts @@ -144,6 +144,13 @@ class TrackInfo extends MediaInfo { async addToWatchHistory(): Promise { return super.addToWatchHistory(Constants.CLIENTS.YTMUSIC.NAME, Constants.CLIENTS.YTMUSIC.VERSION, 'https://music.'); } + + /** + * Updates the watch time of the song. + */ + async updateWatchTime(startTime: number): Promise { + return super.updateWatchTime(startTime, Constants.CLIENTS.YTMUSIC.NAME, Constants.CLIENTS.YTMUSIC.VERSION, 'https://music.'); + } get available_tabs(): string[] { return this.tabs ? this.tabs.map((tab) => tab.title) : [];