我正在捕获 Opus 的实时音频流,无论我为音频采样率选择什么,我都会得到 48khz 的输出。
这是我的命令行
./ffmpeg -f alsa -ar 16000 -i sysdefault:CARD=CODEC -f alsa -ar 16000 -i sysdefault:CARD=CODEC_1 -filter_complex join=inputs=2:channel_layout=stereo:map=0.1-FR\|1.0-FL,asetpts=expr=N/SR/TB -ar 16000 -ab 64k -c:a opus -vbr off -compression_level 5 output.ogg
这就是 ffmpeg 的回应:
Output #0, ogg, to 'output.ogg': Metadata: encoder : Lavf57.48.100 Stream #0:0: Audio: opus (libopus), 16000 Hz, stereo, s16, delay 104, padding 0, 64 kb/s (default) Metadata: encoder : Lavc57.54.100 libopus
但是,似乎 ffmpeg 撒了谎,因为再次分析文件时,我得到:
Input #0, ogg, from 'output.ogg': Duration: 00:00:03.21, start: 0.000000, bitrate: 89 kb/s Stream #0:0: Audio: opus, 48000 Hz, stereo, s16, delay 156, padding 0 Metadata: ENCODER : Lavc57.54.100 libopus
我尝试了很多采样率的排列,简化为单个音频输入等 - 总是得到相同的结果。
有任何想法吗?
最佳答案
这个问题应该在 super 用户上提问和回答,因为它是关于使用软件而不是编程。但是,既然我知道答案,我还是会发布一个。
FFmpeg 将以指定的采样率对 Opus 进行编码。您可以在 libopusenc.c 的源代码(here 和 here)中验证这一点。
但是 FFmpeg 将以 48 kHz 解码 Opus,即使它是以较低的采样率编码的。您可以在 libopusdec.c(here 和 here)中验证这一点。
这实际上是 Ogg Opus 规范 (IETF RFC 7845) 推荐的。第 5.1 节第 5 项说:
An Ogg Opus player SHOULD select the playback sample rate according to the following procedure:
- If the hardware supports 48 kHz playback, decode at 48 kHz.
- Otherwise, if the hardware's highest available sample rate is a supported rate, decode at this sample rate.
- Otherwise, if the hardware's highest available sample rate is less than 48 kHz, decode at the next higher Opus supported rate above the highest available hardware rate and resample.
- Otherwise, decode at 48 kHz and resample.
由于 FFmpeg 和大多数硬件都支持 48 kHz 播放,因此 48 kHz 用于解码 FFmpeg 中的 Opus。原始采样率存储在 Ogg 容器的 OpusHead 数据包中,因此您可以根据需要使用解析器或其他播放器检索它,但 FFmpeg 忽略它并仅以 48 kHz 解码。
关于ffmpeg 不尊重作品输出中的采样率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39186282/