const { spawn } = require("child_process"); const path = require("path"); const fs = require("fs"); const tmp = path.join(__dirname, "../tmp"); // path to your tmp folder const ytdlp = "yt-dlp"; // Assume yt-dlp is installed globally inside the Docker container const cookiesPath = path.join(__dirname, "./cookies/yt.txt"); function runYtDlp(args) { return new Promise((resolve, reject) => { const process = spawn(ytdlp, args, { stdio: ["ignore", "pipe", "pipe"] }); let stdout = ""; let stderr = ""; process.stdout.on("data", (data) => (stdout += data.toString())); process.stderr.on("data", (data) => (stderr += data.toString())); process.on("close", (code) => { if (code === 0) resolve(stdout.trim()); else reject(new Error(stderr.trim() || `yt-dlp exited with code ${code}`)); }); }); } async function getInfo(url) { try { const result = await runYtDlp(["-j", "--cookies", cookiesPath, url]); const info = JSON.parse(result); return { id: info.id, title: info.title, thumbnail: `https://i.ytimg.com/vi/${info.id}/maxresdefault.jpg`, description: info.description, duration: info.duration, views: info.view_count, likes: info.like_count, comments: info.comment_count, uploaded: info.timestamp, channel: { id: info.channel_id, handle: info.uploader_id, name: info.uploader, picture: info.channel_thumbnail || "", subscribers: info.channel_follower_count, verified: !!info.channel_is_verified, }, videos: [...new Set(info.formats.filter(v => v.video_ext === "mp4").map(v => v.height + "p"))], }; } catch (err) { throw new Error(`Failed to get video info: ${err.message}`); } } async function getVideo(url, quality = "480p") { const ts = Date.now(); const outputFile = `${tmp}/${ts}.mp4`; try { await runYtDlp(["--cookies", cookiesPath, "-f", `ba[ext=m4a]+bv[height=${quality.slice(0, -1)}]`, "--merge-output-format", "mp4", "-o", outputFile, url]); const result = fs.readFileSync(outputFile); fs.unlinkSync(outputFile); return result; } catch (err) { throw new Error(`Failed to download video: ${err.message}`); } } async function getAudio(url) { const ts = Date.now(); const outputFile = `${tmp}/${ts}.mp3`; try { await runYtDlp(["--cookies", cookiesPath,"-f", "ba", "-o", outputFile, url]); const result = fs.readFileSync(outputFile); fs.unlinkSync(outputFile); return result; } catch (err) { throw new Error(`Failed to download audio: ${err.message}`); } } module.exports = { getInfo, getAudio, getVideo, };