【发布时间】:2014-05-25 17:54:24
【问题描述】:
我遇到了一个令人难以置信的问题,我似乎无法解决。
通过 PHP 提供 WebM 文件对我来说并不是什么新鲜事,我什至知道如何使用 HTTP 206 Partial Content。但出于某种原因,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/V00000006.webm 在 Apache 中被重写为 PHP 文件,可以正常播放。
但在 Chrome 中,搜索栏无效。单击搜索栏时,播放器将冻结并且在页面刷新之前不再播放。 Firefox 处理得很好!
如果我将/video/V00000006.webm 更改为指向同一视频的直接链接,它就可以正常工作。我什至比较了两个版本(使用和不使用 PHP)之间的网络请求,第一个请求几乎没有任何差异,但第二个请求在 PHP 交付的视频中失败。
对 Apache 提供的视频文件的初始请求和搜索请求:
请求网址:http://mytestserver.net/movie1152x720.webm 请求方法:GET 状态码:206 部分内容 请求标头 接受:*/* 接受编码:身份;q=1,*;q=0 接受语言:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 缓存控制:无缓存 连接:保持活动 Cookie:PHPSESSID=i562540rek172mnv3nk528acj0;用户密码=;用户邮箱= 主机:mytestserver.net 杂注:无缓存 范围:字节=0- 参考:http://mytestserver.net/video.html 用户代理:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 响应标头 接受范围:字节 连接:关闭 内容长度:4446451 内容范围:字节 0-4446450/4446451 内容类型:video/webm 日期:格林威治标准时间 2014 年 4 月 11 日星期五 13:07:30 ETag:“d2d0027-43d8f3-b91417c0” 最后修改时间:格林威治标准时间 2014 年 4 月 11 日星期五 12:46:31 服务器:Apache/2.2.3 (CentOS) -- 请求网址:http://mytestserver.net/movie1152x720.webm 请求方法:GET 状态码:206 部分内容 请求标头 接受:*/* 接受编码:身份;q=1,*;q=0 接受语言:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 缓存控制:无缓存 连接:保持活动 Cookie:PHPSESSID=i562540rek172mnv3nk528acj0;用户密码=;用户邮箱= 主机:mytestserver.net 杂注:无缓存 范围:字节=4445881- 参考:http://mytestserver.net/video.html 用户代理:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 响应标头 接受范围:字节 连接:关闭 内容长度:570 内容范围:字节 4445881-4446450/4446451 内容类型:video/webm 日期:格林威治标准时间 2014 年 4 月 11 日星期五 13:09:02 ETag:“d2d0027-43d8f3-b91417c0” 最后修改时间:格林威治标准时间 2014 年 4 月 11 日星期五 12:46:31 服务器:Apache/2.2.3 (CentOS)PHP 流视频的初始请求和搜索请求:
请求网址:http://mytestserver.net/video/V00000006.webm 请求方法:GET 状态码:206 部分内容 请求标头 接受:*/* 接受编码:身份;q=1,*;q=0 接受语言:da-DK,da;q=0.8,en-US;q=0.6,en;q=0.4 缓存控制:无缓存 连接:保持活动 Cookie:PHPSESSID=i562540rek172mnv3nk528acj0;用户密码=;用户邮箱= 主机:mytestserver.net 杂注:无缓存 范围:字节=0- 参考:http://mytestserver.net/video.html 用户代理:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36 响应标头 接受范围:字节 Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 连接:关闭 内容长度:8566268 内容范围:字节 0-8566267/8566268 内容类型:video/webm 日期:格林威治标准时间 2014 年 4 月 11 日星期五 13:31:27 过期时间:1981 年 11 月 19 日星期四 08:52:00 GMT 杂注:无缓存 服务器:Apache/2.2.3 (CentOS) X-Powered-By:PHP/5.3.27 -- 请求网址:http://mytestserver.net/video/V00000006.webm 请求标头 注意:显示临时标头。 接受编码:身份;q=1,*;q=0 缓存控制:无缓存 杂注:无缓存 范围:字节=4338314- 参考:http://mytestserver.net/video.html 用户代理: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 页面中显示没有区别。
我希望有人能回答为什么寻找可能不起作用。如果您有任何建议,请告诉我。
谢谢!
【问题讨论】:
标签: php google-chrome ffmpeg html5-video webm