有没有办法使用 FFMPEG 确保可变比特率的 mp3 持续时间准确性?



在我们的应用程序中,我们使用ffmpeg处理音频文件。具体来说,我们使用 NodeJS 库fluent-ffmpeg,(npm 链接)。

我们的音频文件是从各种文本到语音提供商生成的。我们最近注意到,当我们使用 ssml 转换音频以向生成的音频添加暂停时,文件的持续时间不再正确。经过进一步调查,我们注意到标准音频也不正确,只是由于数据更一致,整体更准确。当我们在音频开头暂停时,估计是最差的,超过它非常大(例如,25 秒的音频剪辑读起来为 3 分钟长,但在播放超过 25 秒标记时跳到最后。

我对 MP3 文件的结构进行了一些搜索和研究,对我来说,问题似乎是因为持续时间是由各种音频播放器估计的。Windows 媒体播放器就是一个例子,但 Firefox 的网络播放器似乎也这样做。我尝试将 ffmpeg 命令从使用.audioQuality(0)更改为.audioBitrate(320),它告诉 ffmpeg 使用恒定比特率。 作为参考,我们使用libmp3lame,运行的完整命令如下,分别用于VBR和CBR情况:

对于 VBR(中断持续时间):ffmpeg -i <URL> -acodec libmp3lame -aq 0 -f mp3 pipe:1对于 CBR(正确的持续时间):ffmpeg -i <URL> -acodec libmp3lame -b:a 320k -f mp3 pipe:1

注意:在发送适当的文件头后,我们将输出通过管道传输到请求客户端应用程序,因此 pipe:1 输出。输入是源文件所在的云存储 URL

这解决了我们拥有正确持续时间的问题,如果问题是因为其中一些播放器/音频消费者正在估计持续时间,那么为什么会解决它,这对我来说是有道理的。但是,这是以文件大小明显更大为代价的,这对我来说也很有意义。在测试时,我们发现与WAV中的相同文件相比,VBR mp3约为WAV文件大小的10%,而CBR mp3仍然是WAV文件大小的50%。这实际上违背了为我们的用例支持 mp3 格式的目的,这是大型 WAV 文件的较小但略有损的替代方案。

在研究过程中,我发现 mp3 文件开头的块中可以有 ID3 标签,为音频的使用者指定信息,以便在可能处理整个文件之前知道持续时间。但是,我也发现似乎没有一个标准,至少在持续时间上是这样。更多内容,如歌曲标题、专辑、艺术家等。

我的问题是,有没有办法在仍然使用 VBR 的同时获得 mp3 文件的适当持续时间,最好是通过一些 ffmpeg 机制?谢谢!

FFmpeg 默认会写入带有持续时间信息的 Xing 标头。但是,该值仅在收到整个流数据后才知道,因此 ffmpeg 必须寻找头部来写入它。由于您正在管道输出,因此无法做到这一点。

将文件写入本地或某个可搜索的目标,然后上传。

最新更新