Created
October 31, 2023 15:37
-
-
Save betiol/55deb676330f8fe78f2db6db1a26d179 to your computer and use it in GitHub Desktop.
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 express = require("express"); | |
const ytdl = require("ytdl-core"); | |
const ffmpegPath = require("ffmpeg-static"); | |
const spawn = require("child_process").spawn; | |
const fs = require("fs"); | |
const app = express(); | |
const port = 3000; | |
const startMinute = 3; | |
const startSecond = 51; | |
const endMinute = 4; | |
const endSecond = 51; | |
app.use(express.json()); | |
app.post("/download-cut-and-merge", async (req, res) => { | |
try { | |
const { videoUrl } = req.body; | |
if (!videoUrl) { | |
return res.status(400).json({ error: "url not provided" }); | |
} | |
const videoFileName = `${Date.now()}_video.mp4`; | |
const audioFileName = `${Date.now()}_audio.aac`; | |
const finalFileName = `${Date.now()}_final.mp4`; | |
const start = startMinute * 60 + startSecond; | |
const end = endMinute * 60 + endSecond; | |
const videoStream = ytdl(videoUrl, { | |
filter: (format) => { | |
return ( | |
(format.container === "mp4" && | |
format.hasVideo && | |
format.quality === "hd2160") || | |
(format.container === "webm" && | |
format.hasVideo && | |
format.quality === "hd2160") | |
); | |
}, | |
range: { start: 0, end: 1000 } | |
}); | |
videoStream.pipe(fs.createWriteStream(videoFileName)); | |
videoStream.on("end", () => { | |
const audioStream = ytdl(videoUrl, { | |
format: "audioonly" | |
}); | |
audioStream.pipe(fs.createWriteStream(audioFileName)); | |
audioStream.on("end", () => { | |
const ffmpegProcess = spawn(ffmpegPath, [ | |
"-i", | |
videoFileName, | |
"-i", | |
audioFileName, | |
"-c:v", | |
"libx264", | |
"-c:a", | |
"aac", | |
finalFileName | |
]); | |
ffmpegProcess.on("close", () => { | |
const outputPath = `./downloads/${finalFileName}`; | |
fs.unlinkSync(videoFileName); | |
fs.unlinkSync(audioFileName); | |
const checkInterval = setInterval(() => { | |
if (fs.existsSync(outputPath)) { | |
clearInterval(checkInterval); | |
res.download(outputPath, "final_video.mp4", (err) => { | |
if (err) { | |
console.error("error:", err); | |
res.status(500).json({ error: "error" }); | |
} | |
}); | |
} | |
}, 1000); | |
}); | |
ffmpegProcess.on("error", (err) => { | |
console.error("ffmpeg error:", err); | |
res.status(500).json({ error: "ffmpeg error" }); | |
}); | |
}); | |
audioStream.on("error", (err) => { | |
console.error("audio error:", err); | |
res.status(500).json({ error: "audio error" }); | |
}); | |
}); | |
videoStream.on("error", (err) => { | |
console.error("error to download video:", err); | |
res.status(500).json({ error: "error to download video" }); | |
}); | |
} catch (err) { | |
console.error("idk:", err); | |
res.status(500).json({ error: "idk" }); | |
} | |
}); | |
app.listen(port, () => { | |
console.log(`running at port ${port}`); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment