让我们从一个例子开始:

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

  • 对我来说,这似乎没有多大意义。假定Blob URL代表了永不改变的不可变数据块。但是,似乎MSE能够使它们代表可变的内存缓冲区。

    这是如何工作的?而且,如果我们还想使Blob URL表示一些可变的内存缓冲区,那么我们如何使用JavaScript自己做到这一点?

    最佳答案

    您需要了解BlobURIs 不代表任何数据。它们只是链接,指向内存中的某些资源,就像字符串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);

    对blobURIs来说是一样的。 blobURI指向target对象,此链接无法更改,但target仍然可变。 MediaSource对象也是如此,其他对象也是如此。
    如果您还记得几年前,我们仍然能够对MediaStreams使用blobURI(是个坏主意),那是相同的过程,blobURI以不可更改的方式指向MediaStream对象,但是媒体-数据处于不断变化中(流)。
    即使对于文件,您也可以在硬盘驱动器上拥有一个指向文件的blobURI,即使现在blobURI不再指向任何位置,这也不会阻止您将其从硬盘中删除。
    在这方面的一种特殊情况是Blob的情况,它是由内存中的数据(即不仅仅是指向磁盘上文件的指针)生成的。在这里,Blob所保存的数据是不可变的,因此在这种情况下,blobURI确实指向确实保存了不可变数据的对象。
    而且对于您要求有一个blobURI指向存储在内存中的某些数据,但仍然能够修改此数据,则无法完成...
    这是因为这种情况意味着您使用内存中的数据从Blob对象创建了blobURI,该内存再次将数据保持在不可变状态。

    09-20 21:04