音频样本格式 s16p、ffmpeg 或音频编解码器错误?

标签 audio video ffmpeg codec

我有一个视频文件,大约 3 年前我用 ffmpeg 将视频信息转储到一个 txt 文件中。

...
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s

但是我发现当我使用更新 ffprobe 时格式发生了变化(ffprobe 版本 N-78046-g46f67f4 版权所有 (c) 2007-2016 the FFmpeg developers)。

...
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s

对于相同的视频,其示例格式更改为 s16p。

我实现了一个使用 ffmpeg 的简单视频播放器。 3年前可以播放视频,但改更新ffmpeg后无法输出正确的pcm码流。我花了很多时间终于发现音频应该是 s16 而不是 s16p。在调用 avcodec_decode_audio4 之前添加行后解码的音频流工作,

audio_codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16

但这只是一个 hack。有人遇到这个问题吗?如何让ffmpeg正常工作?任何提示表示赞赏。谢谢!

最佳答案

输出格式changed .这样做的原因相当复杂和技术性,但无论如何让我试着解释一下。

大多数音频编解码器的结构使得每个 channel 的输出最好单独重建, channel 的合并(将“左”和“右”缓冲区交织成一个有序的样本数组 left0 right0 left1 right1 [等] ) 发生在最后。你大概可以想象,如果编码器要再次去交织,那么音频的转码就涉及到两个冗余操作(交织/去交织)。因此,所有有意义的解码器都切换为输出平面音频(因此 s16 更改为 s16p,其中 p 表示平面),其中每个 channel 都是其自己的缓冲区。

因此:现在,交织是在解码后使用重采样库 ( libswresample ) 完成的,而不是作为解码的一个组成部分,并且只有在用户明确想要这样做时,而不是自动/总是。

您确实可以将请求样本格式设置为 S16 以强制解码为 s16 而不是 s16p。将此视为一种兼容性 hack,在某些时候将针对它确实适用的少数解码器以及不适用于新解码器的解码器将其删除。相反,请考虑向您的应用程序添加 libswresample 支持,以在解码器的任何 native 输出格式与您要用于进一步数据处理(例如使用声卡播放)的格式之间进行转换。

关于音频样本格式 s16p、ffmpeg 或音频编解码器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35226255/

相关文章:

ios - 自定义和 "dynamic"通知声音的解决方法

javascript - 视频标签的 XMLHttpRequest?

python-3.x - 如何让 discord bot 队列本地 mp3?

FFMPEG 重新编码所有音频流,同时保留原始音频

image - 提取视频的所有帧而不进行任何色度二次采样

c++ - Windows 上 C++ 的声音处理 - 朝着正确方向轻推

java - Gervill for Oracle Java?

audio - Liquidsoap 未明确定义变量

ios - 在 iOS 中使用 Socket 上传和流式传输视频

javascript - 视频流启动时触发的事件,使用 getUserMedia