ffmpeg 方法封装-PHP

ffmpeg公用方法封装-PHP

拼接视频

      /**
     * 拼接视频
     *  视频地址为 url
     * @param $url
     * @param string $object_name
     * @return array
     * @author: xiao
     * @Date: 2021/4/15  14:04
     */
    public function videoConcatUrl($url,$object_name = '')
    {
        if (!is_array($url) || empty($url)){
            $this->data['code'] = -1;
            $this->data['msg'] = 'url 非数组或为空';
            return $this->data;
        }
        $str = '';
        foreach ($url as $key => $val){
            $str .= "file '".$val."'  \r\n";
        }
        //写入文件
        $temp_txt_name = 'temp_video_file_'.rand(1000,9999).'.txt';
        $fp = @fopen($this->video_path.$temp_txt_name,"w+");
        @fputs($fp,$str);
        @fclose();
        if (!file_exists($this->video_path.$temp_txt_name)){
            $this->data['code'] = -1;
            $this->data['msg']  = 'url文件写入失败';
            return $this->data;
        }
        //执行拼接命令
        # -safe 0 -protocol_whitelist "file,http,https,rtp,udp,tcp,tls"
        $ffmpeg_exec = '/usr/local/ffmpeg/bin/ffmpeg -f concat -safe 0  -i '.$this->video_path.$temp_txt_name.' -c copy '.$this->video_path.$object_name.'';
        exec($ffmpeg_exec,$output,$code);
        if ($code != 0){
            $this->data['code'] = -1;
            $this->data['msg'] = '视频拼接失败';
            return $this->data;
        }
        //删除临时文件
        if (file_exists($this->video_path.$temp_txt_name)){
            @unlink($this->video_path.$temp_txt_name);
        }
        $this->data['data'] = [
            'video_url'  =>  $this->video_path.$object_name
        ];
        return $this->data;
    }

添加字幕(硬压字幕)

    //主要颜色
    private $primaryColour = ['FFFFFF'];
    //边框颜色
    private $OutlineColour = '000000';
    //字体
    private $fontName = ["Muyao\-Softbrush","YRDZST"];

     /**
     * 字幕添加
     * @param $video_url
     * @param $video_srt_url
     * @param $object_name
     * @param string $ratio 分辨率
     * @return array
     * @author: xiao
     * @Date: 2021/4/15  14:41
     */
    public function videoSubtitles($video_url,$video_srt_url,$object_name,$ratio='720x1280')
    {
        if (empty($video_url) || empty($video_srt_url) || empty($object_name)){
            $this->data['code'] = -1;
            $this->data['msg'] = '参数为空';
            return $this->data;
        }
        //下载字幕文件到本地
        $file = file_get_contents($video_srt_url);
        $srt_name = date('YmdHis').'_'.rand(1000,9999).'_'.'srt'.'.srt';
        $srt_path = $this->video_path.$srt_name;
        file_put_contents($srt_path,$file);

        /**
         * 设置字幕样式
         */
        //字体
        $font_name = $this->fontName[rand(0,(count($this->fontName)-1))];
        $out_line_color = $this->OutlineColour;
        //主要颜色
        $primary_color = $this->primaryColour[rand(0,count($this->primaryColour)-1)];
        $primary_color = '&H'.$primary_color;
        $out_line_color = '&H'.$out_line_color;
        $margin_v = rand(70,85);
        $font_size = rand(12,13);

        //根据分辨率判断视频是否为横屏
        if ($ratio == '1280x720' || $ratio == '1920x1080'){
            \Log::error('come in ratio');
            $font_size = rand(18,21);
            $margin_v = rand(5,15);
        }

        $force_style='Fontname='.$font_name.'\,Fontsize='.$font_size.'\,MarginV='.$margin_v.'\,PrimaryColour='.$primary_color.'\,OutlineColour='.$out_line_color.'\,Alignment=2';
        $ffmpeg_exec = "/usr/local/ffmpeg/bin/ffmpeg  -i ".$video_url." -threads 5 -preset ultrafast  -vf subtitles=".$srt_path.":force_style='".$force_style."'    -y ".$this->video_path.$object_name." ";
        exec($ffmpeg_exec,$output,$code);
        if ($code != 0){
            $this->data['code'] = -1;
            $this->data['msg'] = '字幕插入失败';
            return $this->data;
        }
        $this->data['data'] = [
            'video_url'     => $this->video_path.$object_name
        ];

        if (file_exists($srt_path)){
            @unlink($srt_path);
        }
        return $this->data;
    }

