视频加载用URL.createObjectURL,调用revoke后报错net::ERR_FILE_NOT_FOUND
问题分析与解决
问题原因
URL.createObjectURL()生成的URL是本地文件的临时引用,调用URL.revokeObjectURL()后这个引用会立即被销毁。你用setTimeout(() => {...}, 0)相当于同步代码执行完就立刻销毁URL,但此时视频还没完成文件的完整加载或缓冲,后续播放需要读取文件内容时找不到引用,就会抛出net::ERR_FILE_NOT_FOUND错误,导致播放中断。
解决方案
要等视频完成加载,或者确定不再需要该URL时再调用revokeObjectURL(),常用的触发时机是监听视频的loadeddata或ended事件:
修改后的JavaScript代码
document.getElementById('file').addEventListener('change', function (e) { const video = document.getElementById('video'); const url = URL.createObjectURL(this.files[0]); video.src = url; // 监听视频第一帧加载完成事件,加载完成后销毁URL video.addEventListener('loadeddata', function revokeUrl() { URL.revokeObjectURL(url); // 移除事件监听,避免重复触发 video.removeEventListener('loadeddata', revokeUrl); }); // 也可以选择监听视频播放结束事件,播放完再销毁 // video.addEventListener('ended', function revokeUrl() { // URL.revokeObjectURL(url); // video.removeEventListener('ended', revokeUrl); // }); })
代码说明
loadeddata事件:视频第一帧加载完成时触发,此时视频已获取足够文件数据,后续播放不再依赖原URL引用。- 销毁URL后移除对应事件监听,防止重复执行。
如果是大视频,createObjectURL比FileReader转Data URL的性能更好,优先选择上述时机调用销毁方法的方案。
内容的提问来源于stack exchange,提问作者amirhosein karimi
相关产品推荐
相关产品推荐

