14

我知道没有 blob url 只有对象。
我为视频缓冲区制作了自己的 blob 对象,然后在类似于blob://website.com/blablabbla的视频标签的 src 中使用它。我在它工作的浏览器中打开了这个网址

当我将 youtube 视频 src(blob url)的 url 打开到一个新标签时,它不起作用,但我的视频 src(blob url)有效

我想知道如何对我的 blob url 执行相同的操作,以便它们仅在 html 视频标签的 src 中工作并给出错误或在浏览器的外部选项卡/窗口中不起作用。我只是想知道这个和 blob 对象及其 url 属性背后的技术。

4

2 回答 2

12

这个问题对我来说似乎有些模糊,所以这是我的解释(也来自您问题中的小提琴图像中的代码):

  • 您通过-request ( )接收Blob(图像的二进制数据)XMLHttpRequest() GETresponseType = 'blob'
  • 您在for -object中创建一个Blob URLwith (保存二进制数据)URL.createObjectURL()URL StoreXMLHttpRequest() responseBlob
  • 您将生成的Blob URL-string设置src为图像(并将图像附加到文档中,从而显示您刚刚下载的图像)
  • 您“不希望它在新选项卡中工作”(“it”是Blob URL我假设的 -string)。

在您的评论中,您说:

  • 在小提琴中,我检查了图像并复制了 src,然后将其粘贴到新选项卡中,它可以正常工作并显示图像我不希望图像直接与 blob url 一起显示。

  • 如果你去 youtube 并在新标签中打开视频的 src :它不会工作,我希望这发生

在我看来,您希望用户在复制 -string 时能够查看/下载 blob Blob URL(通过检查实时源或简单地right-click-on-image>>Copy Imagelocation)并将其粘贴到新的选项卡/窗口中(您为此提供 youtube举个例子)。

但你也在谈论视频。

TL;DR:您的问题/赏金似乎混合了由以下返回的 2 种不同类型的 URL window.URL.createObjectURL();

  • Blob URL引用(表示的对象)“原始本地数据”(如(本地)文件、Blob 等)
    对于这些,您希望自动(或以编程方式)从浏览器中撤销(您可以考虑在浏览器,仅适用于该浏览器)。 Blob URLURL Store
  • MediaSource object URL引用一个特殊的 MediaSource 对象
    这些 URL 是
    • 仅用于将srcHTMLMediaElement思考<audo><video>元素)链接到特殊MediaSource Object
      注意:新选项卡/窗口不是HTMLMediaElement
    • 已经 自动撤销
      注意:即使它们是通过window.URL.createObjectURL();

这是您的问题图像中的小提琴和下载视频的类似代码Blob(您使用 xhr 在服务器上下载整个视频文件的数据/二进制文件)或任何其他“本地”数据的情况:
您实际上是在使用'裸''未增强' File-API
仅在URL Store会话期间维护(因此它将在页面刷新后继续存在,因为它仍然是同一会话)并在文档卸载时丢失。
所以,如果你的 fiddle 仍然打开,那么 fiddle-document(创建 的文档Blob URL)显然还没有被卸载,因此Blob URL只要它没有被撤销,它就可以用于浏览器(任何选项卡/窗口)!
这是一个相关功能:您可以在浏览器中构建/下载/修改 a Blob,创建 aBlob URL并将其设置为href文件下载链接(用户可以右键单击并在新选项卡/窗口中打开!!)
关闭小提琴或Blob URL从 the撤消 theURL Store和 theBlob URL不再可访问(也不在不同的选项卡/窗口中)。

尝试使用修改后的小提琴: https
://jsfiddle.net/7cyoozwv/ 在这个小提琴中,现在应该不再可以在复制图像 url 后将示例图像加载到不同的选项卡/窗口中(一旦图像显示在您的页面中)。
在这里,我手动撤销了 URL ( revokeObjectURL()),因为它是目前最好的跨浏览器方法(部分原因是 api 尚未完全稳定)。
另请注意:元素的onload事件可以是撤销您的Blob URL.


