欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

php 输出视频流ios无法播放的问题(隐藏真实播放地址),已解决

程序员文章站 2022-03-09 20:15:57
...

通过php直接输出的文件通常不被html5的<video>标签支持,尤其是ios设备。为了完美支持html5的视频播放,php必须支持byte-range请求。因为html5播放视频之前会发送一个只需文件少数字节的请求,确认服务端是否支持byte-range请求,支持才会继续发送请求剩余的文件数据。

具体的问题就是 byte-range ,相信遇到这个问题的朋友也在网上搜索到了许多相关的问题,接下来下面是整理后的代码,经测试苹果端可支持播放,代码如下:

<?php

$localfile = "test.mp4";

$size = filesize($localfile);

$start = 0;
$end = $size - 1;
$length = $size;

header("Accept-Ranges: 0-$size");
header("Content-Type: video/mp4");

$ranges_arr = array();
if (isset($_SERVER['HTTP_RANGE'])) {
    if (!preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/i', $_SERVER['HTTP_RANGE'])) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
    }
    $ranges = explode(',', substr($_SERVER['HTTP_RANGE'], 6));
    foreach ($ranges as $range) {
        $parts = explode('-', $range);
        $ranges_arr[] = array($parts[0],$parts[1]);
    }

    $ranges = $ranges_arr[0];
    if($ranges[0]==''){
        if($ranges[1]!=''){
            //Range: bytes=-n 表示取文件末尾的n个字节
            $length = (int)$ranges[1];
            $start = $size - $length;
        }else{
            //Range: bytes=- 这种形式不合法
            header('HTTP/1.1 416 Requested Range Not Satisfiable');
        }
    }else{
        $start = (int)$ranges[0];
        if($ranges[1]!=''){
            //Range: bytes=n-m 表示从文件的n偏移量读到m偏移量
            $end = (int)$ranges[1];
        }
        //Range: bytes=n- 表示从文件的n偏移量读到末尾
        $length = $end - $start + 1;
    }
    header('HTTP/1.1 206 PARTIAL CONTENT');
}

header("Content-Range: bytes {$start}-{$end}/{$size}");
header("Content-Length: $length");

$buffer = 8096;
$file = fopen($localfile, 'rb');
if($file){
    fseek($file, $start);
    while (!feof($file) && ($p = ftell($file)) <= $end){
        if ($p + $buffer > $end) {
            $buffer = $end - $p + 1;
        }
        set_time_limit(0);
        echo fread($file, $buffer);
        flush();
    }
    fclose($file);
}
die;

?>

 

将代码中的 视频地址更换成你自己本地的视频地址,然后就可以跑起来了。如果有问题请留言指出不足之处,谢谢!

注意:该代码仅支持本地文件流的读取和输出!不支持url 形式的文件。