当前位置: 首页 > 知识库问答 >
问题:

通过PHP加载时,在Chrome中找不到WebM文件(其他浏览器也可以)

龙俭
2023-03-14

我有一个令人难以置信的问题,我似乎无法解决。

在我的世界里,通过PHP提供WebM文件并不是什么新鲜事,我甚至知道如何处理HTTP 206部分内容。但由于某些原因,Chrome不喜欢它。

一个简单的HTML5视频播放

<video width="640" height="360" poster="picture/preview/V00000006.jpg" controls="controls" preload>
    <source type="video/webm" src="/video/V00000006.webm">
</video>

其中/video/v0000006。webm在Apache中被重写为PHP文件,可以正常播放。但在Chrome中,seekbar并不有效。当点击seekbar时,播放器将冻结,直到页面刷新后才会播放。Firefox处理得很好!

如果我更改/video/v0000006。webm要直接链接到同一个视频,它工作得很好。我甚至比较了两个版本(使用和不使用PHP)之间的网络请求,第一个请求几乎没有任何区别,但第二个请求在PHP交付的视频中失败。

Apache交付视频文件的初始请求和搜索请求:

    Request URL:http://mytestserver.net/movie1152x720.webm
    Request Method:GET
    Status Code:206 Partial Content
    Request Headers
    Accept:*/*
    Accept-Encoding:identity;q=1, *;q=0
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4
    Cache-Control:no-cache
    Connection:keep-alive
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail=
    Host:mytestserver.net
    Pragma:no-cache
    Range:bytes=0-
    Referer:http://mytestserver.net/video.html
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36
    Response Headers
    Accept-Ranges:bytes
    Connection:close
    Content-Length:4446451
    Content-Range:bytes 0-4446450/4446451
    Content-Type:video/webm
    Date:Fri, 11 Apr 2014 13:07:30 GMT
    ETag:"d2d0027-43d8f3-b91417c0"
    Last-Modified:Fri, 11 Apr 2014 12:46:31 GMT
    Server:Apache/2.2.3 (CentOS)

    --

    Request URL:http://mytestserver.net/movie1152x720.webm
    Request Method:GET
    Status Code:206 Partial Content
    Request Headers
    Accept:*/*
    Accept-Encoding:identity;q=1, *;q=0
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4
    Cache-Control:no-cache
    Connection:keep-alive
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail=
    Host:mytestserver.net
    Pragma:no-cache
    Range:bytes=4445881-
    Referer:http://mytestserver.net/video.html
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36
    Response Headers
    Accept-Ranges:bytes
    Connection:close
    Content-Length:570
    Content-Range:bytes 4445881-4446450/4446451
    Content-Type:video/webm
    Date:Fri, 11 Apr 2014 13:09:02 GMT
    ETag:"d2d0027-43d8f3-b91417c0"
    Last-Modified:Fri, 11 Apr 2014 12:46:31 GMT
    Server:Apache/2.2.3 (CentOS)

PHP流视频的初始请求和查找请求:

    Request URL:http://mytestserver.net/video/V00000006.webm
    Request Method:GET
    Status Code:206 Partial Content
    Request Headers
    Accept:*/*
    Accept-Encoding:identity;q=1, *;q=0
    Accept-Language:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4
    Cache-Control:no-cache
    Connection:keep-alive
    Cookie:PHPSESSID=i562540rek172mnv3nk528acj0; userPassword=; userEmail=
    Host:mytestserver.net
    Pragma:no-cache
    Range:bytes=0-
    Referer:http://mytestserver.net/video.html
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36
    Response Headers
    Accept-Ranges:bytes
    Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Connection:close
    Content-Length:8566268
    Content-Range:bytes 0-8566267/8566268
    Content-Type:video/webm
    Date:Fri, 11 Apr 2014 13:31:27 GMT
    Expires:Thu, 19 Nov 1981 08:52:00 GMT
    Pragma:no-cache
    Server:Apache/2.2.3 (CentOS)
    X-Powered-By:PHP/5.3.27

    --

    Request URL:http://mytestserver.net/video/V00000006.webm
    Request Headers CAUTION: Provisional headers are shown.
    Accept-Encoding:identity;q=1, *;q=0
    Cache-Control:no-cache
    Pragma:no-cache
    Range:bytes=4338314-
    Referer:http://mytestserver.net/video.html
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36

请注意第二个请求是如何不完成的,显示了临时标头。

我尝试过修改缓存头,将其设置为将来,将其设置为空,并使用文件附件头。

我试着摆弄了很多服务代码,但是最近我得到了一个简单的例子。

<?php

$path = 'test.webm';

$size=filesize($path);

$fm=@fopen($path,'rb');
if(!$fm) {
  header ("HTTP/1.0 404 Not Found");
  die();
}

$begin=0;
$end = $size-1;

if(isset($_SERVER['HTTP_RANGE'])) {
  if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
    $begin=intval($matches[0]);
    if(!empty($matches[1])) {
      $end=intval($matches[1]);
    }
  }
}

if($begin>0||$end<$size)
  header('HTTP/1.0 206 Partial Content');
else
  header('HTTP/1.0 200 OK');

header("Content-Type: video/webm");
header('Accept-Ranges: bytes');
header('Content-Length:'.($end-$begin+1));
header("Content-Disposition: inline;");
header("Content-Range: bytes $begin-$end/$size");
header("Content-Transfer-Encoding: binary\n");
header('Connection: close');

ob_get_clean();
flush();

$f = fopen($path, 'r');
fseek($f, $offset);

$pos = 0;
$length = $end-$begin;

while($pos < $length)
{
    $chunk = min($length-$pos, 1024);

    echo fread($f, $chunk);
    flush();

    $pos += $chunk;
}
?>

请注意,直接在浏览器中输入PHP交付的视频URL与在HTML页面中显示没有区别。

我希望有人能回答为什么寻找可能不起作用。如果你有任何建议,请告诉我。

谢谢

共有1个答案

杜辰龙
2023-03-14

供大家将来参考:

  1. PHP中HTTP_范围的在线示例充满了错误
  2. Chrome不善于解释网络错误
  3. 大小很重要

简而言之,我的问题是由于我的PHP脚本计算并返回错误的数字。Chrome会表现得好像它甚至没有尝试完成网络请求,这使得调试变得很困难。

现在,我把我所有的网络电话,并通过cURL(在我的Linux控制台)拉他们。在这里,我会得到一个更有用的错误,如curl:(18)传输关闭,剩余1个字节读取

内容长度的1字节错误使Chrome取消网络请求,而不向您显示它得到的响应头以及取消请求的原因。

这是我的工作代码,包含内容范围和内容长度的工作计算$filesize=filesize($file);

$offset = 0;
$length = $filesize;

$partialContent = false;

if(isset($_SERVER['HTTP_RANGE']))
{
    $partialContent = true;

    if(!preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches))
    {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header('Content-Range: bytes */' . $filesize);
        exit;
    }

    $offset = intval($matches[1]);

    if(isset($matches[2]))
    {
        $end = $intval($matches[2]);
        if($offset > $end)
        {
            header('HTTP/1.1 416 Requested Range Not Satisfiable');
            header('Content-Range: bytes */' . $filesize);
            exit;
        }

        $length = $end - $offset;
    }
    else
        $length = $filesize - $offset;
}

