html从多个url下载文件块,就好像它是1个文件一样

时间:2019-01-29 08:04:20

标签: javascript html5

我想将文件拆分为多个块,并将每个块托管在不同的url或服务器上,是否有可能欺骗客户端,就像从单个url下载文件一样? (无需更改服务器托管文件的方式)

我想使用视频文件来执行此操作,因此我可以在html video元素中使用它作为源,但可以从多个服务器进行流式传输。

计划B将创建一个自定义视频播放器,并根据需要更改源,但这绝不是无缝的。

1 个答案:

答案 0 :(得分:0)

您无法通过简单的方式真正实现与浏览器相同的行为。

您必须了解,浏览器在显示媒体时非常聪明,并且可以访问我们只是js激活器无法访问的信息。
首先,当他们确实显示媒体时,他们将搜索元数据。这些通常位于文件的开头,也可以位于文件的末尾(也许有时位于其他位置,但这在网络上很少见)。
因此,他们从一开始就进行range request开始,希望能够解析文件的元数据,如果找不到,他们将在末尾进行搜索。
一旦获得了这些元数据,他们就会知道每个数据块相对于媒体时间戳的位置。因此,他们只能从服务器请求显示用户请求的时间所需的字节。
这样一来,您可以找到比已经获取的东西更远的东西。搜索完成后,浏览器将取消之前的请求,并在请求的时间(如果尚未提取)对包含数据的字节范围进行新的请求。

浏览器负责获取和解码部分,因此两者可以一起通信,并且可以进行此设置。但是,我们无权访问解码部分,我们所能做的就是获取数据,并将其提供给浏览器的解码器。

这意味着要能够做您想做的事情,我们将需要知道我们文件的生成方式,以便能够根据用户的需要使自己成为正确的 range-requests 寻求操作。

这是可行的,实际上,这是大多数视频服务(例如YouTube)所做的,以提供可变的媒体质量。 您可以使用MediaSource将数据提供给浏览器的解码器,就像它是来自服务器的流一样。
数据作为流提供的事实还意味着您将必须构建自己的用户界面,以使他们能够找到所需的位置。希望您能理解,我不会在此答案中这么做,而是保持很高的水平。



即使它可能无法满足您的需求,我也必须包括惰性方法,该方法包括下载完整的介质并将其构建在用户的计算机内存中。 这具有无法执行任何范围请求的巨大缺点,因此您的用户必须下载整个文件,然后才能开始播放它,如果您的用户不是一个好主意,在慢速的网络上,但它的优点是易于实施:

// some URLs
const path = "https://dl.dropboxusercontent.com/s/",
  file1 = "f945qd8gju2x5y6/part_1.mp4",
  file2 = "qs3us6qve32jjju/part_2.mp4"
console.log('begin to fetch, please be patient');
// fetch all the different parts
Promise.all([
  fetch(path + file1).then(r=>r.blob()),
  fetch(path + file2).then(r=>r.blob())
])
// merge in a single Blob
.then(arr => new Blob(arr)) 
// display from memory
.then(blob => vid.src = URL.createObjectURL(blob))
.then(_ => console.log('ready to play'));
<video id="vid" controls></video>