res*_*sle 10 javascript blob indexeddb
从 Chrome 80 开始,Blob 或 IndexedDB 的工作方式似乎发生了一些变化。
将视频文件作为 blob 加载并通过 createObjectURL 将其分配给 HTML5 Video 元素,仍然有效:
// 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();
Run Code Online (Sandbox Code Playgroud)
输出:Promise {} 并且视频播放得很好。
检查 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
Run Code Online (Sandbox Code Playgroud)
我曾经将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();
Run Code Online (Sandbox Code Playgroud)
检查检索到的 blob,它看起来与 XMLHttpRequest 返回的完全一样
但是,它不起作用:
输出:未捕获(承诺)DOMException:该元素没有支持的来源。
我无法弄清楚是什么变化打破了以前的工作直到现在。它变得更奇怪:
如果我得到存储的 blob,那个显然不能再直接分配给视频 src 的 blob,我这样做......
var url = URL.createObjectURL(cachedblob);
RequestAsBlob(url,
function(blob)
{
var url = URL.createObjectURL(blob);
video.src = url;
video.play();
}
Run Code Online (Sandbox Code Playgroud)
这有效!!我正在引用一个存储在 indexedDB 中的 blob,为它创建一个 url,通过 XMLHttpRequest 再次加载它,就像它实际上在某个远程位置一样,再次将它作为 blob 接收......并再次为其创建一个 URL ...它的工作原理。
这没有道理。我希望有人能对此有所了解。
可以重现,即使在 Canary 版本 (82) 中,您在打开此问题时也做得很好。
现在,有比通过 XHR 获取更简单的解决方法,例如在 stable (80) 中,您只需要将检索到的 Blob 包装在一个新的 Blob 中:
video.src = URL.createObjectURL(new Blob( [ blob ] ) );
Run Code Online (Sandbox Code Playgroud)
作为一个小提琴,因为 StackSnippet™ 不允许访问 IndexedDB。
然而,这种解决方法似乎只适用于稳定版本 (80),在 Canary (82) 上,我们需要实际将整个 Blob 读取到一个 ArrayBuffer 并从该 ArrayBuffer 构建一个新的 Blob:
const buf = await blob.arrayBuffer();
vid.src = URL.createObjectURL( new Blob( [ buf ] ) );
Run Code Online (Sandbox Code Playgroud)
小提琴。
由于后者也适用于稳定版,并且我们不知道他们何时能够修复该错误,因此您可能希望改用第二种解决方法。
1:或者如果你想让我这样做,请告诉我。