api/youtube: refactor playability status handling

This commit is contained in:
wukko 2024-10-23 18:08:50 +06:00
parent a3ee3d9c16
commit ae271fd3c6
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2

View file

@ -1,5 +1,4 @@
import { fetch } from "undici"; import { fetch } from "undici";
import { Innertube, Session } from "youtubei.js"; import { Innertube, Session } from "youtubei.js";
import { env } from "../../config.js"; import { env } from "../../config.js";
@ -146,41 +145,49 @@ 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;
if (playability.status === "LOGIN_REQUIRED") { switch(playability.status) {
if (playability.reason.endsWith("bot")) { case "OK":
return { error: "youtube.login" } break;
}
if (playability.reason.endsWith("age")) { case "LOGIN_REQUIRED":
return { error: "content.video.age" } if (playability.reason.endsWith("bot")) {
} return { error: "youtube.login" }
if (playability?.error_screen?.reason?.text === "Private video") { }
return { error: "content.video.private" } if (playability.reason.endsWith("age")) {
} return { error: "content.video.age" }
}
if (playability?.error_screen?.reason?.text === "Private video") {
return { error: "content.video.private" }
}
break;
case "UNPLAYABLE":
if (playability?.reason?.endsWith("request limit.")) {
return { error: "fetch.rate" }
}
if (playability?.error_screen?.subreason?.text?.endsWith("in your country")) {
return { error: "content.video.region" }
}
if (playability?.error_screen?.reason?.text === "Private video") {
return { error: "content.video.private" }
}
break;
case "AGE_VERIFICATION_REQUIRED":
return { error: "content.video.age" };
default:
return { error: "content.video.unavailable" };
} }
if (playability.status === "UNPLAYABLE") {
if (playability?.reason?.endsWith("request limit.")) {
return { error: "fetch.rate" }
}
if (playability?.error_screen?.subreason?.text?.endsWith("in your country")) {
return { error: "content.video.region" }
}
if (playability?.error_screen?.reason?.text === "Private video") {
return { error: "content.video.private" }
}
}
if (playability.status === "AGE_VERIFICATION_REQUIRED") {
return { error: "content.video.age" }
}
if (playability.status !== "OK") {
return { error: "content.video.unavailable" };
}
if (basicInfo.is_live) { if (basicInfo.is_live) {
return { error: "content.video.live" }; return { error: "content.video.live" };
} }
if (basicInfo.duration > env.durationLimit) {
return { error: "content.too_long" };
}
// return a critical error if returned video is "Video Not Available" // return a critical error if returned video is "Video Not Available"
// or a similar stub by youtube // or a similar stub by youtube
if (basicInfo.id !== o.id) { if (basicInfo.id !== o.id) {
@ -212,11 +219,9 @@ export default async function(o) {
if (bestVideo) bestQuality = qual(bestVideo); if (bestVideo) bestQuality = qual(bestVideo);
if ((!bestQuality && !o.isAudioOnly) || !hasAudio) if ((!bestQuality && !o.isAudioOnly) || !hasAudio) {
return { error: "youtube.codec" }; return { error: "youtube.codec" };
}
if (basicInfo.duration > env.durationLimit)
return { error: "content.too_long" };
const checkBestAudio = (i) => (i.has_audio && !i.has_video); const checkBestAudio = (i) => (i.has_audio && !i.has_video);
@ -226,9 +231,7 @@ export default async function(o) {
if (o.dubLang) { if (o.dubLang) {
let dubbedAudio = adaptive_formats.find(i => let dubbedAudio = adaptive_formats.find(i =>
checkBestAudio(i) checkBestAudio(i) && i.language === o.dubLang && i.audio_track
&& i.language === o.dubLang
&& i.audio_track
) )
if (dubbedAudio && !dubbedAudio?.audio_track?.audio_is_default) { if (dubbedAudio && !dubbedAudio?.audio_track?.audio_is_default) {
@ -313,5 +316,5 @@ export default async function(o) {
} }
} }
return { error: "fetch.fail" } return { error: "fetch.fail" };
} }