FFmpeg-channel rematrix

channel rematrix

Channel rematrix 是一种音频处理技术,用于将多声道音频转换为不同的多声道格式。它可以将一个多声道音频信号从一种布局转换为另一种布局,例如从 5.1 到 7.1 或从立体声到环绕声。

ffmpeg中的rematrix可以通过fixter完成,swresample也支持auto-rematrix。

bash 复制代码
ffmpeg -y -v 56 -i 1ch-16k.wav -filter_complex "\
[0:a]pan=mono|c0=c0[a0]; \
[0:a]pan=mono|c0=c0[a1]; \
[0:a]pan=mono|c0=c0[a2]; \
[0:a]pan=mono|c0=c0[a3]; \
[0:a]pan=mono|c0=c0[a4]; \
[0:a]pan=mono|c0=c0[a5]; \
[0:a]pan=mono|c0=c0[a6]; \
[0:a]pan=mono|c0=c0[a7]; \
[0:a]pan=mono|c0=c0[a8]; \
[0:a]pan=mono|c0=c0[a9]; \
[0:a]pan=mono|c0=c0[a10]; \
[0:a]pan=mono|c0=c0[a11]; \
[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9][a10][a11]amerge=inputs=12[aout]" \
-map "[aout]" 12ch-16k.wav

这个命令将一个1声道、16kHz采样率的wav文件转换为12声道音频文件,并且每个声道的内容都相同。下面是对命令的详细解释:

  • -y:覆盖输出文件,不询问。
  • -v 56:设置日志级别为verbose,输出更多详细信息。
  • -i 1ch-16k.wav:指定输入文件路径。
  • -filter_complex "...":使用复合滤镜进行处理。复合滤镜可以包含多个滤镜及其连接关系。
  • [0:a]pan=mono|c0=c0[a0]:使用pan滤镜将输入音频流(第0条流)从单声道变成12个单独的声道之一(第0号声道),并将输出流命名为a0
  • [0:a]pan=mono|c0=c0[a1]:同上,将输入流从单声道变成12个单独的声道之一(第1号声道),并将输出流命名为a1
  • ...:依次类推,直到为所有12个声道都创建了一个新的输出流。
  • [a0][a1][a2]...[a11]amerge=inputs=12[aout]:使用amerge滤镜将12个单独的声道混合成一个12声道的音频流,并将输出流命名为aout。其中inputs=12表示输入流的数量为12。
  • -map "[aout]":指定复合滤镜的输出流作为输出文件的音频流。
  • 12ch-16k.wav:指定输出文件路径。

最终,这个命令会将单声道音频文件转换为12声道音频文件,每个声道的内容都相同。由于使用了pan滤镜,所以输出文件中的每一个声道都来自于原始音频文件的左声道。如果需要使用右声道,可以将c0=c0修改为c0=c1

因为ffmpeg不支持12 channel播放,所以这个播放的时候会报错,需要指定layout才行,比如12channel,实际只播放8channel,这个就先不尝试了。

因此,发现ffmpeg中定义了下面的channel layout,如果不是这里面的就需要指定channel layout:

