首页 > 解决方案 > 在特定时间加载 BLOB 视频

问题描述

例如,我会将 BLOB 视频加载为 Youtube 或 Netflix。即在BLOB中加载0s到10s的视频,显示出来,然后加载10s到20s的视频。

我考虑过执行此代码(它可以在没有 #t =0,10 的情况下工作,但在返回之前等待整个视频加载)。

var query = new XMLHttpRequest();
var videolink = "test.mp4";
var videobalise = $("video");
var get = videolink + "#t=0,10";

query.open("GET", get, true);
query.responseType = "blob";
query.onload = function(){

   if(this.status === 200){

        var currentTime = videobalise[0].currentTime;
        var paused = false;
        if(!videobalise[0].paused) paused = true;

        window.URL = window.URL || window.webkitURL;

        var videoBlob = this.response;
        var video = window.URL.createObjectURL(videoBlob);

        videobalise.attr("src", video);
        videobalise[0].currentTime = currentTime;

        if(paused == true){
            videobalise[0].play();
        }

   }
}
query.send();

在此先感谢,
托马斯

标签: javascriptvideoblob

解决方案


我不能告诉 Netflix,但对于 YouTube,这不是他们所做的。

您看到的作为src<video>元素的 blob URI 指向MediaSource对象,而不是 Blob。


现在,MediaElement 中的#t片段标识符src仅适用于 MediaElement。
MediaElements 将尝试仅从服务器加载所需的数据。这要归功于Range requests。但它要求媒体的元数据已经被提取和解析,这样浏览器才能知道下一个要加载的数据位于哪个字节范围。片段标识符只是告诉浏览器我们只对其中定义的范围感兴趣的一种方式,因此,这个片段标识符还需要媒体的元数据是可访问的,并提供正确的字节偏移量
#t

所有这些都表明您实际上需要在设置此#t片段标识符的 URI 上提供完整的文件。

因此,在您的情况下,您必须从原始 URI 加载完整文件,并且只有在您将设置为<video>' 的blob URI 上,您src才会附加片段标识符:

var url = "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/a4/BBH_gravitational_lensing_of_gw150914.webm/BBH_gravitational_lensing_of_gw150914.webm.480p.webm";
fetch(url) // fetch the whole file
  .then(resp => resp.blob())
  .then(blob => {
    const blobURI = URL.createObjectURL(blob);
    const fragId = '#t=5' // starts at 5s
    vid.src = blobURI + fragId; // here you set the fragId
  });
video{height:100vh}
<video id="vid" controls></video>

所以这可能不是你想要的,因为你实际上会加载完整的文件。

但我猜你真正想要的是一种隐藏原始文件的方法,拼命地试图阻止你的用户下载它。然后,很遗憾地告诉你,这根本行不通,因为你的 AJAX 请求是清晰可见的。
请注意,即使按范围获取自己并使用像 YT 这样的 MediaSource 也不起作用,YT 视频实际上是可下载的。

如果您真的想这样做,最好的办法可能是使用Encrypted Media Extensions API


推荐阅读