如何让videoshow或JS包按指定时长合并图片与音频(而非固定5秒)
解决图片与音频合并MP4时长固定5秒及音频淡出问题
问题根源
你当前代码的核心问题是定义了videoOptions但未传递给videoshow实例,videoshow默认的图片循环时长为5秒,所以无论你设置多少duration都不会生效;音频末尾淡出也是videoshow的默认行为。
方案1:修复videoshow代码
方式1:传递全局配置
将定义好的videoOptions作为第二个参数传给videoshow,让全局配置生效:
const imgToMP4 = (caption, sound, image, duration, output) => { smartLog('info', `Converting ${image}`); const videoOptions = { fps: 10, loop: duration, transition: false, videoBitrate: 1024, videoCodec: 'libx264', size: '640x?', audioBitrate: '128k', audioChannels: 2, format: 'mp4', pixelFormat: 'yuv420p', }; // 关键:将videoOptions作为第二个参数传入 videoshow([{ path: image }], videoOptions) .audio(sound, { fade: false }) // 添加fade: false禁用音频淡出 .save(output) .on('start', function (command) { smartLog('info', `ffmpeg process started: ${image}`); }) .on('error', function (err) { smartLog('error', err); }) .on('end', function (output) { smartLog('info', `Video created: ${output}`); }); };
方式2:单独设置图片时长
如果只需要给单张图片设置时长,也可以直接在图片对象中指定loop,优先级高于全局配置:
videoshow([ { path: image, loop: duration // 直接给当前图片设置循环时长 } ]) .audio(sound, { fade: false }) .save(output) // ... 事件监听代码不变
方案2:直接使用fluent-ffmpeg(推荐)
避开包装器的默认行为限制,直接用fluent-ffmpeg可以更精准控制输出效果:
const imgToMP4 = (caption, sound, image, duration, output) => { smartLog('info', `Converting ${image}`); FFmpeg() // 输入图片,设置循环播放及时长 .input(image) .inputOptions(`-loop 1`, `-t ${duration}`) // 输入音频,同步时长避免截断/淡出 .input(sound) .inputOptions(`-t ${duration}`) // 视频编码参数 .outputOptions('-c:v libx264', '-b:v 1024k', '-pix_fmt yuv420p', '-s 640x?') // 音频编码参数 .outputOptions('-c:a aac', '-b:a 128k', '-ac 2') // 指定输出格式 .format('mp4') .save(output) .on('start', (command) => { smartLog('info', `ffmpeg process started: ${command}`); }) .on('error', (err) => { smartLog('error', err); }) .on('end', () => { smartLog('info', `Video created: ${output}`); }); };
代码说明
-loop 1:让图片循环播放-t ${duration}:分别给图片和音频指定时长,确保两者完全同步- 直接配置编码参数,没有包装器的默认淡出等行为干扰,输出效果完全可控
内容的提问来源于stack exchange,提问作者Bragon
相关产品推荐
相关产品推荐

