Last active
April 15, 2024 20:51
-
-
Save astrarudra/59da1dbb42bddff3460a74fe5170ac37 to your computer and use it in GitHub Desktop.
yt-dlp - Compute approx file size
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const filterYTVideoFormats = (info) => { | |
const { formats, requested_formats } = info | |
let bestAudio = requested_formats.find(o => o.vcodec === "none") | |
const filteredFormats = Object.values(formats.reduce((acc, curr) => { | |
if(!curr.height || curr.height < 480 || curr.format_note === "Premium") return acc | |
curr.vcodec = curr.vcodec.split('.')[0] | |
const selected = acc[curr.height] | |
// Already there is a selecton for this height - Select Better, use approx if filesize not available | |
if(selected){ | |
let better = false | |
if(curr.vcodec === "av01") { // Best Codec. | |
if(selected.vcodec === "av01") better = curr.vbr > selected.vbr | |
else better = true | |
} else if(selected.vcodec !== "av01" && curr.vcodec === "vp09") { | |
if(selected.vcodec === "vp09") better = curr.vbr > selected.vbr | |
else better = true | |
} | |
if(!better) better = curr.vbr > selected.vbr | |
if(!better){ // if curr is not better, we will see if we can use it's file size | |
const useForApprox = !selected.size && curr.filesize | |
if(useForApprox){ | |
selected.size = (curr.filesize / curr.vbr) * selected.vbr | |
selected.approx = true | |
} | |
return acc | |
} | |
// if curr is better and dont have file size, we will use existing file size if available. | |
if(selected.size && !curr.filesize){ | |
curr.filesize = (selected.size / selected.vbr) * curr.vbr | |
curr.approx = true | |
} | |
} | |
const { height, width, filesize, vbr, resolution, approx, audio_channels, format_id, vcodec } = curr | |
acc[curr.height] = { | |
id: format_id, h: height, w: width, res: resolution, size: filesize, | |
approx, vbr, vcodec, | |
hasAudio: !!audio_channels, | |
} | |
return acc; | |
}, {})); | |
filteredFormats.forEach(o => { | |
o.size = parseFloat((( !o.hasAudio ? (o.size + bestAudio.filesize) : o.size) / 1048576).toFixed(2)) | |
}) | |
const { id, title, acodec, aspect_ratio, asr, audio_channels, duration_string, fps, language } = info | |
const response = { | |
id, | |
formats: filteredFormats.sort((a, b) => b.h - a.h), | |
info: { | |
title, | |
aid: bestAudio.format_id, | |
acodec, asr, fps, language, | |
ratio: aspect_ratio, | |
audioChannels: audio_channels, | |
duration: duration_string, | |
}, | |
} | |
return response | |
} | |
const ytDetails = (ytHash) => { | |
return new Promise((resolve, reject) => { | |
console.log("INPUT YT-INFO: ", ytHash) | |
exec(`yt-dlp -j ${ytHash}`, (error, stdout, stderr) => { | |
console.log("YT-INFO RAW JSON: ", info); | |
try { | |
const info = JSON.parse(stdout); | |
resolve(response); | |
} catch (parseError) { | |
console.error('Error parsing JSON:', parseError); | |
reject(parseError); | |
} | |
}) | |
}) | |
} | |
// Usage | |
ytDetails(ytHash).then(info => { | |
const data = filterYTVideoFormats(info) | |
console.log(data) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment