UNPKG

@duell10111/youtubei.js

Version:

A JavaScript client for YouTube's private API, known as InnerTube.

190 lines 8.64 kB
var _TV_session, _TV_actions; import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import { HorizontalListContinuation, Parser } from '../../parser/index.js'; import NavigationEndpoint from '../../parser/classes/NavigationEndpoint.js'; import { HomeFeed, VideoInfo, MyYoutubeFeed } from '../../parser/yttv/index.js'; import { generateRandomString, InnertubeError, throwIfMissing } from '../../utils/Utils.js'; import HorizontalList from '../../parser/classes/HorizontalList.js'; import Playlist from '../../parser/yttv/Playlist.js'; import Library from '../../parser/yttv/Library.js'; import SubscriptionsFeed from '../../parser/yttv/SubscriptionsFeed.js'; import PlaylistsFeed from '../../parser/yttv/PlaylistsFeed.js'; class TV { constructor(session) { _TV_session.set(this, void 0); _TV_actions.set(this, void 0); __classPrivateFieldSet(this, _TV_session, session, "f"); __classPrivateFieldSet(this, _TV_actions, session.actions, "f"); } async getInfo(target, client) { throwIfMissing({ target }); const payload = { videoId: target instanceof NavigationEndpoint ? target.payload?.videoId : target, playlistId: target instanceof NavigationEndpoint ? target.payload?.playlistId : undefined, playlistIndex: target instanceof NavigationEndpoint ? target.payload?.playlistIndex : undefined, params: target instanceof NavigationEndpoint ? target.payload?.params : undefined, racyCheckOk: true, contentCheckOk: true }; const watch_endpoint = new NavigationEndpoint({ watchEndpoint: payload }); const watch_next_endpoint = new NavigationEndpoint({ watchNextEndpoint: payload }); const watch_response = watch_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { playbackContext: { contentPlaybackContext: { vis: 0, splay: false, lactMilliseconds: '-1', signatureTimestamp: __classPrivateFieldGet(this, _TV_session, "f").player?.sts } }, serviceIntegrityDimensions: { poToken: __classPrivateFieldGet(this, _TV_session, "f").po_token }, client }); const watch_next_response = await watch_next_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client }); const response = await Promise.all([watch_response, watch_next_response]); const cpn = generateRandomString(16); return new VideoInfo(response, __classPrivateFieldGet(this, _TV_actions, "f"), cpn); } async getHomeFeed() { const client = 'TV'; const home_feed = new NavigationEndpoint({ browseEndpoint: { browseId: 'default' } }); const response = await home_feed.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client }); return new HomeFeed(response, __classPrivateFieldGet(this, _TV_actions, "f")); } async getLibrary() { const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FElibrary' } }); const response = await browse_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); return new Library(response, __classPrivateFieldGet(this, _TV_actions, "f")); } async getSubscriptionsFeed() { const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FEsubscriptions' } }); const response = await browse_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); return new SubscriptionsFeed(response, __classPrivateFieldGet(this, _TV_actions, "f")); } /** * Retrieves the user's playlists. */ async getPlaylists() { const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FEplaylist_aggregation' } }); const response = await browse_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); return new PlaylistsFeed(response, __classPrivateFieldGet(this, _TV_actions, "f")); } /** * Retrieves the user's My YouTube page. */ async getMyYoutubeFeed() { const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: 'FEmy_youtube' } }); const response = await browse_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); return new MyYoutubeFeed(response, __classPrivateFieldGet(this, _TV_actions, "f")); } async getPlaylist(id) { throwIfMissing({ id }); if (!id.startsWith('VL')) { id = `VL${id}`; } const browse_endpoint = new NavigationEndpoint({ browseEndpoint: { browseId: id } }); const response = await browse_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); return new Playlist(response, __classPrivateFieldGet(this, _TV_actions, "f")); } // Utils async fetchContinuationData(item, client) { let continuation; if (item.is(HorizontalList)) { continuation = item.continuations?.first()?.continuation; } else if (item.is(HorizontalListContinuation)) { continuation = item.continuation; } else { throw new InnertubeError(`No supported YTNode supplied. Type: ${item.type}`); } if (!continuation) { throw new InnertubeError('No continuation data available.'); } const data = await __classPrivateFieldGet(this, _TV_actions, "f").execute('/browse', { client: client ?? 'TV', continuation: continuation }); const parser = Parser.parseResponse(data.data); return parser.continuation_contents; } // Interactions for TV (for default OAuth login) /** * Adds videos to a given playlist. * @param playlist_id - The playlist ID. * @param video_ids - An array of video IDs to add to the playlist. * @param client - Innertube Client to use for request */ async addVideos(playlist_id, video_ids, client) { throwIfMissing({ playlist_id, video_ids }); if (!__classPrivateFieldGet(this, _TV_actions, "f").session.logged_in) throw new InnertubeError('You must be signed in to perform this operation.'); const playlist_edit_endpoint = new NavigationEndpoint({ playlistEditEndpoint: { playlistId: playlist_id, actions: video_ids.map((id) => ({ action: 'ACTION_ADD_VIDEO', addedVideoId: id })) } }); const response = await playlist_edit_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client }); return { playlist_id, action_result: response.data.actions // TODO: implement actions in the parser }; } /** * Adds a given playlist to the library of a user. * @param playlist_id - The playlist ID. */ async addToLibrary(playlist_id) { throwIfMissing({ playlist_id }); if (!__classPrivateFieldGet(this, _TV_actions, "f").session.logged_in) throw new InnertubeError('You must be signed in to perform this operation.'); const like_playlist_endpoint = new NavigationEndpoint({ likeEndpoint: { status: 'LIKE', target: playlist_id } }); return await like_playlist_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); } /** * Remove a given playlist to the library of a user. * @param playlist_id - The playlist ID. */ async removeFromLibrary(playlist_id) { throwIfMissing({ playlist_id }); if (!__classPrivateFieldGet(this, _TV_actions, "f").session.logged_in) throw new InnertubeError('You must be signed in to perform this operation.'); const remove_like_playlist_endpoint = new NavigationEndpoint({ likeEndpoint: { status: 'INDIFFERENT', target: playlist_id } }); return await remove_like_playlist_endpoint.call(__classPrivateFieldGet(this, _TV_actions, "f"), { client: 'TV' }); } } _TV_session = new WeakMap(), _TV_actions = new WeakMap(); export default TV; //# sourceMappingURL=TV.js.map