【问题标题】:HTML5 video element not requesting end RangeHTML5 视频元素不请求结束范围
【发布时间】:2017-05-22 03:14:55
【问题描述】:

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

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

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

这是来自 Chrome 的完整请求列表,在底部您可以看到对 url view?watch=v__AAAAAA673pxX 的请求一直处于待处理状态,基本上直到 element 发出新请求为止。

简而言之:当使用http-range 请求时,html5 元素会陷入下载循环,并导致所有其他请求保持“待处理”状态。

更新

问题已在服务器端解决。

虽然原始流函数会输出每个字节,但我已修改代码以仅输出实际缓冲区的大小。这会强制elements 对剩余数据发出新请求。

这里的一个重要注意事项是在每个HTTP RANGE 请求中返回与文件大小、开始和结束位置相匹配的content-lengthaccept-rangescontent-ranges

供日后参考:

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();
}

【问题讨论】:

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


    【解决方案1】:

    假设您有一个 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,则可能会导致压缩,从而禁用范围标头

    【讨论】:

    • 你是对的。不幸的是,提供的代码使用while 循环将数据输出到请求。我已经做到了,只输出缓冲区大小(例如(1024 * 1024)),以便在达到缓冲区大小后立即关闭输出流。这确保了&lt;video&gt;/&lt;audio&gt; 必须发出新的数据请求,因为提供的数据与Content-Length 标头不匹配。
    猜你喜欢
    • 2013-03-27
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多