You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用FFmpeg复制/裁剪音频并实现音视频时长匹配合并?

解决视频与音频合并时的音频循环/裁剪需求

问题核心

需将带原生音频的视频与外部音频合并,遵循以下规则:

  • 视频时长 > 音频时长:将外部音频循环播放至与视频时长匹配
  • 音频时长 > 视频时长:将外部音频裁剪至与视频时长一致

当前代码无法实现音频循环延长,原因是误用了apad滤镜(仅补全静音填充时长),而非真正的音频循环播放逻辑。

解决方案

修改FFmpeg命令,使用aloop滤镜实现音频无限循环,配合amix滤镜的时长控制逻辑,精准匹配视频时长:

修改后的Node.js代码

export async function overlayAudio(id: number, music: Music) {
  console.log('start')
  const videoPath = path.join(__dirname, `../../../uploads/movie/${id}/result/movie/predfinal.mp4`);
  
  if (music === null) {
    return videoPath.match(/\\uploads(.*)/)[0];
  } else {
    const audioPath = path.join(__dirname, `../../../${music.audio}`);
    const outputVideoPath = path.join(__dirname, `../../../uploads/movie/${id}/result/movie/output.mp4`);
    const matchPath = outputVideoPath.match(/\\uploads(.*)/);
    // 替换循环逻辑:用aloop实现音频循环,amix以视频时长为基准
    const cmd = `ffmpeg -i ${videoPath} -i ${audioPath} -filter_complex "[0:a]volume=1[a];[1:a]volume=0.2,aloop=loop=-1:size=2147483647[b];[a][b]amix=inputs=2:duration=first:dropout_transition=0" -c:v copy -c:a aac -shortest ${outputVideoPath}`;

    try {
      await execPromise(cmd);
      console.log('end!')
      return matchPath[0];
    } catch (error) {
      console.error('Error:', error);
      throw error;
    }
  }
}

关键参数说明

  • aloop=loop=-1:size=2147483647:loop=-1设置音频无限循环,size设为FFmpeg支持的最大整数,确保循环时长足够覆盖任意长度的视频
  • amix=inputs=2:duration=first:dropout_transition=0:duration=first指定混合后音频时长以视频原生音频的时长为准,自动实现循环延长或裁剪;dropout_transition=0消除音频循环衔接时的过渡杂音
  • -shortest:强制输出视频时长与视频流一致,避免滤镜逻辑导致的时长偏差

内容的提问来源于stack exchange,提问作者Руслан Лысенко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:43:15