Media Source Extensions appendBuffer of WebM stream 以随机顺序

Media Source Extensions appendBuffer of WebM stream in random order

我正在尝试实现从多个来源并行下载视频。但是MSE appendBuffer 方法在不遵循视频文件的顺序时总是失败。

我想以随机顺序添加部分并播放视频 "as soon as possible"。 我正在探索 SourceBuffer 模式 属性 以及 timestampOffset。 None 其中有帮助。

我想知道我拥有的源 webm 文件是否可以在 "not supported format" 中用于这样的任务(顺序方法工作正常)。

source video file

感谢您的任何建议。

更新: 我试图分析众所周知的 example video file 并且我发现可以不按顺序附加其中的一部分。似乎有必要遵循 Cluster byte ranges:

<Cluster type="list" offset="4357">
  <Timecode type="uint" value="0"/>
  <SimpleBlock type="binary" size="7723" trackNum="1" timecode="0" presentationTimecode="0" flags="80"/>
  <SimpleBlock type="binary" size="5" trackNum="2" timecode="0" presentationTimecode="0" flags="80"/>
  ...
</Cluster>
<Cluster type="list" offset="16187">
  <Timecode type="uint" value="385"/>
  <SimpleBlock type="binary" size="5" trackNum="2" timecode="0" presentationTimecode="385" flags="80"/>
  <SimpleBlock type="binary" size="4968" trackNum="1" timecode="13" presentationTimecode="398" flags="80"/>
  ...
</Cluster>

在深入了解 webm 格式规范、编译 libwebm 工具和研究 DASH 后,我 终于想出了如何让 MSE appendBuffer 以任意顺序工作!

  1. ffmpeg -i result.webm -g 10 -c:v libvpx resultClusters.webm (也可以使用libvpx-vp9)
  2. mkvmuxer_sample -i resultClusters.webm -o resultRepaired.webm
  3. mse_json_manifest resultRepaired.webm >> manifest.json

您将在 stdout 上得到如下内容:

{
  "type": "video/webm; codecs=\"vp8\"",
  "duration": 27771.000000,
  "init": { "offset": 0, "size": 258},
  "media": [
    { "offset": 258, "size": 54761, "timecode": 0.000000 },
    { "offset": 55019, "size": 166431, "timecode": 2.048000 },
    { "offset": 221450, "size": 49258, "timecode": 4.130000 },
    { "offset": 270708, "size": 29677, "timecode": 6.148000 },
    { "offset": 300385, "size": 219929, "timecode": 8.232000 },
    { "offset": 520314, "size": 25132, "timecode": 10.335000 },
    { "offset": 545446, "size": 180777, "timecode": 12.440000 },
    { "offset": 726223, "size": 76107, "timecode": 14.471000 },
    { "offset": 802330, "size": 376557, "timecode": 14.794000 },
    { "offset": 1178887, "size": 247138, "timecode": 16.877000 },
    { "offset": 1426025, "size": 78468, "timecode": 18.915000 },
    { "offset": 1504493, "size": 25614, "timecode": 20.991000 },
    { "offset": 1530107, "size": 368277, "timecode": 23.093000 },
    { "offset": 1898384, "size": 382847, "timecode": 25.097000 },
    { "offset": 2281231, "size": 10808, "timecode": 27.135000 }
  ]
}

现在您所要做的就是首先加载元数据 xhr.setRequestHeader("Range", "bytes=0-257");,然后在 ANY ORDER 中加载所有其他段。例如。第二段范围是 55019-221449 字节。

解释:

最重要的是 ffmpeg 重新编码 帧组 设置为您想要的集群大小。在这个例子中,我选择了非常低的阈值(每 10 帧),但你可以选择更高的 导致生成更少的簇("media" 数组中的项目更少)。

之后,您必须以经典方式修复 cues(使用 sample_muxer 来自 libwebm ) 就可以开始了。

测试于:Chrome 51,Firefox 47。