如何调整FFmpeg视频时长?拼接失效问题排查求助
问题
用FFmpeg在AWS Lambda上将3张图片制作成9秒视频,实际仅显示第一张图片3秒就结束。前期日志显示流程正常,怀疑processSingleImage的输出参数和视频拼接流程存在问题,代码如下:
async function processImages(imageStreams) { for (let i = 0; i < imageStreams.length; i++) { await processSingleImage(imageStreams[i], `/tmp/temp_video_${i}.mp4`, i); } await concatenateVideos(imageStreams.length); } async function processSingleImage(imageStream, outputPath, index) { return new Promise((resolve, reject) => { const command = ffmpeg(imageStream); command .outputOptions(["-c:v libx264", "-t 12", "-pix_fmt yuv420p", "-vf scale=1280:720", "-r 1"]) .on("end", () => { resolve(); }) .on("error", (err) => { console.error(`Error during processing of image ${index}:`, err); reject(err); }) .saveToFile(outputPath); }); } async function concatenateVideos(numberOfVideos) { const fileList = "/tmp/file_list.txt"; let fileContent = ""; for (let i = 0; i < numberOfVideos; i++) { fileContent += `file '/tmp/temp_video_${i}.mp4'\n`; } await fs.writeFile(fileList, fileContent); return new Promise((resolve, reject) => { ffmpeg() .input(fileList) .inputOptions(["-f concat", "-safe 0"]) .outputOptions(["-c copy"]) .saveToFile("/tmp/output.mp4"); }); }
修复方案
1. 修正单图片转视频的参数与时长
- 目标是每张图片显示3秒(3张共9秒),将
-t 12改为-t 3。 - 添加
-loop 1让图片循环播放,否则FFmpeg仅读取单帧,时长设置会失效;同时将帧率参数-r 1移至输入参数,确保按1帧/秒的速率生成视频。
修改后的processSingleImage:
async function processSingleImage(imageStream, outputPath, index) { return new Promise((resolve, reject) => { const command = ffmpeg(imageStream); command .inputOptions(["-loop 1", "-r 1"]) // 新增循环逻辑,设置输入帧率 .outputOptions(["-c:v libx264", "-t 3", "-pix_fmt yuv420p", "-vf scale=1280:720"]) .on("end", () => { resolve(); }) .on("error", (err) => { console.error(`Error during processing of image ${index}:`, err); reject(err); }) .saveToFile(outputPath); }); }
2. 修复拼接函数的Promise逻辑
原concatenateVideos中的FFmpeg命令未绑定end和error事件,导致Promise无法完成状态变更,Lambda可能在拼接完成前终止,生成不完整视频。需要补充事件监听:
修改后的concatenateVideos:
async function concatenateVideos(numberOfVideos) { const fileList = "/tmp/file_list.txt"; let fileContent = ""; for (let i = 0; i < numberOfVideos; i++) { fileContent += `file '/tmp/temp_video_${i}.mp4'\n`; } await fs.writeFile(fileList, fileContent); return new Promise((resolve, reject) => { ffmpeg() .input(fileList) .inputOptions(["-f concat", "-safe 0"]) .outputOptions(["-c copy"]) .on("end", () => { resolve(); }) .on("error", (err) => { console.error("Error during video concatenation:", err); reject(err); }) .saveToFile("/tmp/output.mp4"); }); }
3. 额外检查点
- 确认AWS Lambda临时存储空间有足够写入权限,且文件大小未超出限制。
- 可在日志中添加临时视频文件的时长校验,确保每张临时视频确实为3秒。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

