HTML5视频源作为本地存储的BLOB不再起作用
从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();
输出: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
我过去常常将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返回的BLOB完全相同
但是,它不起作用:
输出:未捕获(承诺中)DOMException:该元素没有受支持的源。
我想不出是什么改变打破了以前的正常工作。 更奇怪的是:
如果我获得存储的blob,即显然不能再直接分配给video src的blob,则我执行此操作.
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,即使在金丝雀版本(82)中,您的开场白也很棒this issue。
现在,有比通过XHR获取更简单的解决方法,例如在STRATE(80)中,您只需要将检索到的Blob包装在一个新的Blob中:
video.src = URL.createObjectURL(new Blob( [ blob ] ) );
ASa fiddle,因为堆栈片段™不允许访问索引数据库。
但是,此解决方法似乎只在稳定版本(80)上有效,在Canary(82)上,我们需要将整个Blob实际读取到ArrayBuffer并从该ArrayBuffer构建新的Blob:
const buf = await blob.arrayBuffer();
vid.src = URL.createObjectURL( new Blob( [ buf ] ) );
fiddle。
由于后者也适用于稳定,并且我们不知道他们何时能够修复该错误,因此您可能希望改用第二种解决方法。
1:或者如果您希望我这样做,请告诉我。
相关文章