api/youtube: use poToken, visitorData, and web client with cookies

and also decipher media whenever needed, but only if cookies are used
This commit is contained in:
wukko 2024-12-23 22:58:16 +06:00
parent 9da3ba60a9
commit c6d0e0bdd5
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2

View file

@ -48,7 +48,7 @@ const transformSessionData = (cookie) => {
return; return;
const values = { ...cookie.values() }; const values = { ...cookie.values() };
const REQUIRED_VALUES = [ 'access_token', 'refresh_token' ]; const REQUIRED_VALUES = ['access_token', 'refresh_token'];
if (REQUIRED_VALUES.some(x => typeof values[x] !== 'string')) { if (REQUIRED_VALUES.some(x => typeof values[x] !== 'string')) {
return; return;
@ -66,12 +66,18 @@ const transformSessionData = (cookie) => {
const cloneInnertube = async (customFetch) => { const cloneInnertube = async (customFetch) => {
const shouldRefreshPlayer = lastRefreshedAt + PLAYER_REFRESH_PERIOD < new Date(); const shouldRefreshPlayer = lastRefreshedAt + PLAYER_REFRESH_PERIOD < new Date();
const cookie = getCookie('youtube')?.toString();
const rawCookie = getCookie('youtube');
const cookieValues = rawCookie?.values();
const cookie = rawCookie?.toString();
if (!innertube || shouldRefreshPlayer) { if (!innertube || shouldRefreshPlayer) {
innertube = await Innertube.create({ innertube = await Innertube.create({
fetch: customFetch, fetch: customFetch,
retrieve_player: false, retrieve_player: !!cookie,
cookie cookie,
po_token: cookieValues?.po_token,
visitor_data: cookieValues?.visitor_data,
}); });
lastRefreshedAt = +new Date(); lastRefreshedAt = +new Date();
} }
@ -117,7 +123,7 @@ const cloneInnertube = async (customFetch) => {
return yt; return yt;
} }
export default async function(o) { export default async function (o) {
let yt; let yt;
try { try {
yt = await cloneInnertube( yt = await cloneInnertube(
@ -134,6 +140,8 @@ export default async function(o) {
} else throw e; } else throw e;
} }
const cookie = getCookie('youtube')?.toString();
let useHLS = o.youtubeHLS; let useHLS = o.youtubeHLS;
// HLS playlists don't contain the av1 video format, at least with the iOS client // HLS playlists don't contain the av1 video format, at least with the iOS client
@ -141,9 +149,20 @@ export default async function(o) {
useHLS = false; useHLS = false;
} }
let innertubeClient = "ANDROID";
if (cookie) {
useHLS = false;
innertubeClient = "WEB";
}
if (useHLS) {
innertubeClient = "IOS";
}
let info; let info;
try { try {
info = await yt.getBasicInfo(o.id, useHLS ? 'IOS' : 'ANDROID'); info = await yt.getBasicInfo(o.id, innertubeClient);
} catch (e) { } catch (e) {
if (e?.info) { if (e?.info) {
const errorInfo = JSON.parse(e?.info); const errorInfo = JSON.parse(e?.info);
@ -168,7 +187,7 @@ export default async function(o) {
const playability = info.playability_status; const playability = info.playability_status;
const basicInfo = info.basic_info; const basicInfo = info.basic_info;
switch(playability.status) { switch (playability.status) {
case "LOGIN_REQUIRED": case "LOGIN_REQUIRED":
if (playability.reason.endsWith("bot")) { if (playability.reason.endsWith("bot")) {
return { error: "youtube.login" } return { error: "youtube.login" }
@ -243,7 +262,7 @@ export default async function(o) {
} else { } else {
throw new Error("couldn't fetch the HLS playlist"); throw new Error("couldn't fetch the HLS playlist");
} }
}).catch(() => {}); }).catch(() => { });
if (!fetchedHlsManifest) { if (!fetchedHlsManifest) {
return { error: "youtube.no_hls_streams" }; return { error: "youtube.no_hls_streams" };
@ -324,7 +343,7 @@ export default async function(o) {
} }
const checkFormat = (format, pCodec) => format.content_length && const checkFormat = (format, pCodec) => format.content_length &&
(format.mime_type.includes(codecList[pCodec].videoCodec) (format.mime_type.includes(codecList[pCodec].videoCodec)
|| format.mime_type.includes(codecList[pCodec].audioCodec)); || format.mime_type.includes(codecList[pCodec].audioCodec));
// sort formats & weed out bad ones // sort formats & weed out bad ones
@ -438,6 +457,10 @@ export default async function(o) {
urls = audio.uri; urls = audio.uri;
} }
if (innertubeClient === "WEB" && innertube) {
urls = audio.decipher(innertube.session.player);
}
return { return {
type: "audio", type: "audio",
isAudioOnly: true, isAudioOnly: true,
@ -464,11 +487,17 @@ export default async function(o) {
width: video.width, width: video.width,
height: video.height, height: video.height,
}); });
filenameAttributes.resolution = `${video.width}x${video.height}`; filenameAttributes.resolution = `${video.width}x${video.height}`;
filenameAttributes.extension = codecList[codec].container; filenameAttributes.extension = codecList[codec].container;
video = video.url; video = video.url;
audio = audio.url; audio = audio.url;
if (innertubeClient === "WEB" && innertube) {
video = video.decipher(innertube.session.player);
audio = audio.decipher(innertube.session.player);
}
} }
filenameAttributes.qualityLabel = `${resolution}p`; filenameAttributes.qualityLabel = `${resolution}p`;