• PHP后端读取文件给video标签返回视频地址


    获取请求文件内容起始位

    通过$_SERVER['HTTP_RANGE']或者TP5的request()->header('Range')方法来获取原始头
    Range: bytes=0- //请求头原样
    Range: bytes=0-1 //IOS请求头

    /**
      * 获取请求range
      * @param string $range 请求头range值
      * @return array $ret 请求内容范围 $ret['start'] 开始位,$ret['end']结束位
      */
    private function getPlayRange($range)
    {
            $ret=[];
            list($key, $offset) = explode('=', $range);
            list($start, $end) = explode('-', $offset);
            $ret=[
                'start'=>$start,
                'end'=>$end
            ];
            return $ret;
    }
    

    获取文件内容

    通过file_get_contents来读取文件内容

    /**
      * 获取文件流
      * @param string $file 文件绝对路径
      * @param int $offset 文件偏移值
      * @param int $length 请求的文件长度
      * @return $stream 文件内容
      */
    private function getFileStream($file, $offset,$length)
    {
            //超时或超出大小可以修改PHP参数 memory_limit和max_execution_time
            //set_time_limit(0)
            $size = filesize($file);
            //限制超出文件长度
            if($offset+$length>=$size){
                $length=$size;
            }
            return @file_get_contents($file, false, null, $offset, $length);
    }
    

    设置响应头

    需要输出以下3个响应头
    Content-Length: 27602948 // 本次响应文件长度
    Content-Range: bytes 0-27602947/27602948 {偏移起始值}-{偏移结束值-1}/{文件总大小}
    Content-Type: video/mp4

    /**
      * 获取响应头
      * @param string $file 文件绝对路径
      * @param int $offset 文件偏移值
      * @param int $length 请求的文件长度
      * @return array $header 响应头
      */
    private function getVideoHeader($file, $offset,$length)
    {
            $size = filesize($file);
            $end=0;
            //设置返回长度范围
            if($offset+$length>=$size){
                $end=$size-1;
                $length=$size-$offset;
            }else{
                $end=$offset+$length- 1;
            }
            $header = [
                'Content-Length' => $length,
                'Content-Range' => 'bytes ' . $offset . "-" . $end . "/" . $size,
                'Content-Type' => 'video/mp4'
            ];
            return $header;
    }
    /**
       * 获取IOS响应头
       * @param string $file 文件路径
       * @param int $start 内容起始位置
       * @param int $end 内容结束位置
       * @return array $header 响应头
       */
    private function getVideoHeaderByIOS($file, $start,$end)
    {
        $size = filesize($file);
        $length=$end-$start+1;
        $header = [
            'Content-Length' => $length,
            'Content-Range' => 'bytes ' . $start . "-" . $end . "/" . $size,
            'Content-Type' => 'video/mp4'
        ];
        return $header;
    }
    

    输出结果

    这里需要返回206状态码
    使用header()设置响应头返回文件内容
    TP5可以使用response()方法响应;
    response($stream, 206, $header);

    try {
        //获取视频流和视频头
        if($range['end']!=''){
            //兼容IOS IOS下请求头range回有开始位和结束位 PC和安卓则只有起始位
            $stream = $this->getFileStream($file, $range['start'], $range['end']-$range['start']+1);
            $header = $this->getVideoHeaderByIOS($file, $range['start'], $range['end']);
        }else{
            //每次读取长度
            $length=1024*1024*5;
            $stream = $this->getFileStream($file, $range['start'],$length);
            $header = $this->getVideoHeader($file, $range['start'],$length);
        }
    } catch (Exception $e) {
        exit($e->getMessage());
    }
    return response($stream, 206, $header);
    
  • 相关阅读:
    [2011Summary Weekly]March.28April.1
    如何对需求分析人员进行考核测试角度
    算法实现三角形式输出C(n,k)
    Scrum 培训系列Scrum on a Page
    [练习]solveMaze
    excel中如何统计条件筛选后的条数
    开发人员绩效考核中"有效"bug数的统计
    Scrum 培训系列Scrum Lifecycle
    IIS6.0日志文件自定义类代码
    IIS6.0日志文件分析代码_3线程读取文件到数据库
  • 原文地址:https://www.cnblogs.com/xinghan/p/10913695.html
Copyright © 2020-2023  润新知