0

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

我们的音频文件是从各种文本到语音提供商生成的。我们最近注意到,当我们使用 ssml 转换音频以向生成的音频添加暂停时,文件上的持续时间不再正确。经过进一步调查,我们注意到标准音频也不正确,由于数据更一致,总体上更准确。当我们在音频开始处暂停时,估计是最差的,超出了很大的幅度(例如,25 秒的音频剪辑会读为 3 分钟长,但播放超过 25 秒时会跳到结尾.

我对 MP3 文件的结构进行了一些搜索和研究,对我来说,问题似乎是因为各种音频播放器估计了持续时间。Windows 媒体播放器就是一个例子,但 Firefox 的网络播放器似乎也能做到这一点。我尝试将 ffmpeg 命令从 using .audioQuality(0)(将 ffmpeg 设置为使用 VBR)更改为.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 标签,为音频的消费者指定信息,以便在可能处理整个文件之前知道持续时间。但是,我也发现似乎没有一个标准,至少在持续时间上是这样。更多信息,如歌曲名称、专辑、艺术家等。

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

4

1 回答 1

0

默认情况下,FFmpeg 确实会写入带有持续时间信息的 Xing 标头。但是,只有在接收到整个流数据后才能知道该值,因此 ffmpeg 必须寻找头部来写入它。由于您正在管道输出,因此无法完成。

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

于 2022-03-04T08:47:26.327 回答