【发布时间】:2020-06-30 04:56:33
【问题描述】:
作为我正在进行的项目的一部分,需要将多段音频数据连接到一个大型音频文件中。音频文件由四个来源生成,各个文件存储在 Google Cloud 存储桶中。每个文件都是一个 mp3 文件,并且很容易验证每个单独的文件是否正确生成(单独的,我可以播放它们,在我最喜欢的软件中编辑它们等)。
为了将音频文件合并在一起,nodejs 服务器使用 axios POST 请求将文件从 Google Cloud 存储加载为数组缓冲区。从那里,它使用Buffer.from() 将每个数组缓冲区放入一个节点缓冲区,所以现在我们有一个缓冲区对象数组。然后它使用Buffer.concat() 将 Buffer 对象连接成一个大 Buffer,然后我们将其转换为 Base64 数据并发送到客户端服务器。
这很酷,但是在连接从不同来源生成的音频时会出现问题。我上面提到的 4 个来源是 Text to Speech 软件平台,例如 Google Cloud Voice 和 Amazon Polly。具体来说,我们有来自 Google Cloud Voice、Amazon Polly、IBM Watson 和 Microsoft Azure Text to Speech 的文件。基本上只有五个文本到语音的解决方案。同样,所有单独的文件都可以工作,但是通过这种方法将它们连接在一起时会产生一些有趣的效果。
当声音文件被连接时,似乎取决于它们来自哪个平台,声音数据要么会包含在最终的声音文件中,要么不会包含在最终的声音文件中。以下是基于我的测试的“兼容性”表:
|------------|--------|--------|-----------|-----|
| Platform / | Google | Amazon | Microsoft | IBM |
|------------|--------|--------|-----------|-----|
| Google | Yes | No | No | No |
|------------|--------|--------|-----------|-----|
| Amazon | | No | No | Yes |
|------------|--------|--------|-----------|-----|
| Microsoft | | | Yes | No |
|------------|--------|--------|-----------|-----|
| IBM | | | | Yes |
|------------|--------|--------|-----------|-----|
效果如下:当我播放大输出文件时,它总是开始播放包含的第一个声音文件。从那里,如果下一个声音文件兼容,就会听到,否则会完全跳过(没有空声音或任何东西)。如果它被跳过,则该文件的“长度”(例如 10 秒长的音频文件)包含在生成的输出声音文件的末尾。但是,当我的音频播放器到达播放最后一个“兼容”音频的位置时,它会立即跳到结尾。
作为一个场景:
Input:
sound1.mp3 (3s) -> Google
sound2.mp3 (5s) -> Amazon
sound3.mp3 (7s)-> Google
sound4.mp3 (11s) -> IBM
Output:
output.mp3 (26s) -> first 10s is sound1 and sound3, last 16s is skipped.
在这种情况下,输出声音文件的长度为 26 秒。在前 10 秒,您会听到 sound1.mp3 和 sound3.mp3 连续播放。然后在 10 秒时(至少在 Firefox 中播放这个 mp3 文件),播放器在 26 秒时立即跳到结尾。
我的问题是:有没有人知道为什么有时我可以以这种方式连接音频数据,而其他时候却不能?怎么会在输出文件的末尾包含这个“缺失”的数据?如果它适用于某些情况,那么连接二进制数据是否应该在所有情况下都有效,因为所有文件都具有 mp3 编码?如果我错了,请告诉我我可以做些什么来成功连接任何 mp3 文件:) 我可以提供我的nodeJS后端代码,但是使用的过程和方法如上所述。
感谢阅读?
【问题讨论】:
标签: node.js audio concatenation buffer mp3