2017-08-16 69 views
0

我使用的blob:HTTPS作为源为我的视频标签,就像这样:检测404: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); 

有了HTML这样的:

<video id="review-video" controls="" width="100%"> 
    <source id="review-video-source" /> 
</video> 

现在,如果我重新加载页面并开始播放,它的工作原理。如果我玩,让它玩,然后重播没有等待时间它的作品。 然而,如果我重新加载页面,然后等待一段时间(如1-2分钟),然后按播放,它会失败。

留言我在Chrome浏览器中得到如下:

GET blob:https://example.com/debeecfe-49b0-4c98-87d6-8ead325b2d75 404 (Not Found) 

所以,它就像一滴被自动移除了一段时间后,浏览器内存中。我想在事件被删除或者当我通过开始播放获得404时捕获该事件,因此我可以刷新该Blob。

我曾尝试:

var source = document.querySelector("#review-video-source"); 
source.addEventListener("error", function(event) { 
    console.debug("An error accoured"); 
}); 

但是,这似乎并没有捕获错误。 我能做什么?

回答

1

你的主要问题是您在canplaythrough事件吊销blobURI造成的事实。

canplaythrough事件只是浏览器发出的通知,让我们知道它认为它可以在不中断的情况下加载和播放整个媒体;这并不意味着它已经加载了所有内容。

在BlobURI的情况下,连接速度非常快(来自内存),浏览器可能认为它能够在4k瞬间获取StarWars传奇。
因此,您很早就得到这个canplaythrough事件,但浏览器实际上并未压缩所有数据。尽管如此,您还是撤消了BlobURI,当浏览器再次尝试获取数据以便解压缩并读取它时,BlobURI指针的末尾就再也没有任何东西了。

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

  • 如果你需要播放的媒体只有一次
    呼叫URL.revokeObjectURL(blobURI)ended事件。这将会触发,视频的当前时间首次到达结尾。

  • 如果需要多次播放视频:在beforeunload活动页面
    撤销blobURI。这样,只要页面处于活动状态,BlobURI指针就始终处于活动状态,但不会在内存中阻塞整个Blob的时间超过页面生命(如果您完全不撤销BlobURI,则会发生这种情况)。


以及如何视频BLOB检测404:HTTPS源,我真的不知道一个很好的方法,除了监听意外跳转到结束,但是这不应该是无论如何都需要blobURIs。

0

一种方法来解决它使用fetch API像这样:

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 
    }); 
}