我有一个<video>和<audio>元素,它通过范围请求从服务器加载一个文件(mp4,mp3,不重要)。
但是,元素似乎只从我的服务器请求结束范围,从那里开始尝试直接从字节0流到末尾,导致播放器陷入“下载循环”,这使得浏览器暂停所有其他操作,直到下载完成为止。


有人知道这个问题的解决办法吗?例如,我是否必须使流请求的content length或accept-ranges有一个实际的结束?
这是来自Chrome的完整请求列表,在底部您可以看到,对url view?watch=v__AAAAAA673pxX的请求一直处于待定状态,基本上直到element放置了一个新请求为止。

简单地说,html5元素在使用http-range请求时会被困在下载循环中,并导致所有其他请求保持“挂起”。
更新
这个问题在服务器端得到了解决。
虽然原始流函数实际上会输出每一个字节,但我修改了代码,使其只输出实际缓冲区的大小。这迫使elements对剩余的数据提出新的请求。
这里的一个重要注意事项是返回与文件大小、开始和结束位置匹配的content-length、accept-ranges和content-ranges在每个HTTP RANGE请求中的位置。
供今后参考:
function stream(){
$i = $this->start;
set_time_limit(0);
while(!feof($this->stream) && $i <= $this->end) {
$bytesToRead = $this->buffer;
if(($i+$bytesToRead) > $this->end) {
$bytesToRead = $this->end - $i + 1;
}
$data = fread($this->stream, $bytesToRead);
echo $data;
flush();
$i += $bytesToRead;
}
}新的流功能:
function stream()
{
//added a time limit for safe-guarding
set_time_limit(3);
echo fread($this->stream, $this->offset);
flush();
}发布于 2017-01-07 15:11:15
假设当浏览器第一次请求视频时有1M字节的视频将像这样发送头部
Host:localhost
Range:bytes=0-Range header bytes=0-意味着浏览器要求服务器返回到它可以返回的任何东西。没有指定结束位置。
对于此服务器,通常会使用除最后一个字节以外的整个文件来回复,以保留范围上下文。
Accept-Ranges:bytes
Content-Length:99999
Content-Range:bytes 0-99999/1000000现在假设您的视频被下载到30%,并且您寻求到70%,那么浏览器将请求该部分报头如下所示
Host:localhost
Range:bytes=700000-然而,元素似乎只向我的服务器请求结束范围,
你可以看到你被错误地推断--这是视频部分的起始位置
现在服务器可能会回复如下
Accept-Ranges:bytes
Content-Length:300000
Content-Range:bytes 700000-99999/1000000注意,Content-Range,它显式地告诉文件.So的哪一部分,我猜您的服务器没有发送这些信息,浏览器也被窃听了。此外,有时候mime类型也会引起问题,尝试使用文件的精确mimetype,如Content-Type: video/mp4.If,您使用Content-Type: application/octet-stream,然后可能导致压缩,这将禁用范围标头。
https://stackoverflow.com/questions/41521272
复制相似问题