为了录制音频和视频,我在MediaRecorder API的ondataavailable下创建webm文件。我必须单独播放每个创建的webm文件。
Mediarecorder API只在第一个块(webm文件)中插入头信息,所以其余的块在没有头信息的情况下不会单独播放。
正如link 1和link 2所建议的,我已经从第一个块中提取了头部信息,
// for the most regular webm files, the header information exists
// between 0 to 189 Uint8 array elements
const headerIinformation = arrayBufferFirstChunk.slice(0, 189);
并将该头信息挂入第二块中,第二块仍然不能播放,但此时浏览器显示的是视频海报(单帧)和两块之和的时长,例如:10秒;每个块持续时间为5秒。
同样的标题信息的事情,我已经做了十六进制编辑器。我在编辑器中打开了webm文件,并从第一个webm文件中复制了前190个元素,并将其放入第二个文件中,类似于下图,即使这一次,第二个webm文件也无法播放,结果与前面的示例相同。
红色显示标题信息:
这一次我复制了头和集群信息从第一个webm文件放在第二个文件,类似下面的图片,但没有成功,
问题
我做错了什么?
有没有什么方法可以单独播放webm文件/块?
注意:我不能使用MediaSource播放这些块。
编辑1
正如@布拉德建议的那样,我想将第一个集群之前的所有内容插入到后面的集群中。我有几个webm文件,每个文件的持续时间为5秒。在深入挖掘文件之后,我才知道,几乎每个备用文件都没有集群点(没有0x 1F 43 B675)。
这里我很困惑,我必须在每个文件的开头或每个第一个簇的开头插入头信息(初始化数据)?如果我选择后面的选项,那么如何播放没有任何集群的webm文件?
或者,首先我需要使每个webm文件的方式,它有集群在一开始,所以我可以prepend头信息之前,集群在这些文件?
编辑2
经过一些挖掘和阅读this,我得出的结论是,每个webm文件需要头信息,集群和实际数据。
2条答案
按热度按时间ux6nzvsh1#
//对于最常规的webm文件,头信息是存在的
//0到189个Uint 8数组元素
在没有看到实际文件数据的情况下,很难说,但这可能是错误的。“头信息”需要是直到第一个Cluster element的所有信息。也就是说,您希望保留从文件开始到看到
0x1F43B675
之前的所有数据,并将其视为初始化数据。这可以/将因文件而异。在我的测试文件中,这发生在中的1 KB之后。并将该头信息挂入第二块中,第二块仍然不能播放,但此时浏览器显示的是视频海报(单帧)和两块之和的时长,例如:10秒;每个块持续时间为5秒。
从MediaRecorder输出的块与分段无关,并且可以在不同的时间出现。您实际上希望在Cluster元素上进行拆分。这意味着您需要解析这个WebM文件,至少要解析到当集群的标识符
0x1F43B675
出现时拆分集群的程度。有没有什么方法可以单独播放webm文件/块?
你走在正确的道路上,只要把第一个集群之前的所有东西都前置到后面的集群。
一旦你得到了工作,你可能会遇到的下一个问题是,你将无法做到这一点与任何集群。第一个群集 * 必须 * 以关键帧开始,否则浏览器不会对其进行解码。Chrome会跳到下一个集群,但这并不可靠。不幸的是,没有办法配置关键帧的位置与MediaRecorder。如果你足够幸运,能够处理这个视频服务器端,这里是如何用FFmpeg做到这一点:https://stackoverflow.com/a/45172617/362536
njthzxwz2#
**好吧,看起来这并不像你必须扫描blob来找到神奇值那么容易。
答案是
193``199
现在你看到了。问题是我是怎么得到这个号码的?为什么不是
42
的倍数?暴力
好吧,逻辑很简单,录制视频,收集块,切片第一个块,计算新的blob并尝试使用
HTMLVideoElement
播放它。如果失败,则增加偏移。MediaRecorder.start
中较小的timeslice
参数和setTimeout
中的超时参数,头偏移量变为1。可惜不是42。