我有一个<video>
和<audio>
元素,它通过Range请求从我的服务器加载文件(mp4,mp3,无关紧要)。
然而,似乎元素只从我的服务器请求结束范围,并从那里开始尝试直接从字节0流到结尾,导致播放器卡在&#34;下载循环中#34 ;,这使浏览器暂停所有其他操作,直到下载完成。
有谁知道这个问题的解决方案?例如,我是否必须使我的流请求真正结束其content length
或accept-ranges
?
以下是Chrome的完整请求列表,您可以在底部看到对网址view?watch=v__AAAAAA673pxX
的请求保持待定状态,基本上直到{{1}发出新请求为止}。
简而言之:当使用element
请求时,html5元素会陷入下载循环,导致所有其他请求停留在等待状态&#34;。
更新
问题已在服务器端解决。
尽管原始流函数会逐字输出每个字节,但我修改了代码以仅输出实际缓冲区的大小。这会强制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;
}
}
答案 0 :(得分:2)
假设您有一个1M字节的视频 当您第一次浏览视频请求时,它会发送这样的标题
Host:localhost
Range:bytes=0-
范围标题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
它明确告诉文件的哪个部分。所以我猜你的服务器没有发送这些信息而且浏览器被窃听了。
另外,有时mime类型也会导致问题,尝试使用文件的确切mimetype,如Content-Type: video/mp4
。如果使用Content-Type: application/octet-stream
,则可能导致压缩,这会禁用范围标题