以下是链接到使用返回的<audio><video>MediaSource ObjectMediaSource object URLwindow.URL.createObjectURL(MediaSource)
an的或源发生的情况媒体源扩展 (MSE) 还扩展File-API'window.URL.createObjectURL()以接受MediaSource Object. URL 对象扩展的(当前草案)指定:

该算法旨在反映 autoRevoke 设置为 true 的 createObjectURL()[FILE-API] 方法的行为。

请注意,File API's的当前规范window.URL.createObjectURL() 不再具有可供程序员访问的autoRevoke(或flag_oneTimeOnly)布尔标志,而应该将其window.URL.createFor()用于此目的。我想知道 Media-Source 规范何时会模仿这一点(并且为了向后兼容将它们别名createObjectURL()为新的createFor()扩展名(似乎更合适,因为这似乎是它目前的工作方式))。

这些生成的自动撤销的 URL 字符串用于srca HTMLMediaElement(think <audo>& <video>elements) 链接到特殊的MediaSource Object.
我不认为一个空的Document(来自一个新的选项卡/窗口)是一个<audo>or<video>元素。

也许“关于 MSE 的快速教程” (来源:MSDN可能有助于阐明区别和基本用法:

要使用 MSE API,请执行以下步骤:

  1. video在页面的 HTML 部分中定义一个 HTML5元素。
  2. MediaSource在 JavaScript 中创建一个对象。
  3. createObjectURL使用MediaSource对象作为源创建一个虚拟 URL 。
  4. 将虚拟 URL 分配给视频元素的src属性。
  5. 使用您要添加的视频的 mime 类型创建SourceBufferusing 。addSourceBuffer
  6. 从在线媒体文件中获取视频初始化片段,并将其添加到SourceBufferwith appendBuffer.
  7. 从媒体文件中获取视频数据的片段,将它们附加到SourceBufferwith appendBuffer
  8. 调用play视频元素上的方法。
  9. 重复步骤 7 直到完成。
  10. 清理。

您(或像 youtube 这样的大玩家,他们将动态选择支持的技术在客户端平台上播放(因此无法确定您在谈论哪种 youtube 视频 URL))可能正在使用新的特殊功能MediaSource Object播放视频(或音频)。
这为 HTML5 视频添加了基于缓冲区的源选项以支持流式传输(与在播放之前下载完整的视频文件或使用 Silverlight 或 Adob​​e Flash 等插件流式传输媒体相比)。

希望这就是你所追求的!

于 2016-04-07T22:04:22.583 回答
5

实际上,您引用的 URL 只是"string"对自身的引用BLOB(使用函数创建window.URL.createObjectURL);因此,您可以像使用普通 URL 一样使用它。而且,范围也仅限于文档卸载之前。

因此,我认为您不可能仅使用浏览器打开 URL。而且我还尝试重新创建您所说的内容,但无济于事(在我自己的网站中,创建一个 blob 并将 URL 放入浏览器)。

下面是代码

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://kurrik.github.io/hackathons/static/img/sample-128.png");
xhr.responseType = "blob";
xhr.onload = function response(e) {
   var urlCreator = window.URL || window.webkitURL;
   var imageUrl = urlCreator.createObjectURL(this.response);
   console.log(imageUrl);
   var imgDOM = document.createElement("img");

   imgDOM.src = imageUrl;
   document.getElementById("divImage").appendChild(imgDOM);
};
xhr.send();

小提琴在这里


更新 :

好的,我看了之后。似乎 youtube 正在使用媒体源来流式传输视频。

我还没有更新小提琴(找不到我可以使用的视频)。但是,基本上,它仍然使用相同的函数 ( createObjectURL) 来创建 blob URL。但是,不是使用源(图像、视频等)传递给函数。您应该将MediaSource对象传递给函数。

然后,您使用 blob URL 并将其传递到video.src. 因此,当您尝试打开 blob 链接时。您应该无法再次看到该视频。

于 2016-04-07T08:24:44.033 回答