api/youtube: add hls codec fallback, update hls error code, refactor

also fixed best audio format
This commit is contained in:
wukko 2024-10-28 15:45:18 +06:00
parent 60b22cb5f7
commit fba6ba09c2
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2

View file

@ -210,7 +210,7 @@ export default async function(o) {
const hlsManifest = info.streaming_data.hls_manifest_url; const hlsManifest = info.streaming_data.hls_manifest_url;
if (!hlsManifest) { if (!hlsManifest) {
return { error: "content.video.no_streams" }; return { error: "youtube.no_hls_streams" };
} }
const fetchedHlsManifest = await fetch(hlsManifest, { const fetchedHlsManifest = await fetch(hlsManifest, {
@ -224,7 +224,7 @@ export default async function(o) {
}).catch(() => {}); }).catch(() => {});
if (!fetchedHlsManifest) { if (!fetchedHlsManifest) {
return { error: "content.video.no_streams" }; return { error: "youtube.no_hls_streams" };
} }
const variants = HLS.parse(fetchedHlsManifest).variants.sort( const variants = HLS.parse(fetchedHlsManifest).variants.sort(
@ -232,34 +232,41 @@ export default async function(o) {
); );
if (!variants || variants.length === 0) { if (!variants || variants.length === 0) {
return { error: "content.video.no_streams" }; return { error: "youtube.no_hls_streams" };
}
// HLS playlists don't contain AV1 format, at least with the iOS client
if (format === "av1") {
format = "vp9";
} }
const matchHlsCodec = codecs => ( const matchHlsCodec = codecs => (
codecs.includes(hlsCodecList[format].videoCodec) codecs.includes(hlsCodecList[format].videoCodec)
); );
const best = variants.find(i => { const best = variants.find(i => matchHlsCodec(i.codecs));
if (matchHlsCodec(i.codecs)) {
return i; const preferred = variants.find(i =>
matchHlsCodec(i.codecs) && matchQuality(i.resolution) === quality
);
let selected = preferred || best;
if (!selected) {
format = "h264";
selected = variants.find(i => matchHlsCodec(i.codecs));
} }
});
const preferred = variants.find((i) => { if (!selected) {
if (matchHlsCodec(i.codecs) && matchQuality(i.resolution) === quality) { return { error: "youtube.no_hls_streams" };
return i;
} }
});
const selected = preferred || best; audio = selected.audio.find(i => i.isDefault);
const defaultAudio = selected.audio.find(i => i.isDefault);
audio = defaultAudio;
if (o.dubLang) { if (o.dubLang) {
const dubbedAudio = selected.audio.find(i => const dubbedAudio = selected.audio.find(i =>
i.language === o.dubLang i.language === o.dubLang
) );
if (dubbedAudio && !dubbedAudio.isDefault) { if (dubbedAudio && !dubbedAudio.isDefault) {
audio = dubbedAudio; audio = dubbedAudio;
@ -359,15 +366,20 @@ export default async function(o) {
youtubeDubName: isDubbed ? o.dubLang : false youtubeDubName: isDubbed ? o.dubLang : false
} }
if (audio && o.isAudioOnly) return { if (audio && o.isAudioOnly) {
let bestAudio = format === "h264" ? "m4a" : "opus";
if (o.youtubeHLS) bestAudio = "m4a";
return {
type: "audio", type: "audio",
isAudioOnly: true, isAudioOnly: true,
urls: audio.url, urls: audio.url,
filenameAttributes, filenameAttributes,
fileMetadata, fileMetadata,
bestAudio: format === "h264" ? "m4a" : "opus", bestAudio,
isHLS: o.youtubeHLS, isHLS: o.youtubeHLS,
} }
}
if (video && audio) { if (video && audio) {
let resolution; let resolution;