UNPKG

@np-dev/youtubei-js

Version:

A wrapper around YouTube's private API. Supports YouTube, YouTube Music, YouTube Kids and YouTube Studio (WIP).

144 lines 8.05 kB
var _MediaInfo_page, _MediaInfo_actions, _MediaInfo_cpn, _MediaInfo_playback_tracking; import { __awaiter, __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; import * as Constants from '../../utils/Constants.js'; import * as FormatUtils from '../../utils/FormatUtils.js'; import { InnertubeError } from '../../utils/Utils.js'; import { Parser } from '../../parser/index.js'; import PlayerStoryboardSpec from '../../parser/classes/PlayerStoryboardSpec.js'; import { getStreamingInfo } from '../../utils/StreamingInfo.js'; import ContinuationItem from '../../parser/classes/ContinuationItem.js'; import TranscriptInfo from '../../parser/youtube/TranscriptInfo.js'; class MediaInfo { constructor(data, actions, cpn) { var _a, _b; _MediaInfo_page.set(this, void 0); _MediaInfo_actions.set(this, void 0); _MediaInfo_cpn.set(this, void 0); _MediaInfo_playback_tracking.set(this, void 0); __classPrivateFieldSet(this, _MediaInfo_actions, actions, "f"); const info = Parser.parseResponse(data[0].data); const next = ((_a = data === null || data === void 0 ? void 0 : data[1]) === null || _a === void 0 ? void 0 : _a.data) ? Parser.parseResponse(data[1].data) : undefined; __classPrivateFieldSet(this, _MediaInfo_page, [info, next], "f"); __classPrivateFieldSet(this, _MediaInfo_cpn, cpn, "f"); if (((_b = info.playability_status) === null || _b === void 0 ? void 0 : _b.status) === 'ERROR') throw new InnertubeError('This video is unavailable', info.playability_status); this.streaming_data = info.streaming_data; this.playability_status = info.playability_status; this.player_config = info.player_config; __classPrivateFieldSet(this, _MediaInfo_playback_tracking, info.playback_tracking, "f"); } /** * Generates a DASH manifest from the streaming data. * @param url_transformer - Function to transform the URLs. * @param format_filter - Function to filter the formats. * @param options - Additional options to customise the manifest generation * @returns DASH manifest */ toDash(url_transformer, format_filter, options = { include_thumbnails: false }) { var _a; return __awaiter(this, void 0, void 0, function* () { const player_response = __classPrivateFieldGet(this, _MediaInfo_page, "f")[0]; if (player_response.video_details && (player_response.video_details.is_live || player_response.video_details.is_post_live_dvr)) { throw new InnertubeError('Generating DASH manifests for live and Post-Live-DVR videos is not supported. Please use the DASH and HLS manifests provided by YouTube in `streaming_data.dash_manifest_url` and `streaming_data.hls_manifest_url` instead.'); } let storyboards; if (options.include_thumbnails && ((_a = player_response.storyboards) === null || _a === void 0 ? void 0 : _a.is(PlayerStoryboardSpec))) { storyboards = player_response.storyboards; } return FormatUtils.toDash(this.streaming_data, url_transformer, format_filter, __classPrivateFieldGet(this, _MediaInfo_cpn, "f"), __classPrivateFieldGet(this, _MediaInfo_actions, "f").session.player, __classPrivateFieldGet(this, _MediaInfo_actions, "f"), storyboards); }); } /** * Get a cleaned up representation of the adaptive_formats */ getStreamingInfo(url_transformer, format_filter) { var _a; return getStreamingInfo(this.streaming_data, url_transformer, format_filter, this.cpn, __classPrivateFieldGet(this, _MediaInfo_actions, "f").session.player, __classPrivateFieldGet(this, _MediaInfo_actions, "f"), ((_a = __classPrivateFieldGet(this, _MediaInfo_page, "f")[0].storyboards) === null || _a === void 0 ? void 0 : _a.is(PlayerStoryboardSpec)) ? __classPrivateFieldGet(this, _MediaInfo_page, "f")[0].storyboards : undefined); } /** * Selects the format that best matches the given options. * @param options - Options */ chooseFormat(options) { return FormatUtils.chooseFormat(options, this.streaming_data); } /** * Downloads the video. * @param options - Download options. */ download(options = {}) { return __awaiter(this, void 0, void 0, function* () { const player_response = __classPrivateFieldGet(this, _MediaInfo_page, "f")[0]; if (player_response.video_details && (player_response.video_details.is_live || player_response.video_details.is_post_live_dvr)) { throw new InnertubeError('Downloading is not supported for live and Post-Live-DVR videos, as they are split up into 5 second segments that are individual files, which require using a tool such as ffmpeg to stitch them together, so they cannot be returned in a single stream.'); } return FormatUtils.download(options, __classPrivateFieldGet(this, _MediaInfo_actions, "f"), this.playability_status, this.streaming_data, __classPrivateFieldGet(this, _MediaInfo_actions, "f").session.player, this.cpn); }); } /** * Retrieves the video's transcript. * @param video_id - The video id. */ getTranscript() { var _a; return __awaiter(this, void 0, void 0, function* () { const next_response = this.page[1]; if (!next_response) throw new InnertubeError('Cannot get transcript from basic video info.'); if (!next_response.engagement_panels) throw new InnertubeError('Engagement panels not found. Video likely has no transcript.'); const transcript_panel = next_response.engagement_panels.get({ panel_identifier: 'engagement-panel-searchable-transcript' }); if (!transcript_panel) throw new InnertubeError('Transcript panel not found. Video likely has no transcript.'); const transcript_continuation = (_a = transcript_panel.content) === null || _a === void 0 ? void 0 : _a.as(ContinuationItem); if (!transcript_continuation) throw new InnertubeError('Transcript continuation not found.'); const response = yield transcript_continuation.endpoint.call(this.actions); return new TranscriptInfo(this.actions, response); }); } /** * Adds video to the watch history. */ addToWatchHistory(client_name = Constants.CLIENTS.WEB.NAME, client_version = Constants.CLIENTS.WEB.VERSION, replacement = 'https://www.') { return __awaiter(this, void 0, void 0, function* () { if (!__classPrivateFieldGet(this, _MediaInfo_playback_tracking, "f")) throw new InnertubeError('Playback tracking not available'); const url_params = { cpn: __classPrivateFieldGet(this, _MediaInfo_cpn, "f"), fmt: 251, rtn: 0, rt: 0 }; const url = __classPrivateFieldGet(this, _MediaInfo_playback_tracking, "f").videostats_playback_url.replace('https://s.', replacement); const response = yield __classPrivateFieldGet(this, _MediaInfo_actions, "f").stats(url, { client_name, client_version }, url_params); return response; }); } /** * Actions instance. */ get actions() { return __classPrivateFieldGet(this, _MediaInfo_actions, "f"); } /** * Content Playback Nonce. */ get cpn() { return __classPrivateFieldGet(this, _MediaInfo_cpn, "f"); } /** * Original parsed InnerTube response. */ get page() { return __classPrivateFieldGet(this, _MediaInfo_page, "f"); } } _MediaInfo_page = new WeakMap(), _MediaInfo_actions = new WeakMap(), _MediaInfo_cpn = new WeakMap(), _MediaInfo_playback_tracking = new WeakMap(); export default MediaInfo; //# sourceMappingURL=MediaInfo.js.map