事情本身不复杂,线索都在日志里。把 44.1kHz 立体声的访谈录音转成 16k 单声道喂给转写模型,命令是 ffmpeg -i in.mp3 -ar 16000 -ac 1 out.wav,结果整段音频听起来比原片慢了半拍,转写出来的时间戳整体后移。换成 sox 转就没有这个现象,试过加 -sample_fmt s16 也没用。
第一反应是「输出容器选错,采样率写进头里但数据没重采样」,验证下来不成立。
这类报错背后常见的原因有几处,逐个排除就行。输入是可变帧率的 mp3,重采样时没有做时间基准对齐。也可能是async 参数默认 1,允许按样本数拉伸时间轴。
少数情况下是音频里有可变比特率的拼接段,解码器补了静音。
动手时先看输入流的真实采样率与帧时长
ffprobe -v error -show_entries stream=sample_rate,channels,codec_name -of default=nw=1 in.mp3
再往下重采样时把 async 关掉
ffmpeg -i in.mp3 -ar 16000 -ac 1 -af aresample=async=0 out.wav
接着用 sox 转一遍做对照
sox in.mp3 -r 16000 -c 1 out_sox.wav
剩下的就是比较两个输出的时长是否一致
ffprobe -v error -show_entries format=duration -of csv=p=0 out.wav out_sox.wav
改完先别撤,确认这几项。转出的 wav 时长与原片相差在 50ms 以内,转写时间戳与人工标注对齐,语速听感恢复正常。
这里还有个坑。aresample 的 async 默认值会为了补齐时间戳做拉伸,处理语音素材时显式写成 async=0,再单独处理真正的断流。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
