|
|
// alternate.js |
|
|
|
|
|
const fs = require("fs"); |
|
|
const path = require("path"); |
|
|
const { spawn } = require("child_process"); |
|
|
|
|
|
// Ensure output folder exists |
|
|
if (!fs.existsSync("output")) fs.mkdirSync("output"); |
|
|
|
|
|
// Step 1: Search for files |
|
|
const inputDir = "inputs"; |
|
|
const files = fs.readdirSync(inputDir); |
|
|
|
|
|
const audioFile = files.find(f => f.toLowerCase().endsWith(".wav")); |
|
|
const imageFile = files.find(f => f.toLowerCase().match(/\.(jpg|jpeg|svg)$/)); |
|
|
|
|
|
if (!audioFile || !imageFile) { |
|
|
console.error("❌ Missing .wav and/or .jpg/.svg file in inputs/"); |
|
|
process.exit(1); |
|
|
} |
|
|
|
|
|
const audioPath = path.join(inputDir, audioFile); |
|
|
const imagePath = path.join(inputDir, imageFile); |
|
|
const outputName = `output-${Date.now()}.mp4`; |
|
|
const outputPath = path.join("output", outputName); |
|
|
|
|
|
// Step 2: Convert using ffmpeg (no duration check) |
|
|
console.log(`🎧 Found: ${audioFile}`); |
|
|
console.log(`🖼️ Found: ${imageFile}`); |
|
|
console.log(`🚀 Starting conversion → ${outputName}`); |
|
|
|
|
|
const args = [ |
|
|
"-loop", "1", |
|
|
"-i", imagePath, |
|
|
"-i", audioPath, |
|
|
"-c:v", "libx264", |
|
|
"-preset", "ultrafast", |
|
|
"-tune", "stillimage", |
|
|
"-crf", "23", |
|
|
"-c:a", "aac", |
|
|
"-shortest", |
|
|
"-pix_fmt", "yuv420p", |
|
|
"-movflags", "+faststart", |
|
|
outputPath |
|
|
]; |
|
|
|
|
|
const ffmpeg = spawn("ffmpeg", args); |
|
|
|
|
|
ffmpeg.stderr.on("data", (data) => { |
|
|
console.log(data.toString().trim()); // log raw ffmpeg output |
|
|
}); |
|
|
|
|
|
ffmpeg.on("exit", (code) => { |
|
|
if (code !== 0) { |
|
|
console.error(`❌ FFmpeg exited with code ${code}`); |
|
|
return; |
|
|
} |
|
|
|
|
|
console.log(`✅ Conversion complete! Saved to: ${outputPath}`); |
|
|
});
|
|
|
|