首页 > 解决方案 > 如果 Blob URL 是不可变的,Media Source Extension API 如何使用它们来流式传输视频?

问题描述

让我们从一个例子开始:

  1. 您访问 youtube.com,该网站在某些设备上使用带有 HTML5 的媒体源扩展 (MSE)。
  2. MSE 使用 blob URL 注入 <video> 标记。它看起来像这样:blob: https: //www.youtube.com/blahblahblah
  3. 在流式传输整个视频的过程中,您的浏览器会进行多次网络调用以下载各种视频块,并将它们附加到 MSE 的 SourceBuffer
  4. 因此,Meda Source 对象作为一个整体在整个视频流中更新
  5. 但是,最初附加到 <video> 元素的 blob URL(假定表示媒体源对象)保持不变。

对我来说,这似乎没有多大意义。假设 Blob URL 表示永远不会更改的不可变数据块。但似乎 MSE 能够使它们代表一个可变的内存缓冲区。

这在引擎盖下是如何工作的?如果我们还想让 blob URL 代表一些可变的内存缓冲区,我们如何使用 javascript 自己做到这一点?

标签: javascripthtmlbrowsermedia-source

解决方案


您需要了解 BlobURI不代表任何数据。它们只是链接,指向内存中的某些资源,就像字符串https://stackoverflow.com/questions/54613972本身不包含您正在阅读的任何内容一样,它只是指向将生成页面的服务器指令。

它们的链接可以说是不可变的,一旦你使用 生成它URL.createObjectURL(target),你就不能改变它target,就像你使用const关键字一样。

例如const foo = {}现在foo不能设置为除此对象之外的其他内容。但是地址指向的对象foo仍然是可变的。foo.bar = 'baz'仍然可以完成。

const foo = {};
try{
  foo = 'fails';
}
catch(e) {
  console.error(e);
}
foo.mutable = true;

console.log(foo);

好吧,对于 blobURI,它是一样的。blobURI 指向一个target对象,此链接无法更改,但target仍是可变的。这适用于 MediaSource 对象,但也适用于其他对象。

如果你还记得几年前,我们仍然可以为 MediaStreams 使用 blobURI(这是一个坏主意),这是相同的过程,blobURI 以不可变的方式指向 MediaStream 对象,但是媒体-数据不断变化(流)。

即使对于文件,您也可以很好地拥有一个指向硬盘驱动器上的文件的 blobURI,这不会阻止您将其从硬盘中删除,即使 blobURI 现在不再指向任何地方。

这方面的一个特殊情况是 Blob 的情况,它是从内存中的数据生成的(即不仅仅是指向磁盘上文件的指针)。这里 Blob 持有的数据是不可变的,所以在这种情况下,blobURI 确实指向一个确实持有不可变数据的对象。

对于您请求有一个指向存储在内存中的某些数据的 blobURI,但仍然能够修改此数据,这是无法完成的......
这是因为这种情况意味着您使用 Blob 对象创建了 blobURI内存中的数据,它再次将数据保存在不可变状态。


推荐阅读