mirror of
https://github.com/wukko/cobalt.git
synced 2025-02-24 12:08:55 +01:00
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 format = o.format || "h264";
|
||||||
|
let fallback = false;
|
||||||
|
|
||||||
const filterByCodec = (formats) =>
|
const filterByCodec = (formats) =>
|
||||||
formats.filter(e =>
|
formats.filter(e =>
|
||||||
|
@ -195,25 +196,32 @@ export default async function(o) {
|
||||||
|
|
||||||
let adaptive_formats = filterByCodec(info.streaming_data.adaptive_formats);
|
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";
|
format = "h264";
|
||||||
adaptive_formats = filterByCodec(info.streaming_data.adaptive_formats);
|
adaptive_formats = filterByCodec(info.streaming_data.adaptive_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bestVideo = adaptive_formats.find(i => i.has_video && i.content_length);
|
const bestVideo = !fallback ? earlyBestVideo : adaptive_formats.find(i => checkBestVideo(i));
|
||||||
const hasAudio = adaptive_formats.find(i => i.has_audio && i.content_length);
|
const bestAudio = !fallback ? earlyBestAudio : adaptive_formats.find(i => checkBestAudio(i));
|
||||||
|
|
||||||
if ((!bestVideo && !o.isAudioOnly) || (!hasAudio && o.isAudioOnly)) {
|
if (checkNoMedia(bestVideo, bestAudio)) {
|
||||||
return { error: "fetch.empty" };
|
return { error: "youtube.codec" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkBestAudio = (i) => (i.has_audio && !i.has_video);
|
let audio = bestAudio;
|
||||||
|
|
||||||
let audio = adaptive_formats.find(i => checkBestAudio(i) && i.is_original);
|
|
||||||
let isDubbed;
|
let isDubbed;
|
||||||
|
|
||||||
if (o.dubLang) {
|
if (o.dubLang) {
|
||||||
let dubbedAudio = adaptive_formats.find(i =>
|
const dubbedAudio = adaptive_formats.find(i =>
|
||||||
checkBestAudio(i) && i.language === o.dubLang && i.audio_track
|
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 = {
|
const fileMetadata = {
|
||||||
title: cleanString(basicInfo.title.trim()),
|
title: cleanString(basicInfo.title.trim()),
|
||||||
artist: cleanString(basicInfo.author.replace("- Topic", "").trim())
|
artist: cleanString(basicInfo.author.replace("- Topic", "").trim())
|
||||||
|
@ -262,19 +266,16 @@ export default async function(o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const qual = (i) => {
|
const qual = (i) => {
|
||||||
if (!i.quality_label) {
|
if (!i.quality_label) return;
|
||||||
return;
|
return i.quality_label.split('p', 2)[0].split('s', 2)[0];
|
||||||
}
|
|
||||||
|
|
||||||
return i.quality_label.split('p', 2)[0].split('s', 2)[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const quality = o.quality === "max" ? "9000" : o.quality;
|
const quality = o.quality === "max" ? "9000" : o.quality;
|
||||||
const bestQuality = qual(bestVideo);
|
const bestQuality = qual(bestVideo);
|
||||||
const matchingQuality = Number(quality) > Number(bestQuality) ? bestQuality : quality;
|
const useBestQuality = Number(quality) > Number(bestQuality);
|
||||||
|
|
||||||
const video = adaptive_formats.find(i =>
|
const video = useBestQuality ? bestVideo : adaptive_formats.find(i =>
|
||||||
qual(i) === matchingQuality && i.has_video && !i.has_audio
|
qual(i) === quality && checkBestVideo(i)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (video && audio) {
|
if (video && audio) {
|
||||||
|
|
Loading…
Reference in a new issue