Skip to content

Instantly share code, notes, and snippets.

@betiol
Created October 31, 2023 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save betiol/55deb676330f8fe78f2db6db1a26d179 to your computer and use it in GitHub Desktop.
Save betiol/55deb676330f8fe78f2db6db1a26d179 to your computer and use it in GitHub Desktop.
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