@imput/youtubei.js
Version:
A JavaScript client for YouTube's private API, known as InnerTube. Fork of youtubei.js
173 lines • 9.97 kB
JavaScript
var _MediaInfo_page, _MediaInfo_actions, _MediaInfo_cpn, _MediaInfo_playback_tracking;
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
import { Constants, FormatUtils } from '../../utils/index.js';
import { InnertubeError } from '../../utils/Utils.js';
import { getStreamingInfo } from '../../utils/StreamingInfo.js';
import { Parser } from '../../parser/index.js';
import { TranscriptInfo } from '../../parser/youtube/index.js';
import ContinuationItem from '../../parser/classes/ContinuationItem.js';
import PlayerMicroformat from '../../parser/classes/PlayerMicroformat.js';
import MicroformatData from '../../parser/classes/MicroformatData.js';
class MediaInfo {
constructor(data, actions, cpn) {
_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.playerResponse ? data[0].data.playerResponse : data[0].data);
const next = data[1]?.data ? Parser.parseResponse(data[1].data) : undefined;
__classPrivateFieldSet(this, _MediaInfo_page, [info, next], "f");
__classPrivateFieldSet(this, _MediaInfo_cpn, cpn, "f");
if (info.playability_status?.status === 'ERROR')
throw new InnertubeError('This video is unavailable', info.playability_status);
if (info.microformat && !info.microformat?.is(PlayerMicroformat, MicroformatData))
throw new InnertubeError('Unsupported microformat', info.microformat);
this.basic_info = {
...info.video_details,
/**
* Microformat is a bit redundant, so only
* a few things there are interesting to us.
*/
...{
embed: info.microformat?.is(PlayerMicroformat) ? info.microformat?.embed : null,
channel: info.microformat?.is(PlayerMicroformat) ? info.microformat?.channel : null,
is_unlisted: info.microformat?.is_unlisted,
is_family_safe: info.microformat?.is_family_safe,
category: info.microformat?.is(PlayerMicroformat) ? info.microformat?.category : null,
has_ypc_metadata: info.microformat?.is(PlayerMicroformat) ? info.microformat?.has_ypc_metadata : null,
start_timestamp: info.microformat?.is(PlayerMicroformat) ? info.microformat.start_timestamp : null,
end_timestamp: info.microformat?.is(PlayerMicroformat) ? info.microformat.end_timestamp : null,
view_count: info.microformat?.is(PlayerMicroformat) && isNaN(info.video_details?.view_count) ? info.microformat.view_count : info.video_details?.view_count,
url_canonical: info.microformat?.is(MicroformatData) ? info.microformat?.url_canonical : null,
tags: info.microformat?.is(MicroformatData) ? info.microformat?.tags : null
},
like_count: undefined,
is_liked: undefined,
is_disliked: undefined
};
this.annotations = info.annotations;
this.storyboards = info.storyboards;
this.endscreen = info.endscreen;
this.captions = info.captions;
this.cards = info.cards;
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 options
* @returns DASH manifest
*/
async toDash(options = {}) {
const player_response = __classPrivateFieldGet(this, _MediaInfo_page, "f")[0];
const manifest_options = options.manifest_options || {};
if (player_response.video_details && (player_response.video_details.is_live)) {
throw new InnertubeError('Generating DASH manifests for live 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;
let captions;
if (manifest_options.include_thumbnails && player_response.storyboards) {
storyboards = player_response.storyboards;
}
if (typeof manifest_options.captions_format === 'string' && player_response.captions?.caption_tracks) {
captions = player_response.captions.caption_tracks;
}
return FormatUtils.toDash(this.streaming_data, this.page[0].video_details?.is_post_live_dvr, options.url_transformer, options.format_filter, __classPrivateFieldGet(this, _MediaInfo_cpn, "f"), __classPrivateFieldGet(this, _MediaInfo_actions, "f").session.player, __classPrivateFieldGet(this, _MediaInfo_actions, "f"), storyboards, captions, manifest_options);
}
/**
* Get a cleaned up representation of the adaptive_formats
*/
getStreamingInfo(url_transformer, format_filter) {
return getStreamingInfo(this.streaming_data, this.page[0].video_details?.is_post_live_dvr, url_transformer, format_filter, this.cpn, __classPrivateFieldGet(this, _MediaInfo_actions, "f").session.player, __classPrivateFieldGet(this, _MediaInfo_actions, "f"), __classPrivateFieldGet(this, _MediaInfo_page, "f")[0].storyboards ? __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.
*/
async download(options = {}) {
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.
*/
async getTranscript() {
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 = transcript_panel.content?.as(ContinuationItem);
if (!transcript_continuation)
throw new InnertubeError('Transcript continuation not found.');
const response = await transcript_continuation.endpoint.call(this.actions);
return new TranscriptInfo(this.actions, response);
}
async addToWatchHistory(client_name, client_version, replacement = 'https://www.') {
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);
return await __classPrivateFieldGet(this, _MediaInfo_actions, "f").stats(url, {
client_name: client_name || Constants.CLIENTS.WEB.NAME,
client_version: client_version || Constants.CLIENTS.WEB.VERSION
}, url_params);
}
async updateWatchTime(startTime, client_name = Constants.CLIENTS.WEB.NAME, client_version = Constants.CLIENTS.WEB.VERSION, replacement = 'https://www.') {
if (!__classPrivateFieldGet(this, _MediaInfo_playback_tracking, "f"))
throw new InnertubeError('Playback tracking not available');
const url_params = {
cpn: __classPrivateFieldGet(this, _MediaInfo_cpn, "f"),
st: startTime.toFixed(3),
et: startTime.toFixed(3),
cmt: startTime.toFixed(3),
final: '1'
};
const url = __classPrivateFieldGet(this, _MediaInfo_playback_tracking, "f").videostats_watchtime_url.replace('https://s.', replacement);
return await __classPrivateFieldGet(this, _MediaInfo_actions, "f").stats(url, {
client_name,
client_version
}, url_params);
}
get actions() {
return __classPrivateFieldGet(this, _MediaInfo_actions, "f");
}
/**
* Content Playback Nonce.
*/
get cpn() {
return __classPrivateFieldGet(this, _MediaInfo_cpn, "f");
}
/**
* 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