1. 程式人生 > >linux系統,CentOS7.2安裝ffmpeg擴充套件,PHP用FFmpeg擷取視訊第一幀作為視訊封面,並給圖片新增播放視訊按鈕

linux系統,CentOS7.2安裝ffmpeg擴充套件,PHP用FFmpeg擷取視訊第一幀作為視訊封面,並給圖片新增播放視訊按鈕

最近做公司的專案中,有使用者上傳視訊,後臺這邊接收視訊並上傳,獲取視訊第一幀作為視訊封面的功能,在網上查找了好多資料,並且安裝 了ffmpeg-php的PHP擴充套件,由於版本問題,安裝好幾個版本都不成功,最後放棄安裝擴充套件,後來執行程式碼發現不用安裝那個擴充套件也能實現截圖並上傳的功能,所以要擷取視屏第一幀,只需要安裝FFmpeg和yasm即可,建議先安裝yasm,再安裝FFmpeg,我這邊是一邊安裝一邊排錯的,所以我先安裝的實FFmpeg。擷取第一幀的PHP程式碼會在後面詳細列出。

1: 安裝 ffmpeg

ffmpeg的下載連結  http://ffmpeg.org/download.html

解壓安裝包

tar -jxvf ffmpeg-x.x.tar.bz2

進入目錄

cd ffmpeg-x.x

編譯安裝

./configure --enable-shared && make && make install

報錯:

nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the

[email protected] mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.

報這個錯說明沒有安裝yasm,所以要先去安裝yasm
http://yasm.tortall.net/Download.html 下載yasm,上傳到伺服器的local目錄中

解壓:
tar -zxvf yasm.tar.gz

進入解壓目錄安裝: 

cd yasm-1.3.0/
./configure
make
make install

安裝成功以後進入FFmpeg目錄進行安裝,可能需要3,4分鐘時間

如果編譯報錯,請加選項(報錯會提示選項內容)./configure --enable-shared  --選項 && make && make install

安裝完成之後 執行 ffmpeg -version

如果出現ffmpeg: error while loading shared libraries: libavdevice.so.57: cannot open shared object file: No such file or directory

編輯/etc/ld.so.conf檔案中的:include ld.so.conf.d/*.conf 這行下面加入如下內容
/usr/local/ffmpeg-4.0.2
儲存退出後執行ldconfig命令  

檢驗安裝成功與否,輸入 ffmpeg檢驗,出現如下圖內容,即安裝成功

2.修改php.ini中的禁止函式

因為PHP程式碼中會用到exec或者system,直接刪除,還有shell_exc,proc_open,peoc_get_status

cd /usr/local/php/etc

vi php.ini

 修改完成後儲存退出重啟伺服器

service php-fpm restart

看到如下,說明重啟成功
Gracefully shutting down php-fpm .. done
Starting php-fpm  done
 

3.PHP程式碼篇

我用的框架是tp5的框架,程式碼如下,因為視訊和圖片一樣都是檔案,所以接收方式和圖片的接收方式一樣,上傳也是一樣,直接調取框架自帶的上傳類:

$video = request()->file('video');//接收video檔案
if(!empty($video)){
            $info = $video->move(ROOT_PATH . 'public' . DS . 'uploads');
            if($info) {
                $videoName = $info->getSaveName();
                $source = '/uploads/' .$videoName;//原視訊名稱

                $dir = ROOT_PATH . 'public' . DS . 'uploads/';//上傳圖片路徑
                $fileName = str_replace('.mp4','.jpg',$videoName);//圖片名稱
                $video_filePath = $dir.$videoName;//視訊路徑
                //用ffmpeg擷取視訊第一幀,並上傳儲存在和視訊一樣的路徑下
                //使用-ss引數,可以從指定的時間開始處理轉換任務後面是1代表從第一秒開始
                //-s引數,後面是圖片的寬高,這個可以不用寫,因為有橫屏的或者豎屏的視訊,不能固定
                $str = "ffmpeg -i ".$video_filePath." -y -f mjpeg -ss 1 -t 0.001 -s 348*470 ".$dir.$fileName;
                exec($str,$out,$status);
                $datas['video'] = $source;
                $datas['picture'] = '/uploads/' . $fileName;

                $image = \think\Image::open('.'.$datas['picture']);
                //呼叫tp5的圖片處理類,獲取圖片寬高,並給封面圖片新增播放按鈕
                $width = $image->width();
                // 返回圖片的高度
                $height = $image->height();
                $datas['width'] = $width;
                $datas['height'] = $height;
                $water = $dir.'water.png';//播放按鈕
                $image->water($water,\think\Image::WATER_NORTHWEST,50)->save('.'.$datas['picture']);
            }
        }
或者將擷取視訊第一幀的功能封裝一個方法,可以呼叫
/**
 * 擷取視訊第一幀
 *
 * @param  $file   視訊檔案
 * @param  $time    第幾幀
 * @param  $dir     臨時目錄
 * @param  $size    截圖尺寸
 */
public function getVideoCover($file,$time,$dir,$size) {
    $time = $time ? $time : '1';      //預設擷取第一秒第一幀
    $size = $size ? $size : '348*470';
    $fileName = getImgName();

    //臨時視訊路徑,生成截圖後刪除
    $tempfiles = $dir.$fileName.'.mp4';
    $bool = move_uploaded_file($file, $tempfiles);
    $str = "ffmpeg -i ".$tempfiles." -y -f mjpeg -ss ".$time." -t 0.001 -s $size ".$dir.$fileName.'.jpg';
    exec($str,$out,$status);
    return $fileName;
}

成功以後進行資料庫資料的儲存,結束,就是這樣嘍