借助 FFmpeg 的 filter_complex 滤镜混合音频流的实例。

2025-07-03 05:15:36 12 分享链接 开发笔记 ffmpeg

ffmpeg -i input.mp4 -i test.mp3 -i bgm.mp3 -filter_complex "[1:a]volume=1.2[a1];[2:a]volume=0.3[a2];[a1][a2]amix=inputs=2:duration=longest[aout]" -map 0:v -map "[aout]" -vf "scale=1080:1920,subtitles=test.srt:original_size=1080x1920:force_style='FontSize=12,Alignment=2,MarginV=200',drawtext=text='测试标题':fontfile=C\\:/Windows/Fonts/msyh.ttc:fontsize=48:fontcolor=yellow:x=570:y=200" -c:v h264_nvenc -c:a aac -y output.mp4

在 FFmpeg 中,-map 选项用于指定输出文件中包含哪些输入流(音频、视频、字幕等)。你提供的命令中的 -map 0:v -map "[aout]" 表示:

1. -map 0:v

  • 0:表示第一个输入文件(即 -i input.mp4)。
  • v:表示视频流v 是 video 的缩写)。

作用:将第一个输入文件(input.mp4)的视频流复制到输出文件中。

2. -map "[aout]"

  • "[aout]":引用滤镜图中命名的输出流[aout])。

作用:将 filter_complex 滤镜链中最终混合的音频流 [aout] 作为输出文件的音频。

完整命令流程解释

ffmpeg -i input.mp4 -i test.mp3 -i bgm.mp3 \
-filter_complex "[1:a]volume=1.2[a1];[2:a]volume=0.3[a2];[a1][a2]amix=inputs=2:duration=longest[aout]" \
-map 0:v -map "[aout]" \
-vf "scale=1080:1920,..." \
-c:v h264_nvenc -c:a aac -y output.mp4
  1. 输入文件

    • input.mp4(索引 0):视频 + 原始音频(但原始音频未被 -map 选中,因此被丢弃)。
    • test.mp3(索引 1):主音频。
    • bgm.mp3(索引 2):背景音乐。
  2. 滤镜处理

    • [1:a]volume=1.2[a1]:将 test.mp3 的音量放大 1.2 倍。
    • [2:a]volume=0.3[a2]:将 bgm.mp3 的音量缩小至 0.3 倍。
    • amix=inputs=2:duration=longest:混合两个音频,时长以较长的为准。
  3. 映射规则

    • -map 0:v:取 input.mp4 的视频。
    • -map "[aout]":取混合后的音频(test.mp3bgm.mp3 的混合)。
  4. 输出结果

    • 视频:来自 input.mp4,经过缩放和字幕处理。
    • 音频:来自 test.mp3bgm.mp3 的混合,原视频的音频被丢弃。

常见问题

  1. 为什么不直接用 -map 0:a 保留原视频的音频?

    • 因为命令的意图是替换原视频的音频(用 test.mp3bgm.mp3 的混合音轨)。若同时添加 -map 0:a,会导致输出包含多条音频流(原视频音频 + 混合音频),需配合 -disposition 选项指定默认音轨。
  2. 如果想保留原视频的音频,同时添加 BGM 怎么办?

    • 修改滤镜链,将 [0:a](原视频音频)也加入混合:

      [0:a]volume=1.0[a0];[1:a]volume=1.2[a1];[2:a]volume=0.3[a2];[a0][a1][a2]amix=inputs=3:duration=longest[aout]
    • 并确保 -map 0:v 改为 -map 0:v -map 0:a(同时保留原视频的视频流和音频流)。
  3. -map 顺序重要吗?

    • 是的!FFmpeg 按 -map 的顺序分配输出流。例如:

      -map "[aout]" -map 0:v  # 先音频后视频

      会导致输出文件的流顺序为:音频流(索引 0)、视频流(索引 1)。

总结

-map 是 FFmpeg 中控制输入输出流映射的核心选项,通过灵活组合可以实现:

  • 提取特定流(如仅视频或仅音频)。
  • 合并多个输入的流(如视频 + 多音频)。
  • 应用滤镜处理后再输出(如示例中的音频混合)。

python拼装命令实例

ffmpeg -f concat -safe 0 -i videos_to_concat.txt -i D:/Pythons/srtEditor/test.mp3 -i D:/Pythons/srtEditor/bgm.mp3 -filter_complex [1:a]volume=0.4[a1];[2:a]volume=0.3,atrim=end=30.744,asetpts=PTS-STARTPTS[a2];[a1][a2]amix=inputs=2:duration=first[aout] -map 0:v -map [aout] -c:v h264_nvenc -preset medium -cq 23 -b:v 8M -r 30 -s 1080x1920 -gpu 0 -vf scale=1080x1920,subtitles=D\\:/Pythons/srtEditor/test.srt:original_size=1080x1920:force_style='FontSize=14,PrimaryColour=&HFFFFFF&,BackColour=&Hblack&,Shadow=1,1,Box=1,BoxColor=&H00000080&,Alignment=2',drawtext=text='测试标题':fontfile=C\\:/Windows/Fonts/SimHei.ttf:fontsize=48:fontcolor=yellow:x=570:y=200:borderw=1:bordercolor=black -c:v h264_nvenc -c:a aac -b:a 128k -t 30.744 -shortest -y D:/Pythons/srtEditor/final_output.mp4

借助 FFmpeg 的 filter_complex 滤镜混合音频流的实例。