php safari播放mp4,修复video标签在safari中无法播放mp4视频的问题

前言

近期一个站长联系我,向我求救解决一个bug,该问题在网络上很多遇到,但是没有正常的解决方案。

特此记录下。

问题

该站长有一个discuz论坛,其中在帖子中发布视频时,如果添加的视频地址是其他站点的地址或者图片下的视频路径,可以正常播放。

如果使用附件中地址,则异常。

fecdec504ab0

image.png

其中无法播放的地址的代码如下

原因

safari浏览器,在打开视频的时候,他不是一次性请求全部文件的,一般首先会请求0-1字节,这个写在request header的"range"字段中:range:'bytes=0-1'

fecdec504ab0

image.png

chrome也会发送range,只不过它是这样的: 'bytes=0-',表示可以一次性加载整个视频文件。

fecdec504ab0

image.png

如果是想要传输视频,必须要解析range字段,然后按照range字段的要求返回对应的数据,同时response header至少要包含三个字段:"Content-Type", "Content-Range", "Content-Length"

"Content-Type"必需明确指定视频格式,有"video/mp4", "video/ogg", "video/mov"等等。

"Content-Range"格式是 "bytes -/",其中start和end必需对应request header里的range字段,total是文件总大小,不是返回的数据长度

"Content-Length"指定返回的二进制长度

这里需要注意:所有的end是指inclusive end,意味着文件长度如果是245,返回"Content-Range"就是"bytes 0-244/245",错一点视频就放不出来了。

如果你的视频文件可以被直接访问,则以上解析工作是由nginx来处理的。你无需处理,通常可以正常播放。

如果你的视频是编码输出的,例如需要php或者java等读取二进制流,则需要手动处理。

解决

php针对range解析视频流的代码如下:

$total = filesize($filename);

if(isset($_SERVER['HTTP_RANGE'])) {

$range = str_replace('=','-',$_SERVER['HTTP_RANGE']);

$range = explode('-',$range);

if (isset($range[2]) && intval($range[2]) >0){

$end = trim($range[2]);

}else{

$end = $total-1;

}

$start = trim($range[1]);

$size = $end-$start+1;

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

header('Content-Range: bytes '.$start.'-'.$end.'/'.$total);

} else {

$size = $total;

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

header('Content-Range: bytes 0-'.($total-1).'/'.$total);

}

header('Accenpt-Ranges: bytes');

header('Content-Type: video/mpeg4');

$fp = fopen($filename,'rb+');

fseek($fp,$start);

while(!feof($fp)) {

print(fread($fp,$size));

flush();

ob_flush();

}

fclose($fp);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值