Spaces:
Paused
Paused
| 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, | |
| }; | |