为何使用ffmpegio两种方法获取的音频样本数不一致?
MP3样本数计算差异:ffmpegio读取 vs probe结果
你遇到的差异是MP3编码特性和ffmpegio底层处理逻辑共同导致的,核心原因如下:
- MP3的编码填充/延迟:MP3编码时为了满足帧对齐要求,会在音频首尾添加固定数量的静默填充样本,这些样本在解码播放时会被自动丢弃,但文件头记录的
nb_samples(即probe返回的数值)会包含这些填充样本。 - ffmpegio读取的自动过滤:
ffmpegio.open的ra模式底层调用FFmpeg的解码逻辑,会自动剔除这些无效的填充/延迟样本,返回实际有效的音频样本,所以计算出的总数会比probe结果少固定值,且这个差值不随文件长度变化——因为填充样本数是固定的,和音频时长无关。
验证方法
用FFmpeg命令行提取实际解码后的PCM样本数,对比两种结果:
# 假设是单声道,提取PCM后计算样本数 ffmpeg -i a.mp3 -f s16le -ac 1 - | wc -c # 样本数 = 输出字节数 / 2(s16le格式为2字节/样本)
如果这个结果和你用ffmpegio读取计算的290704一致,就坐实了是probe的nb_samples包含了解码时丢弃的填充样本。
解决办法
- 若需要实际可播放的有效样本数,直接用ffmpegio读取的结果即可,这是解码后的真实音频数据。
- 若一定要获取和probe一致的样本数,可以通过FFmpeg参数强制读取所有样本(包括填充部分),在ffmpegio.open时传入
options参数:
with ffmpegio.open(file, 'ra', blocksize=16, sample_fmt='dbl', options={'ignore_loop': '0', 'read_intervals': '%+#'}) as file_opened: total_samples = 0 for indata in file_opened: total_samples += indata.shape[0] print(total_samples)
内容的提问来源于stack exchange,提问作者Julien Larget-Piet
相关产品推荐
相关产品推荐

