Javascript 检测视频blob上的404:https源

Javascript 检测视频blob上的404:https源,javascript,html,html5-video,webrtc,Javascript,Html,Html5 Video,Webrtc,我使用blob:https作为视频标签的源,如下所示: function mk_bloburl(source_id, url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; //important xhr.onload = function(e) { if (this.status == 200) {

我使用blob:https作为视频标签的源,如下所示:

function mk_bloburl(source_id, url) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob'; //important
    xhr.onload = function(e) {
        if (this.status == 200) {
            var blob = this.response;
            var source = document.getElementById(source_id);
            var video = source;
            if (video.tagName=="SOURCE") {
                video = source.parentNode;
            }
            video.oncanplaythrough = function() {
                URL.revokeObjectURL(source.src);
            };
            source.src = URL.createObjectURL(blob);
            video.load();
        }
    };
    xhr.send();
}

mk_bloburl('review-video-source', my_video_url );
<video id="review-video" controls="" width="100%">
    <source id="review-video-source" />
</video>
GET blob:https://example.com/debeecfe-49b0-4c98-87d6-8ead325b2d75 404 (Not Found)
具有如下HTML:

function mk_bloburl(source_id, url) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob'; //important
    xhr.onload = function(e) {
        if (this.status == 200) {
            var blob = this.response;
            var source = document.getElementById(source_id);
            var video = source;
            if (video.tagName=="SOURCE") {
                video = source.parentNode;
            }
            video.oncanplaythrough = function() {
                URL.revokeObjectURL(source.src);
            };
            source.src = URL.createObjectURL(blob);
            video.load();
        }
    };
    xhr.send();
}

mk_bloburl('review-video-source', my_video_url );
<video id="review-video" controls="" width="100%">
    <source id="review-video-source" />
</video>
GET blob:https://example.com/debeecfe-49b0-4c98-87d6-8ead325b2d75 404 (Not Found)
所以,这就像一段时间后,blob会自动从浏览器内存中删除。我想在事件被擦除或通过开始播放获取404时捕获事件,以便刷新该blob

我试过:

var source = document.querySelector("#review-video-source");
source.addEventListener("error", function(event) {
    console.debug("An error accoured");
});
但这似乎没有抓住错误。
我能做什么?

一种绕过它的方法是使用类似的so:

function mk_bloburl(source_id, url){
  fetch(url)//usual get
  .then(response=>{
    if(response.status == 404)
    //Should set here what is an error (ex: x>299)
      Promise.reject("Error 404!");
    return response.blob();
  })//get blob
  .then(blobObj=>{//use blob
    var blob = blobObj;
    var source = focument.getElementById(source_id);
    var video = source;
    if(video.tagName === "SOURCE")
      video = source.parentNode;
    video.oncanplaythrough = ()=>{
      URL.revokeObjectUrl(source.src);
    };
    source.src = URL.revokeObjectURL(blob);
    video.load();
  })
  .catch(error=>{
    //There has been an error,
    //do something about it
    //here
  });
}

您的主要问题是由于您在事件中撤销了blobURI

canplaythrough事件只是一个由浏览器发送的通知,让我们知道它认为它能够不间断地加载和播放整个媒体;这并不意味着它已经加载了所有内容

在BlobURI的例子中,连接速度如此之快,它来自内存,以至于浏览器可能认为它能够在一眨眼的时间内获取4k的星球大战传奇。 所以你很早就得到了这个canplaythrough事件,但是浏览器实际上还没有解压所有的数据。尽管如此,您还是撤销了BlobURI,当浏览器再次尝试获取数据以便解压并读取数据时,BlobURI指针的末尾不再有任何内容

因此,对于您的问题,您有两种解决方案:

如果您只需要播放媒体一次: 在事件中调用URL.revokeObjectURLblobURI。这将在视频的currentTime第一次到达末尾时触发

如果需要多次播放视频: 在出现页面时撤销blobURI。这样,只要页面处于活动状态,BlobURI指针就始终处于活动状态,但不会在内存中阻止整个Blob超过页面寿命,如果根本不撤销BlobURI,就会发生这种情况

关于如何在视频blob:https源上检测404,我真的不知道有什么好方法,除了听一个意外的跳转到结尾,但blobURIs无论如何都不需要这样做