HTML5视频元素未请求结束范围

时间:2017-01-07 12:07:10

标签: javascript php html5 http-headers http-range

我有一个<video><audio>元素,它通过Range请求从我的服务器加载文件(mp4,mp3,无关紧要)。

然而,似乎元素只从我的服务器请求结束范围,并从那里开始尝试直接从字节0流到结尾,导致播放器卡在&#34;下载循环中#34 ;,这使浏览器暂停所有其他操作,直到下载完成。

Range request 1

Range request 2

有谁知道这个问题的解决方案?例如,我是否必须使我的流请求真正结束其content lengthaccept-ranges

以下是Chrome的完整请求列表,您可以在底部看到对网址view?watch=v__AAAAAA673pxX的请求保持待定状态,基本上直到{{1}发出新请求为止}。

Full range request history

简而言之:当使用element请求时,html5元素会陷入下载循环,导致所有其他请求停留在等待状态&#34;。

更新

问题已在服务器端解决。

尽管原始流函数会逐字输出每个字节,但我修改了代码以仅输出实际缓冲区的大小。这会强制http-range对剩余数据发出新请求。

这里的一个重要注意事项是返回与elements个请求中文件的大小,起始和结束位置相匹配的content-lengthaccept-rangescontent-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;
    }
}

1 个答案:

答案 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,则可能导致压缩,这会禁用范围标题