使用 ffmpeg 将多个音轨转换为具有 12 个通道的单个音轨

使用 ffmpeg 将多个音轨转换为具有 12 个通道的单个音轨

我有多个 MOV 文件,每个文件的音轨数量不同。我想将这些文件转换为 MOV,并将音频合并为单个 12 声道音轨。

例如,我有一个包含 4 个单声道音轨的源文件,该文件必须输出为一个包含单个 12 声道音轨的文件。源文件中的第 1 个音轨必须输出到第 1 个声道;第 2 个音轨输出到第 2 个声道;第 3 个音轨输出到第 3 个声道;第 4 个音轨输出到第 4 个声道;输出文件中的第 5-12 个声道将没有音频。

另一个例子:如果源文件有 6 个单通道音轨,那么这 6 个音轨将被映射到输出文件中的 1-6 通道,而 7-12 通道将没有音频。

下面是我的 FFmpeg 命令。它顺利完成了视频转码,并输出了单个 12 声道音轨。问题是源文件中的所有音轨都合并在第一个声道中,而 2-12 声道没有音频。我正在使用 Switch Telestream Player 对文件进行 QC。

ffmpeg -i <input>.mp4 -c:v prores_ks -profile:v 0 -quant_mat 2 -c:a pcm_s16le -b:a 512K -filter_complex "[0:a]pan=mono|c0=c0[a0];[0:a]pan=mono|c0=c1[a1];[0:a]pan=mono|c0=c2[a2];[0:a]pan=mono|c0=c3[a3];[0:a]pan=mono|c0=c4[a4];[0:a]pan=mono|c0=c5[a5];[0:a]pan=mono|c0=c6[a6];[0:a]pan=mono|c0=c7[a7];[0:a]pan=mono|c0=c8[a8];[0:a]pan=mono|c0=c9[a9];[0:a]pan=mono|c0=c10[a10];[0:a]pan=mono|c0=c11[a11];[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9][a10][a11]amerge=inputs=12[aout]" -map 0:v -map "[aout]" <out>.mov

我在用着FFAStrans及其包含的ffmpeg可执行文件可自动移动和转码已放置在其监视文件夹中的每个文件。您能帮助我构建正确的ffmpeg命令吗?

答案1

在下面的公式中,我仅包含了与将单声道音轨映射到 12 通道音轨相关的代码。

ffmpeg -i test_file.mov -filter_complex "[0:a:0]pan=mono|c0=c0[a0];[0:a:1]pan=mono|c0=c0[a1];[0:a:2]pan=mono|c0=c0[a2];[0:a:3]pan=mono|c0=c0[a3];[0:a:0]pan=mono|c0=c1[a4];[0:a:0]pan=mono|c0=c1[a5];[0:a:0]pan=mono|c0=c1[a6];[0:a:0]pan=mono|c0=c1[a7];[0:a:0]pan=mono|c0=c1[a8];[0:a:0]pan=mono|c0=c1[a9];[0:a:0]pan=mono|c0=c1[a10];[0:a:0]pan=mono|c0=c1[a11];[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9][a10][a11]amerge=inputs=12[aout]" -map 0:v -map "[aout]" -c:a pcm_s24le -c:v copy output_file.mov

在您的原始代码中, 仅[a0]包含混合后的声音。您并没有像您想象的那样将四个单声道音轨/通道混合/组合到c012 声道音轨中。 [a1]-[a11]是从不存在的单声道(除 之外的任何音轨c0)混合而来,这就是为什么它们映射到的通道是静音的。最初很难发现这一点,因为您的测试文件包含 4 个相同的单声道音轨,因此无法通过耳朵区分单声道音轨是混合在一起还是只是丢失了。

下表显示了您的代码存在的问题,这些表格比较了原始代码和新代码。请注意,[0:a]对于音轨 0 使用 被解释为FFmpeg等同于[0:a:0]

原始代码

