api/youtube: refactor, fix fallback, don't repeat same actions
fallback to h264 is now done if there's no required media, not only if adaptive formats list is empty. best audio and best video are now picked only once.
This commit is contained in:
parent
7dc0121031
commit
7798844755
1 changed files with 22 additions and 21 deletions
|
@ -184,6 +184,7 @@ export default async function(o) {
|
|||
}
|
||||
|
||||
let format = o.format || "h264";
|
||||
let fallback = false;
|
||||
|
||||
const filterByCodec = (formats) =>
|
||||
formats.filter(e =>
|
||||
|
@ -195,25 +196,32 @@ export default async function(o) {
|
|||
|
||||
let adaptive_formats = filterByCodec(info.streaming_data.adaptive_formats);
|
||||
|
||||
if (adaptive_formats.length === 0 && ["vp9", "av1"].includes(format)) {
|
||||
const checkBestVideo = (i) => (i.has_video && i.content_length);
|
||||
const checkBestAudio = (i) => (i.has_audio && i.content_length && i.is_original);
|
||||
const checkNoMedia = (video, audio) => (!video && !o.isAudioOnly) || (!audio && o.isAudioOnly);
|
||||
|
||||
const earlyBestVideo = adaptive_formats.find(i => checkBestVideo(i));
|
||||
const earlyBestAudio = adaptive_formats.find(i => checkBestAudio(i));
|
||||
|
||||
// check if formats have all needed media and fall back to h264 if not
|
||||
if (["vp9", "av1"].includes(format) && checkNoMedia(earlyBestVideo, earlyBestAudio)) {
|
||||
fallback = true;
|
||||
format = "h264";
|
||||
adaptive_formats = filterByCodec(info.streaming_data.adaptive_formats);
|
||||
}
|
||||
|
||||
const bestVideo = adaptive_formats.find(i => i.has_video && i.content_length);
|
||||
const hasAudio = adaptive_formats.find(i => i.has_audio && i.content_length);
|
||||
const bestVideo = !fallback ? earlyBestVideo : adaptive_formats.find(i => checkBestVideo(i));
|
||||
const bestAudio = !fallback ? earlyBestAudio : adaptive_formats.find(i => checkBestAudio(i));
|
||||
|
||||
if ((!bestVideo && !o.isAudioOnly) || (!hasAudio && o.isAudioOnly)) {
|
||||
return { error: "fetch.empty" };
|
||||
if (checkNoMedia(bestVideo, bestAudio)) {
|
||||
return { error: "youtube.codec" };
|
||||
}
|
||||
|
||||
const checkBestAudio = (i) => (i.has_audio && !i.has_video);
|
||||
|
||||
let audio = adaptive_formats.find(i => checkBestAudio(i) && i.is_original);
|
||||
let audio = bestAudio;
|
||||
let isDubbed;
|
||||
|
||||
if (o.dubLang) {
|
||||
let dubbedAudio = adaptive_formats.find(i =>
|
||||
const dubbedAudio = adaptive_formats.find(i =>
|
||||
checkBestAudio(i) && i.language === o.dubLang && i.audio_track
|
||||
)
|
||||
|
||||
|
@ -223,10 +231,6 @@ export default async function(o) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!audio) {
|
||||
audio = adaptive_formats.find(i => checkBestAudio(i));
|
||||
}
|
||||
|
||||
const fileMetadata = {
|
||||
title: cleanString(basicInfo.title.trim()),
|
||||
artist: cleanString(basicInfo.author.replace("- Topic", "").trim())
|
||||
|
@ -262,19 +266,16 @@ export default async function(o) {
|
|||
}
|
||||
|
||||
const qual = (i) => {
|
||||
if (!i.quality_label) {
|
||||
return;
|
||||
}
|
||||
|
||||
return i.quality_label.split('p', 2)[0].split('s', 2)[0]
|
||||
if (!i.quality_label) return;
|
||||
return i.quality_label.split('p', 2)[0].split('s', 2)[0];
|
||||
}
|
||||
|
||||
const quality = o.quality === "max" ? "9000" : o.quality;
|
||||
const bestQuality = qual(bestVideo);
|
||||
const matchingQuality = Number(quality) > Number(bestQuality) ? bestQuality : quality;
|
||||
const useBestQuality = Number(quality) > Number(bestQuality);
|
||||
|
||||
const video = adaptive_formats.find(i =>
|
||||
qual(i) === matchingQuality && i.has_video && !i.has_audio
|
||||
const video = useBestQuality ? bestVideo : adaptive_formats.find(i =>
|
||||
qual(i) === quality && checkBestVideo(i)
|
||||
);
|
||||
|
||||
if (video && audio) {
|
||||
|
|
Loading…
Reference in a new issue