Browse Source

Enhance audio conversion endpoint with duration analysis and progress logging

master
Atanner 8 months ago
parent
commit
753fd52701
  1. 60
      index.js

60
index.js

@ -1,14 +1,13 @@
const express = require("express"); const express = require("express");
const multer = require("multer"); const multer = require("multer");
const { spawn } = require("child_process"); const { spawn, execSync } = require("child_process");
const fs = require("fs"); const fs = require("fs");
const app = express(); const app = express();
const upload = multer({ dest: "uploads/" }); const upload = multer({ dest: "uploads/" });
app.post("/convert", upload.fields([{ name: "audio" }, { name: "image" }]), (req, res) => { app.post("/convert", upload.fields([{ name: "audio" }, { name: "image" }]), async (req, res) => {
if (!req.files || !req.files.audio || !req.files.image) { if (!req.files?.audio || !req.files?.image) {
console.error("❌ Missing file(s) in request");
return res.status(400).send("Missing audio or image file."); return res.status(400).send("Missing audio or image file.");
} }
@ -16,56 +15,67 @@ app.post("/convert", upload.fields([{ name: "audio" }, { name: "image" }]), (req
const imagePath = req.files.image[0].path; const imagePath = req.files.image[0].path;
const output = `output-${Date.now()}.mp4`; const output = `output-${Date.now()}.mp4`;
let durationSec = 0;
try {
const durationStr = execSync(
`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 ${audioPath}`
).toString().trim();
durationSec = parseFloat(durationStr);
console.log(`🎧 Audio duration: ${durationSec.toFixed(2)} sec`);
} catch (err) {
console.error("❌ Could not determine audio duration");
return res.status(500).send("Failed to analyze audio.");
}
const args = [ const args = [
"-loop", "1", "-loop", "1",
"-i", imagePath, "-i", imagePath,
"-i", audioPath, "-i", audioPath,
"-c:v", "libx264", "-c:v", "libx264",
"-preset", "fast", "-preset", "ultrafast",
"-tune", "stillimage", "-tune", "stillimage",
"-crf", "18", "-crf", "23",
"-c:a", "aac", "-c:a", "aac",
"-shortest", "-shortest",
"-pix_fmt", "yuv420p", "-pix_fmt", "yuv420p",
"-movflags", "+faststart",
output output
]; ];
console.log(`🚀 Starting FFmpeg conversion: ${output}`); console.log(`🚀 Starting conversion to ${output}`);
const ffmpeg = spawn("ffmpeg", args); const ffmpeg = spawn("ffmpeg", args);
let lastLog = Date.now();
ffmpeg.stderr.on("data", (data) => { ffmpeg.stderr.on("data", (data) => {
const now = Date.now(); const line = data.toString().trim();
const text = data.toString(); const timeMatch = line.match(/time=(\d+):(\d+):([\d.]+)/);
// Log a progress update every 3 seconds max if (timeMatch) {
if (text.includes("frame=") && now - lastLog > 3000) { const [, h, m, s] = timeMatch;
console.log(`[FFmpeg Progress] ${text.trim()}`); const timeSec = parseInt(h) * 3600 + parseInt(m) * 60 + parseFloat(s);
lastLog = now; const percent = Math.min(100, ((timeSec / durationSec) * 100).toFixed(1));
console.log(`${line} | 📊 ${percent}%`);
} else {
console.log(line);
} }
// If you want verbose output uncomment this:
// console.log(`[FFmpeg Raw] ${text.trim()}`);
}); });
ffmpeg.on("exit", (code) => { ffmpeg.on("exit", (code) => {
if (code !== 0) { if (code !== 0) {
console.error(`❌ FFmpeg failed with code ${code}`); console.error(`❌ FFmpeg exited with code ${code}`);
res.status(500).send("Conversion failed"); return res.status(500).send("Conversion failed");
} else { }
console.log("✅ FFmpeg finished successfully. Sending file...");
console.log("✅ Conversion complete. Sending file...");
res.download(output, () => { res.download(output, () => {
fs.unlinkSync(audioPath); fs.unlinkSync(audioPath);
fs.unlinkSync(imagePath); fs.unlinkSync(imagePath);
fs.unlinkSync(output); fs.unlinkSync(output);
}); });
}
}); });
}); });
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.send("🎧 FileConvert API is up."); res.send("🎧 FileConvert API is running.");
}); });
app.listen(3000, () => console.log("✅ FileConvert API running on http://0.0.0.0:3000")); app.listen(3000, () => console.log("✅ Listening on http://0.0.0.0:3000"));

Loading…
Cancel
Save