命令 输入
轨迹
输入
通道
输入音频注释                   映射
声音?
[0:a] 平移=单声道|c0=c0[a0] [0:对:0] c0 单声道轨道 0 - c0 有音频 c0:是
[0:a] 平移=单声道|c0=c1[a1] [0:对:0] c1 单声道轨道 0 - c1 无效 c1:
[0:a] 平移=单声道|c0=c2[a2] [0:对:0] c2 单声道轨道 0 - c2 无效 c2:
[0:a] 平移=单声道|c0=c3[a3] [0:对:0] c3 单声道轨道 0 - c3 无效 c3:
[0:a] 平移=单声道|c0=c4[a4] [0:对:0] c4 单声道轨道 0 - c4 无效 c4:
[0:a] 平移=单声道|c0=c5[a5] [0:对:0] c5 单声道轨道 0 - c5 无效 c5:
[0:a] 平移=单声道|c0=c6[a6] [0:对:0] c6 单声道轨道 0 - c6 无效 c6:
[0:a] 平移=单声道|c0=c7[a7] [0:对:0] c7 单声道轨道 0 - c7 无效 c7:
[0:a] 平移=单声道|c0=c8[a8] [0:对:0] c8 单声道轨道 0 - c8 无效 c8:
[0:a] 平移=单声道|c0=c9[a9] [0:对:0] c9 单声道轨道 0 - c9 无效 c9:
[0:a] 平移=单声道|c0=c10[a10] [0:对:0] c10 单声道轨道 0 - c10 无效 c10:
[0:a] 平移=单声道|c0=c11[a11] [0:对:0] c11 单声道轨道 0 - c11 无效 c11:

新代码

命令 输入
轨迹
输入
通道
输入音频注释                 映射
声音?
[0:a:0]平移=单声道|c0=c0[a0] [0:对:0] c0 单声道轨道 0 - c0 有音频 c0:是
[0:a:1]全色=单声道|c0=c0[a1] [0:对:1] c0 单声道轨道 1 - c0 有音频 c1:是的
[0:a:2]平移=单声道|c0=c0[a2] [0:对:2] c0 单声道轨道 2 - c0 有音频 c2:是的
[0:a:3]平移=单声道|c0=c0[a3] [0:对:3] c0 单声道轨道 3 - c0 有音频 c3:是的
[0:a:0]平移=单声道|c0=c1[a4] [0:对:0] c1 单声道轨道 0 - c1 无效 c4:
[0:a:0]平移=单声道|c0=c1[a5] [0:对:0] c1 单声道轨道 0 - c1 无效 c5:
[0:a:0]平移=单声道|c0=c1[a6] [0:对:0] c1 单声道轨道 0 - c1 无效 c6:
[0:a:0]平移=单声道|c0=c1[a7] [0:对:0] c1 单声道轨道 0 - c1 无效 c7:
[0:a:0] 平移=单声道|c0=c1[a8] [0:对:0] c1 单声道轨道 0 - c1 无效 c8:
[0:a:0]平移=单声道|c0=c1[a9] [0:对:0] c1 单声道轨道 0 - c1 无效 c9:
[0:a:0]平移=单声道|c0=c1[a10] [0:对:0] c1 单声道轨道 0 - c1 无效 c10:
[0:a:0] 平移=单声道|c0=c1[a11] [0:对:0] c1 单声道轨道 0 - c1 无效 c11:

答案2

我做了一些 bash 脚本,但我不知道它如何帮助你

#!/bin/bash
f="input 4.mp4"
if [ ! -f "$f" ]; then
ffmpeg -lavfi "
testsrc[v];
aevalsrc=sin(440*2*PI*t):s=8000[a];
aevalsrc=sin(880*2*PI*t)|sin(1760*2*PI*t):s=16000[b];
" -map "[v]" -map "[a]" -map "[b]" -t 5 "$f" -hide_banner -y
fi

AUD=($(ffprobe -v 0 -select_streams a -show_entries stream=channels -of csv=p=0 "$f"))
MRG=""
CNT=0
INP=0
for a in ${AUD[@]}; do
  echo "channels=$a"
  MRG+="[0:a:${CNT}]"
  ((CNT+=$a))
  ((INP++))
done
SIL=""
while (( $CNT < 12 )); do
  SIL+="aevalsrc=0[a${CNT}];"
  MRG+="[a${CNT}]"
  ((CNT++))
  ((INP++))
done

ffmpeg -i "$f" -filter_complex "
${SIL}
${MRG}amerge=inputs=${INP}[a]
" -map 0:v -map "[a]" -c:v copy -c:a pcm_s16le /tmp/out.mov -hide_banner -y

ffplay -f lavfi "amovie='/tmp/out.mov',asplit[a][out0];[a]showspectrum=s=540x1080:mode=separate:legend=1[out1]" -hide_banner -autoexit

相关内容