音频插入

     /**
     * 音频插入
     * @param $video_url
     * @param $audio_url
     * @param $object_name
     * @return array
     * @author: xiao
     * @Date: 2021/4/15  16:11
     */
    public function audioInsert($video_url,$audio_url,$object_name)
    {
        if (empty($video_url) || empty($audio_url) || empty($object_name)){
            $this->data['code'] = -1;
            $this->data['msg'] = '参数为空';
            return $this->data;
        }
        //消除原有视频的音频
        $temp_name = 'temp_'.rand(1000,9999).'.mp4';
        //临时文件
        $temp_path =  public_path() . '/upload/' . $temp_name;
        $clear_audio_exec = '/usr/local/ffmpeg/bin/ffmpeg -i '.$video_url.' -vcodec copy -an  '.$temp_path.'';
        exec($clear_audio_exec,$out,$audio_code);
        if ($audio_code != 0 ){
            $this->data['code'] = -1;
            $this->data['msg'] = '消除音频失败';
            return $this->data;
        }
        # -safe 0 -protocol_whitelist
        $merge_video_exec = '/usr/local/ffmpeg/bin/ffmpeg -i '.$temp_path.' -i '.$audio_url.'  -vcodec copy -acodec copy '.$this->video_path.$object_name.' ';
        exec($merge_video_exec,$o,$merge_code);
        if ($merge_code != 0){
            $this->data['code'] = -1;
            $this->data['msg'] = '音频插入失败';
            return $this->data;
        }

        $this->data['data'] = [
            'video_url'     => $this->video_path.$object_name
        ];
        return $this->data;
    }

压缩视频

    /**
     * 压缩视频
     * @param $video_url
     * @param string $object_name
     * @param string $code_rate
     * @param string $ratio 码率
     * @return array
     * @author: xiao
     * @Date: 2021/4/27  14:49
     */
    public function videoCompress($video_url,$object_name = '',$code_rate = '500k',$ratio='1280x720' )
    {
        if (empty($video_url)){
            $this->data['code'] = -1;
            $this->data['msg'] = '参数为空';
            return $this->data;
        }
//        $ffmpeg_exec = '/usr/local/ffmpeg/bin/ffmpeg -i '.$video_url.' -threads 2 -preset ultrafast -b:v '.$code_rate.' -s '.$width.'x'.$height.' '.$this->video_path.$object_name.' ';
        $ffmpeg_exec = '/usr/local/ffmpeg/bin/ffmpeg -i '.$video_url.' -threads 2 -preset ultrafast -b:v '.$code_rate.' '.$this->video_path.$object_name.' ';
        exec($ffmpeg_exec,$o,$code);

        if ($code != 0){
            $this->data['code'] = -1;
            $this->data['msg'] = '视频压缩失败';
            return $this->data;
        }
        $this->data['data'] = [
            'video_url'     => $this->video_path.$object_name
        ];
        return $this->data;
    }

设置关键帧(主要用于视频拼接中间有卡顿现象)

     /**
     * 设置关键帧
     * @param $video_url
     * @param $object_name
     * @return array
     * @author: xiao
     * @Date: 2021/4/27  17:05
     */
    public function videoSetKey($video_url, $object_name)
    {
        $ffmpeg_exec = '/usr/local/ffmpeg/bin/ffmpeg -i '.$video_url.' -threads 2 -preset ultrafast -g 1 -keyint_min 2  '.$this->video_path.$object_name.' ';
        exec($ffmpeg_exec,$o,$code);

        if ($code != 0){
            $this->data['code'] = -1;
            $this->data['msg'] = '关键帧设置失败';
            return $this->data;
        }
        $this->data['data'] = [
            'video_url'     => $this->video_path.$object_name
        ];
        return $this->data;
    }

获取视频信息

     /**
     * 获取视频信息
     * @param $video_url
     * @return array|string[]
     * @author: xiao
     * @Date: 2021/6/10  15:54
     */
    public function getVideoInfo($video_url)
    {
        $arr = [];
        $ffmpeg_exec = '/usr/local/ffmpeg/bin/ffprobe -i '.$video_url.' -preset ultrafast  2>&1';
//        $video_info = shell_exec($ffmpeg_exec);
        exec($ffmpeg_exec,$info,$code);

        if (empty($info)){
            $this->data['code'] = -1;
            $this->data['msg'] = '获取视频信息失败';
            return $this->data;
        }

        /**
         * 获取视频信息开始
         */
        //分辨率
        if (isset($info[18])){
            $temp_ratio = explode(',',$info[18]);
            $arr['ratio'] = isset($temp_ratio[2])?trim($temp_ratio[2]):'1280x720';
        }

        return $arr;
    }

你可能感兴趣的:(ffmpeg 方法封装-PHP)