HTML5 作为本地存储的 blob 的视频源不再有效

HTML5 Video source as locally stored blob not working anymore

从 Chrome 80 开始,Blob 或 IndexedDB 的工作方式似乎发生了变化。

将视频文件作为 blob 加载并通过 createObjectURL 将其分配给 HTML5 视频元素,仍然有效:

// load the blob through XMLHttprequest
RequestAsBlob("https://devserver/some-video.mp4",
function(blob)
{
  video.src = URL.createObjectURL(blob); 

  // same above, video.src is now "blob:https://devserver/36e15718-e597-4859-95d3-6bc39daaa999"
}

video.play();

输出:承诺{} 而且视频播放得很好。

检查 blob,它看起来像这样:

Blob {size: 6752122, type: "video/mp4"}
size: 6752122
type: "video/mp4"
__proto__: Blob
arrayBuffer: ƒ arrayBuffer()
size: (...)
slice: ƒ slice()
stream: ƒ stream()
text: ƒ text()
type: (...)
constructor: ƒ Blob()
Symbol(Symbol.toStringTag): "Blob"
get size: ƒ size()
get type: ƒ type()
__proto__: Object

我曾经将blob存储到IndexedDB(通过LocalForage),然后检索它并播放它,如下。这个,不再

// blob is a blob fetched from indexedDB
video.src = URL.createObjectURL(blob);  

// video.src is now something like this:
// "blob:https://devserver/ec5e1dfe-0884-40e2-ae8c-c6062734d297"

video.play();

检查检索到的 blob,它看起来与 XMLHttpRequest 返回的完全一样

然而,它不起作用:

输出:未捕获(承诺)DOMException:该元素没有支持的源。

我无法弄清楚是什么改变打破了过去的工作方式。 它变得更奇怪了:

如果我得到存储的 blob,显然不能再直接分配给视频 src 的那个,我会这样做...

var url = URL.createObjectURL(cachedblob);

RequestAsBlob(url,
function(blob)
{
 var url = URL.createObjectURL(blob);

 video.src = url;
 video.play();
}

这行得通!!我正在引用一个存储在 indexedDB 中的 blob,为它创建一个 url,通过 XMLHttpRequest 再次加载它,就像它实际上在某个远程位置一样,再次将它作为一个 blob 接收....并再次创建一个 URL 给它...它起作用了。

没有意义。 我希望有人能对此有所启发。

Could repro, even in Canary build (82), you did great opening this issue.

现在,有比通过 XHR 获取更简单的解决方法,例如在稳定版 (80) 中,您只需将检索到的 Blob 包装在一个新的 Blob 中:

video.src = URL.createObjectURL(new Blob( [ blob ] ) ); 

因为 a fiddle 因为 StackSnippet™ 不允许访问 IndexedDB。

然而,此解决方法似乎仅适用于稳定版本 (80),在 Canary (82) 上,我们需要实际将整个 Blob 读取到 ArrayBuffer 并从该 ArrayBuffer 构建一个新的 Blob:

const buf = await blob.arrayBuffer();
vid.src = URL.createObjectURL( new Blob( [ buf ] ) );

fiddle.
由于后者也适用于稳定版,而且我们不知道他们何时能够修复该错误,您可能希望改用第二种解决方法。

1:或者如果你想让我做,请告诉我。