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

相关推荐
OH_TPC14 小时前
【鸿蒙优选三方库】@ohos/ffmpeg-kit:把 FFmpeg 的全部能量带进鸿蒙
华为·ffmpeg·harmonyos·鸿蒙
是jin奥14 小时前
最新 FFmpeg 安装脚本:Linux x86_64
linux·运维·ffmpeg
骑着蜗牛撵大象32715 小时前
用 Codex 批量做数字人商品口播视频:从分镜 JSON 到成片校验的流水线
java·ffmpeg·json·音视频·数字人·视频·codex
企业数字化笔记17 小时前
视频加放大特写后音画不同步怎么办?OpenCV转场与FFmpeg音轨续接实战
opencv·ffmpeg·音视频
开开心心就好3 天前
课堂随机点名工具,绿色版免安装双击即用
java·服务器·前端·ffmpeg·音视频·perl·symfony
小鹿软件办公3 天前
不依赖 FFmpeg 也能录屏?ShareX 22 新增录屏等十余款新工具
ffmpeg·sharex·免费录屏工具
lll23526917793 天前
Android APP短视频音频提取,主流工具怎么选
ffmpeg·音视频
成都旺小宝科技3 天前
首访决策人没来,AI一客一策两天成交!
大数据·人工智能·机器学习·ffmpeg·语音识别
余槐i4 天前
加了Cookie yt-dlp仍报HTTP 403:3个容易漏的请求头差异
python·http·ffmpeg·开发工具·yt-dlp
余槐i4 天前
yt-dlp 线程开到 16 反而更慢:1000 个视频的实测与限速原因
性能优化·ffmpeg·自动化·开发工具·yt-dlp