c 复制代码
#define AV_CHANNEL_LAYOUT_MONO              AV_CHANNEL_LAYOUT_MASK(1,  AV_CH_LAYOUT_MONO)
#define AV_CHANNEL_LAYOUT_STEREO            AV_CHANNEL_LAYOUT_MASK(2,  AV_CH_LAYOUT_STEREO)
#define AV_CHANNEL_LAYOUT_2POINT1           AV_CHANNEL_LAYOUT_MASK(3,  AV_CH_LAYOUT_2POINT1)
#define AV_CHANNEL_LAYOUT_2_1               AV_CHANNEL_LAYOUT_MASK(3,  AV_CH_LAYOUT_2_1)
#define AV_CHANNEL_LAYOUT_SURROUND          AV_CHANNEL_LAYOUT_MASK(3,  AV_CH_LAYOUT_SURROUND)
#define AV_CHANNEL_LAYOUT_3POINT1           AV_CHANNEL_LAYOUT_MASK(4,  AV_CH_LAYOUT_3POINT1)
#define AV_CHANNEL_LAYOUT_4POINT0           AV_CHANNEL_LAYOUT_MASK(4,  AV_CH_LAYOUT_4POINT0)
#define AV_CHANNEL_LAYOUT_4POINT1           AV_CHANNEL_LAYOUT_MASK(5,  AV_CH_LAYOUT_4POINT1)
#define AV_CHANNEL_LAYOUT_2_2               AV_CHANNEL_LAYOUT_MASK(4,  AV_CH_LAYOUT_2_2)
#define AV_CHANNEL_LAYOUT_QUAD              AV_CHANNEL_LAYOUT_MASK(4,  AV_CH_LAYOUT_QUAD)
#define AV_CHANNEL_LAYOUT_5POINT0           AV_CHANNEL_LAYOUT_MASK(5,  AV_CH_LAYOUT_5POINT0)
#define AV_CHANNEL_LAYOUT_5POINT1           AV_CHANNEL_LAYOUT_MASK(6,  AV_CH_LAYOUT_5POINT1)
#define AV_CHANNEL_LAYOUT_5POINT0_BACK      AV_CHANNEL_LAYOUT_MASK(5,  AV_CH_LAYOUT_5POINT0_BACK)
#define AV_CHANNEL_LAYOUT_5POINT1_BACK      AV_CHANNEL_LAYOUT_MASK(6,  AV_CH_LAYOUT_5POINT1_BACK)
#define AV_CHANNEL_LAYOUT_6POINT0           AV_CHANNEL_LAYOUT_MASK(6,  AV_CH_LAYOUT_6POINT0)
#define AV_CHANNEL_LAYOUT_6POINT0_FRONT     AV_CHANNEL_LAYOUT_MASK(6,  AV_CH_LAYOUT_6POINT0_FRONT)
#define AV_CHANNEL_LAYOUT_HEXAGONAL         AV_CHANNEL_LAYOUT_MASK(6,  AV_CH_LAYOUT_HEXAGONAL)
#define AV_CHANNEL_LAYOUT_6POINT1           AV_CHANNEL_LAYOUT_MASK(7,  AV_CH_LAYOUT_6POINT1)
#define AV_CHANNEL_LAYOUT_6POINT1_BACK      AV_CHANNEL_LAYOUT_MASK(7,  AV_CH_LAYOUT_6POINT1_BACK)
#define AV_CHANNEL_LAYOUT_6POINT1_FRONT     AV_CHANNEL_LAYOUT_MASK(7,  AV_CH_LAYOUT_6POINT1_FRONT)
#define AV_CHANNEL_LAYOUT_7POINT0           AV_CHANNEL_LAYOUT_MASK(7,  AV_CH_LAYOUT_7POINT0)
#define AV_CHANNEL_LAYOUT_7POINT0_FRONT     AV_CHANNEL_LAYOUT_MASK(7,  AV_CH_LAYOUT_7POINT0_FRONT)
#define AV_CHANNEL_LAYOUT_7POINT1           AV_CHANNEL_LAYOUT_MASK(8,  AV_CH_LAYOUT_7POINT1)
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE      AV_CHANNEL_LAYOUT_MASK(8,  AV_CH_LAYOUT_7POINT1_WIDE)
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK AV_CHANNEL_LAYOUT_MASK(8,  AV_CH_LAYOUT_7POINT1_WIDE_BACK)
#define AV_CHANNEL_LAYOUT_OCTAGONAL         AV_CHANNEL_LAYOUT_MASK(8,  AV_CH_LAYOUT_OCTAGONAL)
#define AV_CHANNEL_LAYOUT_HEXADECAGONAL     AV_CHANNEL_LAYOUT_MASK(16, AV_CH_LAYOUT_HEXADECAGONAL)
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX    AV_CHANNEL_LAYOUT_MASK(2,  AV_CH_LAYOUT_STEREO_DOWNMIX)
#define AV_CHANNEL_LAYOUT_22POINT2          AV_CHANNEL_LAYOUT_MASK(24, AV_CH_LAYOUT_22POINT2)

这里面有16channel,那么用这个复杂的graph可以生成16 channel的wav文件,播放也正常:

bash 复制代码
ffmpeg -y -v 56 -i 1ch-16k.wav -filter_complex "\
[0:a]pan=mono|c0=c0[a0]; \
[0:a]pan=mono|c0=c0[a1]; \
[0:a]pan=mono|c0=c0[a2]; \
[0:a]pan=mono|c0=c0[a3]; \
[0:a]pan=mono|c0=c0[a4]; \
[0:a]pan=mono|c0=c0[a5]; \
[0:a]pan=mono|c0=c0[a6]; \
[0:a]pan=mono|c0=c0[a7]; \
[0:a]pan=mono|c0=c0[a8]; \
[0:a]pan=mono|c0=c0[a9]; \
[0:a]pan=mono|c0=c0[a10]; \
[0:a]pan=mono|c0=c0[a11]; \
[0:a]pan=mono|c0=c0[a12]; \
[0:a]pan=mono|c0=c0[a13]; \
[0:a]pan=mono|c0=c0[a14]; \
[0:a]pan=mono|c0=c0[a15]; \
[a0][a1][a2][a3][a4][a5][a6][a7][a8][a9][a10][a11][a12][a13][a14][a15]amerge=inputs=16[aout]" \
-map "[aout]" 16ch-16k.wav

这个实际上用最简单的-ac参数也可以:

bash 复制代码
ffmpeg -y -v 56 -i 1ch-16k.wav -ac 16 out.wav

pan filter的用法

混合具有特定增益水平的通道。filter接受输出通道布局,后跟一组通道定义。

此filter还旨在有效地重新remap音频流的channels。