header('Content-Length: ' . $length);

if($partialContent)
{
     header('HTTP/1.1 206 Partial Content');
     header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $filesize);
     // A full-length file will indeed be "bytes 0-x/x+1", think of 0-indexed array counts
}

请注意,上面的代码片段只包含与部分内容相关的代码,您仍然需要其他标题等来实际处理它。

如果有人感兴趣,下面是我读取文件的代码。我在网上看到了很多关于这方面的错误建议,但我认为我的建议很干净。

$f = fopen($file, 'r');
fseek($f, $offset);

$pos = 0;

while($pos < $length)
{
    $chunk = min($length-$pos, 1024*8);

    echo fread($f, $chunk);
    flush();
    ob_flush();

    $pos += $chunk;
}

案件结案,祝大家好运:-)

 类似资料:
  • 问题内容: 我正在尝试在客户端动态生成文件时在客户端上显示“掩码”。似乎为此的推荐解决方法(因为它不是ajax)是使用iframe并从onload或done事件中侦听以确定文件从服务器实际发送到客户端的时间。 这是我的角度代码: 这在Firefox中效果很好,但在Chrome中没有运气。我也尝试过使用onload函数: 但是我那里也没有运气。 有想法吗? 问题答案: 不幸的是,如果内容是附件,则无

  • 我注意到Chrome中的orderBy排序与其他浏览器中的排序不同。 我正在为角1.3中的一个项目写作。 对于特定的浏览器没有特殊的逻辑,两个数组完全相同。 谓词是显式定义的: 我的ng重复看起来像这样: 我的代码没有什么特别之处。但是,“大小”是字符串(例如大小:“8-”、…、大小:“6”、…)。为什么Chrome上的排序方式与其他浏览器完全不同? 我所有的结果都是从后端按样式分组排序,然后按大

  • 我很难让谷歌字体在Chrome中工作 我正在使用Google的建议链接元素来检索字体(开发工具确认它工作正常)。 Link rel="样式表"href="http://fonts.googleapis.com/css?family=Roboto压缩:400italic" 在CSS文件中,我将所有h2、按钮、选择和输入元素的字体系列设置为“机器人浓缩” 在Google Chrome中,只有字体不显示

  • 问题内容: 我想确保通过AJAX调用请求的数据是新鲜的,而不是被缓存的。为此,我发送标题 但是如果用户按下F5键,我的Chrome版本33会覆盖此标头。 例。将内容与您的网络服务器放在一起 在网络标签上的Chrome调试器中,我看到了test.html AJAX调用。状态代码200。现在按F5重新加载页面。最长寿命:0,状态码304未修改。 Firefox表现出类似的行为。只是覆盖了请求标头,它会

  • 我试图在python中使用selenium chromedriver创建网站www.mouser.co.uk。但从第一枪就被检测为bot。 有人对此有解释吗?。以下是我使用的代码:

  • 问题内容: 我将Selenium与Python Chrome webdriver一起使用。在我的代码中,我使用了: 将webdriver指向webdriver可执行文件。是否可以将webdriver指向Chrome浏览器二进制文件? 在https://sites.google.com/a/chromium.org/chromedriver/capabilities中,它们具有以下内容(我认为这是我