feat: implement automatic yt-dlp and ffmpeg dependency management and media downloading logic

This commit is contained in:
Ümit Tunç
2026-05-28 07:17:55 +03:00
parent 2b303cfc9b
commit c07d68fab1
5 changed files with 107 additions and 23 deletions
+34 -12
View File
@@ -169,12 +169,17 @@ async function checkDependencies(onStatusUpdate) {
}
// Get video metadata (title, thumbnail, duration, etc.)
function getVideoInfo(url) {
function getVideoInfo(url, browser) {
console.log(`[DEBUG] Fetching info for URL: ${url}`);
return new Promise((resolve, reject) => {
// Adding '--no-playlist' prevents yt-dlp from crawling the entire playlist (which hangs/takes extremely long)
console.log(`[DEBUG] Spawning process: ${YTDLP_PATH} --no-playlist -j ${url}`);
const proc = spawn(YTDLP_PATH, ['--no-playlist', '-j', url]);
let args = ['--no-playlist', '-j'];
if (browser) {
args.push('--cookies-from-browser', browser);
}
args.push(url);
console.log(`[DEBUG] Spawning process: ${YTDLP_PATH} ${args.join(' ')}`);
const proc = spawn(YTDLP_PATH, args);
let stdout = '';
let stderr = '';
@@ -206,11 +211,13 @@ function getVideoInfo(url) {
}
// Download video or convert to MP3
function downloadMedia(url, format, quality, outputDir, onProgress) {
console.log(`[DEBUG] Media download requested. Format: ${format}, Quality: ${quality}, Target Dir: ${outputDir}`);
function downloadMedia(url, format, quality, outputDir, browser, onProgress) {
console.log(`[DEBUG] Media download requested. Format: ${format}, Quality: ${quality}, Target Dir: ${outputDir}, Browser Cookies: ${browser || 'none'}`);
return new Promise((resolve, reject) => {
let args = [];
const outputTemplate = path.join(outputDir, '%(title)s.%(ext)s');
const startTime = Date.now();
let totalSize = 'Bilinmiyor';
if (format === 'mp3') {
const q = quality ? `${quality}K` : '320K'; // '320K', '256K', '192K'
@@ -220,25 +227,35 @@ function downloadMedia(url, format, quality, outputDir, onProgress) {
'-x',
'--audio-format', 'mp3',
'--audio-quality', q,
'-o', outputTemplate,
url
'-o', outputTemplate
];
} else {
const res = quality || '1080'; // '1080', '720', '480'
args = [
'--no-playlist',
'--ffmpeg-location', FFMPEG_PATH,
'-f', `bv*[height<=${res}][ext=mp4]+ba[ext=m4a]/b[height<=${res}][ext=mp4] / bv*[height<=${res}]+ba/b[height<=${res}]`,
'-o', outputTemplate,
url
'-f', `bv*[height<=${res}][ext=mp4]+ba[ext=m4a]/b[height<=${res}][ext=mp4]/bv*[height<=${res}]+ba/b[height<=${res}]/bestvideo+bestaudio/best`,
'-o', outputTemplate
];
}
if (browser) {
args.push('--cookies-from-browser', browser);
}
args.push(url);
console.log(`[DEBUG] Spawning downloader process: ${YTDLP_PATH} ${args.join(' ')}`);
const proc = spawn(YTDLP_PATH, args);
proc.stdout.on('data', (data) => {
const line = data.toString();
// Parse total size: e.g. [download] 1.2% of 8.37MiB at...
const sizeMatch = line.match(/of\s+(\d+(?:\.\d+)?\s*[a-zA-Z]+)/);
if (sizeMatch) {
totalSize = sizeMatch[1];
}
const match = line.match(/\[download\]\s+(\d+\.\d+)%/);
if (match && onProgress) {
const percent = parseFloat(match[1]);
@@ -256,7 +273,12 @@ function downloadMedia(url, format, quality, outputDir, onProgress) {
proc.on('close', (code) => {
console.log(`[DEBUG] Downloader process exited with code ${code}`);
if (code === 0) {
resolve();
const durationSec = ((Date.now() - startTime) / 1000).toFixed(1);
resolve({
size: totalSize,
duration: `${durationSec} saniye`,
outputDir: outputDir
});
} else {
reject(new Error(`Download exited with code ${code}`));
}