我有两个必须一个接一个播放的音频文件。 为此,我使用XHR
下载了这两个文件var xhr = new XMLHttpRequest();
xhr.open('GET', fileURL, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
data = new Uint8Array(xhr.response);
//... other handling code
};
并从中构建了一个Blob
var blob = new Blob([data], {type: 'video/mp4'})
这些我用来构建Blob URL
var url = URL.createObjectURL(blob)
然后注入<audio>
标签。 (audioDOM.src = url;
)
此程序适用于Chrome和Firefox。但IE11有时会给我一个问题,它会显示以下注意事项:
通过关闭它们的blob来撤消一个或多个blob URL 被创造。这些URL将不再作为数据支持解析 网址已被释放。
然而,最奇怪的部分是它对第一个文件起作用(在IE中),但对第二个文件不起作用。它们都对整个过程使用相同的代码,只需使用不同的fileURL
调用。这两个文件都存在,已正确下载并已记录到控制台进行验证。
我尝试在构建blob之前复制数据,但似乎并不重要:错误仍然存在。
有没有人知道导致问题的原因以及如何解决问题?
在sbgoran之后编辑:
整个脚本在单个文档上运行,该文档未重新加载。我仍然感到困惑,为什么会这样。我确实设法通过在音频无法加载时循环和创建新URL来创建变通方法,但这不是一个可行的解决方案。奇怪的是,上述方法随机失败:有时URL加载到<audio>
标签时可用,有时则不是。
答案 0 :(得分:6)
除了sbgoran的答案之外,我还有另一个可能的原因 - 如discussed on WhatWG mailing list,IE中有一个错误导致Blob在指向它的变量超出范围时被垃圾收集 - 即使有仍然是指向尚未撤销的Blob的对象URL。
只要需要对象URL,解决方法就可以依赖于保留变量中的原始Blob对象,然后使变量无效并在之后撤消其对象URL。
答案 1 :(得分:2)
根据MSDN createObjectURL method页面的Remarks
部分,IE可能会抱怨很多内容。我不确定您之前是否阅读过这个MSDN页面,但它可能会以某种方式提供帮助。
我会特别检查有关blob网址原始政策的说明
Blob网址受原始政策约束。这意味着它们只能用于与运行创建URL的脚本的文档具有相同原始站点的文档。如果需要使用在不同域中运行的blob对象,则必须使用postMessage API将blob数据发送到框架,然后在那里创建blob:url。
和
createObjectURL返回的URL在创建文档的生命周期内有效,
答案 2 :(得分:1)
然后将注入
<audio>
标签。
你能给这个代码吗?
也许IE有一些垃圾收集器,只要没有包含blob url的DOMString
实例就可以释放blob url。
根据这个理论,用innerHTML
(也许是setAttribute?)创建你的音频标签,我的意思是通过连接url(foo.innerHTML = '<audio src="' + url + '" />';
)意味着唯一包含blob的DOMString
url(由URL.createObjectURL
返回的那个)将在你的函数结束后的某个时间被垃圾收集。