Yii2 MP4视频文件二进制流播放的实现

 /**以二进制流读文件,不可以续传
     * @param $file
     * @param string $type
     */
    public function video1($file,$type = 'video/mp4"')
    {
            $response = \Yii::$app->response;
            $response->format = Response::FORMAT_RAW;
            $header =  $response->headers;
            if ($header->has('Content-Type')) {
                $header->set("Content-Type",$type);
            } else {
                $header->set("Content-Type",$type);
            }
            $response->send();
            readfile($file);
    }

/**以二进制流读文件,可以续传
 * @param $file 文件路径
 * @param string $name 文件自定义的名称
 * @param array $options
 * $opions['fileSize'] 文件内容的字节数
 * $opions['inline'] bool true为用浏览器打开,false为下载到本地
 * $opions['mimeType'] 输出内容的类型
 * @throws NotFoundHttpException
 */
public function video2($file,$name = '',$options = [])
{
    ob_clean();
    $response = \Yii::$app->response;
    $fp = fopen($file,'rb');
    if (!$fp) {
        throw new NotFoundHttpException('文件不存在');
    }
    isset($options['fileSize'])?  : $options['fileSize'] = filesize($file);
    isset($options['inline'])  ?  : $options['inline']   = true;//当mineType为浏览器不能播放的内容是inline将失效,文件会被下载,而不是浏览器打开
    isset($options['mimeType'])?  : $options['mimeType'] = 'application/octet-stream';//当mineType为application/octet-stream时文件会被自动下载而不会用浏览器打开
    $response->sendStreamAsFile($fp,$name,$options);
}


/**输出二进制流,支持断点续传
 * @param string $file 文件路径
 * @param string $type 输出内容类型
 */
public function video3($file = '',$type = 'video/mp4')
{
        ob_clean();
        $response = \Yii::$app->response;
        $response->format = Response::FORMAT_RAW;//必须,否则内容将以默认content-type输出,text/html
        $header =  $response->headers;
        if ($header->has('Content-Type')) {
            $header->set("Content-Type",$type);
        } else {
            $header->set("Content-Type",$type);
        }
        $header->set("Accept-Ranges",'bytes');
        $size = filesize($file);
        if(isset($_SERVER['HTTP_RANGE'])) {
            $response->SetstatusCode(206);
            list($name, $range) = explode("=", $_SERVER['HTTP_RANGE']);
            list($begin, $end)  = explode("-", $range);
            if($end == 0 || !$end)  {
                $end = $size - 1;
            }
        } else {
            $header->set('Content-Range', "bytes */$size");
            $begin = 0; $end = $size - 1;
        }
        $len   = $end-$begin+1;
        $range = "bytes ".$begin-$end/$size;
        $header->set("Content-Length",$len);
        $header->set("Content-Disposition","filename=".basename($file));
        $header->set("Content-Range",$range);
        $response->send();
        $fp = fopen($file, 'rb');
        fseek($fp, $begin);
        while(!feof($fp)) {
            $p = min(1024, $end - $begin + 1);
            $begin += $p;
            echo fread($fp, $p);
            flush();
        }
        fclose($fp);
}

/**
 * @param  $file
 * 原生PHP实现
 * 视频播放2 (可以快进)
 */
public function GetMp4File($file) 
{
    ob_clean();
    $size = filesize($file);
    header("Content-type: video/mp4");
    header("Accept-Ranges: bytes");
    header("Connection: Keep-Alive");
    if(isset($_SERVER['HTTP_RANGE'])){
        header("HTTP/1.1 206 Partial Content");//断点续传
        list($name, $range) = explode("=", $_SERVER['HTTP_RANGE']);
        list($begin,$end) = explode("-", $range);
        if($end == 0 || !$end){
            $end = $size - 1;
        }
    }else {
        $begin = 0; $end = $size - 1;
    }
    header("Content-Length: " . ($end - $begin + 1));
    header("Content-Disposition: filename=".basename($file));
    header("Content-Range: bytes ".$begin."-".$end."/".$size);
    $fp = fopen($file, 'rb');
    if (!$fp) {
        throwException('文件不存在');
    }
    fseek($fp, $begin);
    while(!feof($fp)) {
        $p = min(1024, $end - $begin + 1);
        $begin += $p;
        echo fread($fp, $p);
    }
    fclose($fp);
}
发布了12 篇原创文章 · 获赞 4 · 访问量 4347

猜你喜欢

转载自blog.csdn.net/u013083541/article/details/86011245