PyAv av.open指定使用的编解码器

问题描述

使用PyAv打开alsa音频设备时。我该如何指定使用的编解码器,而不是ffmpeg的认编解码器,因为那是错误的。认情况下,它将使用pcm_s16le,而我需要使用pcm_s32le。我可以使用以下ffmpeg命令在设备上进行记录:

ffmpeg -f alsa -acodec pcm_s32le -i dmic_sv alsaout.wav

但不

ffmpeg -f alsa -i dmic_sv alsaout.wav

哪个会给我以下错误

[alsa @ 0x12061c0] cannot set sample format 0x10000 2 (Invalid argument)
dmic_sv: Input/output error

如何将工作命令传输到PyAv av.open()函数?有stream_options,但似乎不起作用。我尝试过

stream_options = [{'-acodec': 'pcm_s32le'}]
av.open('dmic_sv',format='alsa',mode='r',stream_options=stream_options)

我和上面的一样。

av.error.OSError: [Errno 5] Input/output error: 'dmic_sv'; last error log: [alsa] cannot set sample format 0x10000 2 (Invalid argument)

该怎么做?

解决方法

我会回答我自己的问题,因为我知道了。我阅读了ffmpeg的源代码,发现当未使用alsa音频设备和编解码器时,ffmpeg将默认使用带符号的16位pcm样本。代码here。通过进一步探索源代码,编解码器值来自AVFormatContext::audio_codec_id结构字段。

现在确定使用Cython来使用FFmpeg的PyAV,并通过阅读Container类的PyAV源代码,我注意到它在AVFormatContext变量中包含self.ptr。然后阅读InputContainer源代码,尤其是在调用avformat_open_input函数以打开alsa设备之前。 PyAV不支持指定使用的音频编解码器。

我分叉了图书馆,并迅速结束了对我的solution的攻击。现在的问题是,是否可以将此功能添加到PyAV以强制使用音频编解码器?在这种情况下,当设备使用pcm样本并依靠ffmpeg来选择默认样本时,它将始终使用16位样本,而在我的情况下,我需要使用32位样本。

希望这可以帮助某人并为他们省去我遇到的麻烦:)我也针对PyAV问题here发布了相同的答案。