混合示例,从立体声缩混到单声道,但左声道的系数更大:

bash 复制代码
pan=1c|c0=0.9*c0+0.1*c1

自定义缩混至立体声,自动适用于 3、4、5 和 7 声道环绕声:

bash 复制代码
pan=stereo| FL < FL + 0.5*FC + 0.6*BL + 0.6*SL | FR < FR + 0.5*FC + 0.6*BR + 0.6*SR

给定相同的来源,您还可以切换左前和右前声道并保持输入声道布局:

bash 复制代码
pan="5.1| c0=c1 | c1=c0 | c2=c2 | c3=c3 | c4=c4 | c5=c5"

如果输入是立体声音频流,您可以将左前声道静音(并仍然保持立体声声道布局):

bash 复制代码
pan="stereo|c1=c1"

仍然使用立体声音频流输入,您可以在左前和右前复制右声道:

bash 复制代码
pan="stereo| c0=FR | c1=FR"

学习完pan的用法之后,前面的这个1声道转16声道,命令可以简化为:

bash 复制代码
ffmpeg -y -v 56 -i 1ch-16k.wav -af "\
pan=hexadecagonal | c0=c0 | c1=c0 | c2=c0 | c3=c0 | c4=c0 \
                  | c5=c0 | c6=c0 | c7=c0 | c8=c0 | c9=c0 \
                  | c10=c0 | c11=c0 | c12=c0 | c13=c0 | c14=c0 | c15=c0" \
12ch-16k.wav

其中hexadecagonal来自ffmpeg中layout的定义,通过-layouts可以看到:

bash 复制代码
Standard channel layouts:
NAME           DECOMPOSITION
mono           FC
stereo         FL+FR
2.1            FL+FR+LFE
3.0            FL+FR+FC
3.0(back)      FL+FR+BC
4.0            FL+FR+FC+BC
quad           FL+FR+BL+BR
quad(side)     FL+FR+SL+SR
3.1            FL+FR+FC+LFE
5.0            FL+FR+FC+BL+BR
5.0(side)      FL+FR+FC+SL+SR
4.1            FL+FR+FC+LFE+BC
5.1            FL+FR+FC+LFE+BL+BR
5.1(side)      FL+FR+FC+LFE+SL+SR
6.0            FL+FR+FC+BC+SL+SR
6.0(front)     FL+FR+FLC+FRC+SL+SR
hexagonal      FL+FR+FC+BL+BR+BC
6.1            FL+FR+FC+LFE+BC+SL+SR
6.1(back)      FL+FR+FC+LFE+BL+BR+BC
6.1(front)     FL+FR+LFE+FLC+FRC+SL+SR
7.0            FL+FR+FC+BL+BR+SL+SR
7.0(front)     FL+FR+FC+FLC+FRC+SL+SR
7.1            FL+FR+FC+LFE+BL+BR+SL+SR
7.1(wide)      FL+FR+FC+LFE+BL+BR+FLC+FRC
7.1(wide-side) FL+FR+FC+LFE+FLC+FRC+SL+SR
octagonal      FL+FR+FC+BL+BR+BC+SL+SR
hexadecagonal  FL+FR+FC+BL+BR+BC+SL+SR+TFL+TFC+TFR+TBL+TBC+TBR+WL+WR
downmix        DL+DR
22.2           FL+FR+FC+LFE+BL+BR+FLC+FRC+BC+SL+SR+TC+TFL+TFC+TFR+TBL+TBC+TBR+LFE2+TSL+TSR+BFC+BFL+BFR

参考

AudioChannelManipulation

Convert Multiple audio tracks into a Single Track with 12 channels using ffmpeg

相关推荐
hunandede2 小时前
FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析
c++·ffmpeg·音视频
MonkeyKing_sunyuhua1 天前
FFmpeg将mp4的文件转化为m4a
ffmpeg
zanglengyu1 天前
RK3568硬解码并与Qt界面融合显示深入探究
开发语言·qt·ffmpeg·rk3568硬解码rtsp
橘子味的茶二2 天前
ffmpeg内存模型
ffmpeg
TPCloud2 天前
windows 11编译安装ffmpeg(包含ffplay)
windows·ffmpeg·源码安装·mysys
runing_an_min3 天前
ffmpeg视频滤镜:缓入缓出-fade
ffmpeg·音视频·fade·缓出·缓入
ssslar3 天前
FFMPEG录屏(22)--- Linux 下基于X11枚举所有显示屏,并获取大小和截图等信息
linux·运维·ffmpeg
MonkeyKing_sunyuhua3 天前
FFmpeg 怎么裁剪m4a的音频,从一个时间点开始,裁剪15秒钟的视频
ffmpeg·音视频
DO_Community3 天前
教程:FFmpeg结合GPU实现720p至4K视频转换
ffmpeg·音视频
x66ccff3 天前
使用NVIDIA GPU加速FFmpeg视频压制:完全指南
ffmpeg·音视频