我将如何将 mp3 文件打包到 mp4 容器中?

How would I go about packaging an mp3 file into an mp4 container?

这就是我目前遇到的问题。我需要一个 iOS 的音频播放器来播放 mp3。乍一看,这似乎是一个微不足道的问题,只需创建一个 audio 标签并将 URL 赋给 mp3 文件即可。虽然这在技术上可行,但它基本上无法使用,因为 iOS 需要在开始播放之前下载整个文件。这导致在尝试播放大型 mp3 文件时等待时间非常长(可能接近一分钟)。 所以我尝试的第一件事是手动模仿 chrome 为播放 mp3 文件所做的分块。我首先发送了一个 HEAD 请求来获取音频文件的字节长度。使用该长度/持续时间(以秒为单位)来获取每秒的平均字节数,并使用该数据根据用户寻求的位置请求块。这不起作用,因为有时 mp3 文件包含会影响计算的元数据(如封面图像)。此外,有时 mp3 文件使用 VBR(可变比特率),然后我就完蛋了。

所以这让我想到,Safari 不可能要求最终用户在播放之前下载整个 mp4 文件。所以我拿了一个 mp3 文件,在在线转换器上将其转换为 mp4 并测试了我的理论。瞧,它奏效了。 Safari 以块的形式流式传输 mp4 文件,等待时间接近 0。好的,现在我需要做的就是将 mp3 文件转换为 mp4 文件。现在的问题是,我要求不要使用我的服务器来转换这些文件。我想将这个昂贵的操作卸载给客户端。环顾四周后,我发现了一些 wasm 库可以做到这一点,太棒了!没有。这些 wasm 库非常大 (24 MB),会给我已经很大的捆绑文件增加无法接受的数量。所以这让我想到了我的问题。有什么方法可以让 "trick" safari 认为我的 mp3 文件是 mp4。我已经尝试过的:

输入更改事件 -> 获取文件 -> 将其克隆到 mimeType 为 video/mp4 的新 Blob 中,然后将该文件上传到服务器。 Chrome 在 Safari 上播放这个文件没有问题(可能是因为它检测到它是一个 mp3 文件),但是它无法播放这个文件。

所以我的问题是,是否有任何方法可以将 mp3 文件打包到 mp4 容器(客户端!重要)到 "force" Safari 以分块文件。

Is there any way to "trick" safari into thinking that my mp3 file is mp4

mp4 文件不可搜索,因为客户端 "thinks" 它们是 mp4。他们在搜索工作所需的文件中有一个索引。该索引并不神奇地存在,因为 mime 类型已更改。

is there any way to package the mp3 file in an mp4 container (Client Side...

是的,完全是。但是你必须写代码,而且很复杂。您可以阅读 ISO 14496-12 文档以了解 mp4 文件的结构。和 ISO 11172-3 和 ISO 13818-3 将 Mp3 解析为可以写入 MP4 的帧

我上个月做了这件事,我只需要它用于 128kbps CBR mp3 直播,所以我硬编码了一些东西来支持该特定格式,它可以修改为专门支持不同的比特率,但可能不会可变比特率:/。将它张贴在这里以防任何使用 firefox 而不使用媒体源扩展播放 mp3 的人使用它:https://gist.github.com/fanfare/0fa525af28b275fd6623942d7e9d70dd