php如何截取出視頻中的指定幀做爲圖片

php如何截取出視頻中的指定幀做爲圖片

1、總結

一句話總結:截取視頻指定幀爲圖片,php ffmpeg擴展已經完美實現,而且php ffmpeg是開源的

 

 

2、php如何截取出視頻中的指定幀做爲圖片

截取視頻指定幀爲圖片,php ffmpeg擴展已經完美實現:php

 
1
2
3
4
5
6
$movie = new ffmpeg_movie( $video_filePath );
$ff_frame = $movie ->getFrame(1);
$gd_image = $ff_frame ->toGDImage();
$img = "./test.jpg" ;
imagejpeg( $gd_image , $img );
imagedestroy( $gd_image );

然而問題來了,智能手機拍攝的視頻,因爲拍攝方向不一樣,視頻會被旋轉,並帶上meta信息rotate,當你相對視頻截取frame圖片的時候,若是有rotate信息的視頻,frame也是旋轉的,所以你須要將截取的圖片相應的旋轉。html

而後php ffmpeg擴展並沒有法獲知rotation信息(php ffmpeg擴展文檔),但能夠經過ffmpeg命令行獲取:git

/usr/local/ffmpeg/bin/ffprobe test.mp4 -show_streams  | grep rotate
用php簡單封裝下以下:
github

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function get_video_orientation( $video_path ) {
   $cmd = "/usr/local/ffmpeg/bin/ffprobe " . $video_path . " -show_streams 2>/dev/null" ;
   $result = shell_exec( $cmd );
   
   $orientation = 0;
   if ( strpos ( $result , 'TAG:rotate' ) !== FALSE) {
     $result = explode ( "\n" , $result );
     foreach ( $result as $line ) {
       if ( strpos ( $line , 'TAG:rotate' ) !== FALSE) {
         $stream_info = explode ( "=" , $line );
         $orientation = $stream_info [1];
       }
     }
   }
   return $orientation ;
}

使用imagerotate()函數就能夠旋轉截圖:shell

 
1
2
3
4
5
6
7
8
9
$movie = new ffmpeg_movie( $video_filePath );
$frame = $movie ->getFrame(1);
$gd = $frame ->toGDImage();
if ( $orientation = $this ->get_video_orientation( $video_filePath )) {
   $gd = imagerotate( $gd , 360- $orientation , 0);
}
$img = "./test.jpg" ;
imagejpeg( $gd , $img );
imagedestroy( $gd_image );

最後還有一個麻煩事,不是全部的播放器和瀏覽器均可對video識別orientation並自動rotate,若是你想對視頻進行旋轉,可經過ffmpeg命令解決:centos

/usr/local/ffmpeg/bin/ffmpeg -i input.mp4 -vf 'transpose=3' -metadata:s:v:0 rotate=0 數組

 

參考:php截取視頻指定幀爲圖片_php技巧_腳本之家
https://www.jb51.net/article/84359.htm
瀏覽器

 

 

3、ffmpeg-php擴展

php視頻縮略圖,較經常使用的是ffmpeg-phpmarkdown

1: 安裝 ffmpegphp7

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

解壓安裝包

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

進入目錄

cd ffmpeg-x.x

編譯安裝

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

安裝完成以後 執行 ffmpeg -version

若是可以出現相似下列信息,說明ffmpeg安裝成功。

ffmpeg version 2.5.11 Copyright (c) 2000-2016 the FFmpeg developers
built on Apr 17 2017 16:47:15 with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-11)
configuration: --enable-shared
libavutil      54. 15.100 / 54. 15.100
libavcodec     56. 13.100 / 56. 13.100
libavformat    56. 15.102 / 56. 15.102
libavdevice    56.  3.100 / 56.  3.100
libavfilter     5.  2.103 /  5.  2.103
libswscale      3.  1.101 /  3.  1.101
libswresample   1.  1.100 /  1.  1.100

 2 安裝ffmpeg-php

官方的下載連接

https://sourceforge.net/projects/ffmpeg-php/files/ffmpeg-php/

官方版本已經好久好久不更新了,我在centos 7 + php5.6&php7.1   centos6.5+php5  試了都不行。在configure完 make的時候會報錯。

後來在github上找了一個版本。在centos7.2+php5.5.6 上編譯安裝成功 (centos7 + php7.1仍是不行)

地址:    git clone https://github.com/tony2001/ffmpeg-php.git 

也能夠訪問個人百度雲盤進行下載

https://pan.baidu.com/s/1skQTVlj

進入 ffmpeg-php目錄 進行編譯擴展

/usr/local/php/bin/phpize   

./configure --with-php-config=/usr/local/php/bin/php-config

make && make install

注意(若是make以後出現錯誤,那就是ffmpeg-php版本的問題,別再折騰了,換版本吧(或者下降php版本試試))。

在php的配置文件 php.ini中 添加  

extension=ffmpeg.so

重啓php。在 phpinfo()中查看有無ffmpeg信息。

有的話就OK

或者執行 

/usr/local/php/bin/php -i |grep ffmpeg

 要是有輸出的話OK

 

參考:ffmpeg-php擴展 - 思此狂 - 博客園
https://www.cnblogs.com/jkklearn/p/6737467.html

 

 
 

 

2、PHP的ffmpeg使用

由於項目需求,同事寫了一個ffmpeg的類,可是由於臨時來了一個其餘的項目,因此這個未完成的類就交給我來完成,因此我就把這個類的完成過程記錄一下

<?php include('FFmpegSupport.php'); //http://blog.csdn.net/doublefi123/article/details/24325159 基本用法 class FFmpegManage { /** * ffmpeg默認結構:ffmpeg [全局選項] [輸入文件選項] -i (輸入文件路徑) [輸出文件選項] (輸出文件路徑) * 其中[]括號裏的是可選,()括號裏的是必選的 */ private $ExecString = 'ffmpeg.exe '; //命令語句 private $GlobalOptions = ''; //全局選項 private $ErrMessage = array(); //錯誤信息 private $InputFileOptionsString = ''; //輸入文件選項 private $InputFileOptions = array(); //輸入文件選項數組 private $InputFilePath = array(); //輸入文件路徑 private $OutFileOptions = ''; //輸出文件選項 private $OutFilePath = ''; //輸出文件路徑 private $OutFileTybe = ''; //輸入文件的後綴名 //可配置參數 private $config = array( 'startTime'=>1, //文件開始時間 'fmt'=>1, //文件格式 'codec'=>1, //解碼器 'audioCodec'=>1, //音頻解碼器 'bitRate'=>1, //比特率 'sampleRate'=>1, //採樣率 'audioChannels'=>1, //聲道數 'endTime'=>1, //結束時間 'timeLength'=>1, //文件時間長度 ); /** $Config = array( 'inputFilePath' => array(), //輸入路徑(不能爲空) 'outputFilePath' => '', //輸出路徑(不能爲空) //輸入文件選項(爲空時不執行) 'fileOption' =>array( 'studyTime' => '', //文件開始時間 'fmt' => '', //文件格式 'codec' => '', //解碼器 'audioCodec' => '', //音頻解碼器 'bitRate' => '', //比特率 'sampleRate' => '', //採樣率 'audioChannels' => '', //聲道數 'endTime' => '', //結束時間 'timeLength' => '', //文件時間長度 ), ); **/ public function setConfig($config){ @$fileOption = $config['fileOption']; @$inputFilePath = $config['inputFilePath']; @$outputFilePath = $config['outputFilePath']; //判斷是否有輸入或輸出路徑 if(empty($inputFilePath) && empty($outputFilePath)){ $this->setErrMessage('inputFilePath and outputFilePath is null'); } //獲取輸入文件路徑 if(!is_array($inputFilePath)){ $filePathArray = explode('+',$inputFilePath); }else{ $filePathArray = $inputFilePath; } if(!empty($fileOption)) //遍歷輸入文件路徑 foreach($filePathArray as $filePath){ //將配置信息進行遍歷 foreach($fileOption as $key => $value){ //判斷配置信息是否正確,若是不正確跳過 if(!empty($this->config[$key]) && !empty($value)){ //加載配置 $this->$key($value); } } //判斷文件是否能進行寫入 if( file_exists( $filePath ) ){ //將輸入配置與輸入文件進行關聯 $this->InputFilePath[] = '-i ' . $filePath . ' '; $this->InputFileOptions[] = '-i ' . $filePath . ' '.$this->InputFileOptionsString; $this->InputFileOptionsString = ''; }else{ $this->setErrMessage('Input File is not Exist!!'); } } $this->OutFileTybe = substr( $outputFilePath , -4 ); $this->OutFilePath = $outputFilePath . ' '; return $this; } /** * 設置ffmpeg執行時對全部選項都回答yes,例文件已存在,要覆蓋的時候程序會等待回答yes or on ,有時候不添加會出錯 * @return $this */ public function setAnswerAllYes(){ $this->GlobalOptions .= ' -y '; return $this; } ////////////////////////////配置信息載入//////////////////////////// /** * 強制設定文件的格式,須要使用ffmpeg當前版本支持的名稱(缺省使用擴展名稱) * @param $_fileType String 文件類型 */ private function fmt( $_fileType ){ empty( $_fileType ) ? $this->setErrMessage( 'File Type is empty!!'): $this->InputFileOptionsString .= '-f ' . $_fileType . ' '; } /** * 設置輸入文件的起始時間點,在此時間點開始讀取數據 , * @param $_time int 起始時間(單位:秒s) */ private function startTime( $_time ){ $_time = (int)$_time; empty($_time) && ($_time < 0) ? $this->setErrMessage( " $_time must be biger than 0"): $this->InputFileOptionsString .= '-ss ' . $_time . ' '; } /** * 指定解碼器,需輸入此版本支持的解碼器 * @param $_codecName */ private function codec( $_codecName ){ empty( \FFmpegSupport::$InputProtocolsArray[ $_codecName ] ) && empty( \FFmpegSupport::$OutputProtocolsArray[ $_codecName ] ) ? $this->setErrMessage( 'This versions ffmpeg is not support this codec!!' ): $this->InputFileOptionsString .= '-c ' . $_codecName . ' '; } /** *指定音頻解碼器 * @param $_audioCodecName String 解碼器名稱,需輸入此版本ffmpeg支持的解碼器 */ private function audioCodec( $_audioCodecName ){ empty( \FFmpegSupport::$InputProtocolsArray[ $_audioCodecName ] ) && empty( \FFmpegSupport::$OutputProtocolsArray[ $_audioCodecName ] ) ? $this->setErrMessage( 'This versions ffmpeg is not support this codec!!' ): $this->InputFileOptionsString .= '-acodec ' . $_audioCodecName . ' '; } /** * 設置音頻流的採樣率 * 能夠使用的採樣率 * 8,000 Hz - 電話所用採樣率, 對於人的說話已經足夠 * 11,025 Hz * 22,050 Hz - 無線電廣播所用採樣率 * 32,000 Hz - miniDV 數碼視頻 camcorder、DAT (LP mode)所用採樣率 * 44,100 Hz - 音頻 CD, 也經常使用於 MPEG-1 音頻(VCD, SVCD, MP3)所用採樣率 * 47,250 Hz - 商用 PCM 錄音機所用採樣率 * 48,000 Hz - miniDV、數字電視、DVD、DAT、電影和專業音頻所用的數字聲音所用採樣率 * 50,000 Hz - 商用數字錄音機所用採樣率 * 96,000 或者 192,000 Hz - DVD-Audio、一些 LPCM DVD 音軌、BD-ROM(藍光盤)音軌、和 HD-DVD (高清晰度 DVD)音軌所用所用採樣率 * 2.8224 MHz - Direct Stream Digital 的 1 位 sigma-delta modulation 過程所用採樣率。 * @param $_audioSampleRate int 音頻採樣率,單位Hz */ private function sampleRate( $_audioSampleRate ){ $_audioSampleRate < 1 ? $this->setErrMessage( 'AudioSampleRate can not smaller than 0!!'): $this->InputFileOptionsString .= '-ar ' . $_audioSampleRate . ' '; } /** * 設置音頻流的比特率 * @param $_audioBitRate int 音頻比特率,單位bps */ private function bitRate( $_audioBitRate ){ $_audioBitRate < 1 ? $this->setErrMessage( 'BitRate can not smaller than 0!!'): $this->InputFileOptionsString .= '-ab ' . $_audioBitRate . ' '; } /** * 設置音頻流的聲道數目 * @param $_channels int 通道數目整數,大於等於1 */ private function audioChannels( $_channels ){ $_channels<1 ? $this->setErrMessage( 'Channels count must be biger than 0!!'): $this->InputFileOptionsString .= '-ac ' . $_channels . ' '; } /** * 設置終止時間點 * @param $_endTimePoint String 終止時間點 hh:mm:ss */ private function endTime( $_endTimePoint ){ $_endTimePoint = trim( $_endTimePoint ); $_endTimePoint < 0 ? $this->setErrMessage( 'Time can not be less than 0!!'): $this->OutFileOptions .= '-to ' . $_endTimePoint . ' '; } /** * 設置時間長度 * @param $_time String 時間長度 hh:mm:ss * @return $this Class 此類 */ private function timeLength( $_timeLen ){ $_timeLen = trim( $_timeLen ); $_timeLen < 0 ? $this->setErrMessage( 'Time can not be less than 0!!'): $this->OutFileOptions .= '-t ' . $_timeLen . ' '; } ////////////////////////////處理音頻//////////////////////////// /** * 修改音頻的音量 * @param $_volume int 你須要設置的音頻音量 * @return $this Class 此類 */ public function changeAudioVolume( $_volume ){ ( (int)$_volume < 10 )? $this->setErrMessage( 'Volume can not smaller than 10!!'): $this->OutFileOptions .= '-vol ' . $_volume . ' '; return $this; } /** * 合併多音軌 * @return $this Class 此類 */ public function audioComplex( ){ if( sizeof( $this->InputFilePath ) < 2 ){ $this->setErrMessage( 'In this Complex function, The number of input files can not smaller than 2!!'); }elseif( $this->OutFileTybe == 'amr' ){ $this->setErrMessage( 'The outfile can not be amr type!!'); }else{ $this->OutFileOptions .= '-filter_complex join=inputs=2: '; } return $this; } /** * 多音軌合併(好比將BGM與人聲結合) * @return $this */ public function audioAmix(){ count($this->InputFilePath) < 2 ? $this->setErrMessage('File number is less than 2'): $this->OutFileOptions .= '-filter_complex amix=inputs=2:duration=first:dropout_transition=2 '; return $this; } /** * 拼接兩個音頻文件 * @return $this Class 此類 */ public function audioJoin( ){ ( sizeof( $this->InputFilePath ) < 2 )? $this->setErrMessage( 'The number of input files can not smaller than 2!!' ): $this->OutFileOptions .= '-filter_complex acrossfade=d=10:c1=exp:c2=exp '; return $this; } /** * 改變音頻的速率 * @param $_speed int 你須要設置的速率 分數格式 7/10 * @return $this Class 此類 */ public function changeAudioSpeed( $_speed ){ $_speed = trim( $_speed ); ( $_speed <= 0 && empty($_speed))? $this->ErrMessage[] = 'The slowdown speed can not smaller than 0 or =0!!': $this->OutFileOptions .= '-filter:a atempo=' . $_speed . ' '; return $this; } /** * 改變原音頻的聲調,改變聲音 * @param $_rateHz rateHz */ public function audioChangeVoice( $_rateHz ){ $_rateHz = trim( $_rateHz ); ( $_rateHz < 100 )? $this->ErrMessage[] = 'The rate size cannot be lower than 100Hz!!': $this->OutFileOptions .= '-filter_complex asetrate=r=' . $_rateHz . ' '; return $this; } ////////////////////////////處理視頻//////////////////////////// /** * 裁剪視頻 * @param $_Property Array 包括如下元素:'operation':操做,'width':要裁剪的寬,'height':要裁剪的高,'offestX':水平偏移,'offestY':垂直偏移 * @return $this */ public function videoCrop( $_Property ){ if(empty($_Property) && !is_array($_Property)){ $this->setErrMessage('The parameter is incorrect'); }else { switch ($_Property['operation']) { case 'normal'://普通操做,即要輸入裁剪的寬高和開始裁剪的xy值 $this->OutFileOptions .= '-filter_complex crop=w=' . $_Property['width'] . ':h=' . $_Property['height'] . ':x=' . $_Property['offestX'] . ':y=' . $_Property['offestY'] . ' '; break; case 'centerWH'://從中心開始裁剪多寬和多高,須要輸入裁剪的寬高值 $this->OutFileOptions .= '-filter_complex crop=' . $_Property['width'] . ':' . $_Property['height'] . ' '; break; case 'center'://從中心開始裁剪,裁剪的寬高值由程序控制 $this->OutFileOptions .= '-filter_complex crop=out_w=in_h crop=in_h '; break; case 'boder'://據上下多少,左右多少進行裁剪,需輸入裁剪的寬高值,此時寬高值爲:距離邊界多少像素值 $this->OutFileOptions .= '-filter_complex crop="in_w-2 ' . $_Property['width'] . ':in_h-2 ' . $_Property['height'] . '" '; break; case 'shake': $this->OutFileOptions .= "-filter_complex crop='in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2+((in_h-out_h)/2)*sin(n/7)' "; break; } } return $this; } /** * 在視頻上畫網格 * @param $_boxWidthCount int 水平多少個格, 默認3 * @param $_boxHeightCount int 垂直多少個格,默認3 * @param $_thickness int 網格線的寬度,默認2 * @param $_color String 網格顏色名稱,默認yellow,詳解:https://xdsnet.gitbooks.io/other-doc-cn-ffmpeg/content/ffmpeg-doc-cn-37.html * @param $_transparent 網格透明度,0~1 ,支持一位小數,默認1 * @return $this Class 此類 */ public function videoDrawGrid( $_boxWidthCount = "" , $_boxHeightCount ="" , $_thickness ="" , $_color ="" , $_transparent =""){ if( empty( $_color ) ){ $_color = 'yellow'; } if( empty( $_transparent ) ){ $_transparent = 1; } if( empty( $_thickness ) ){ $_thickness = 2; } if( empty( $_boxWidthCount ) ){ $_boxWidthCount = 3; } if( empty( $_boxHeightCount ) ){ $_boxHeightCount = 3; } $this->OutFileOptions .= '-filter_complex drawgrid=width='.$_boxWidthCount . ':height=' . $_boxHeightCount . ':thickness=' . $_thickness . ':color=' . $_color . '@' . $_transparent . ' '; return $this; } /** * 水平翻轉視頻 * @return $this */ public function videoHFlip(){ $this->OutFileOptions .= '-vf "hflip" '; return $this; } /** * 垂直翻轉視頻 * @return $this */ public function videoVFlip(){ $this->OutFileOptions .= '-vf "vflip" '; return $this; } /** * 旋轉視頻 * @param $_dir int 角度(單位:90度) * @return $this Class 此類 */ public function videoTranspose( $_dir ){ if(empty($_dir)){ $_dir = 90; } $this->OutFileOptions .= '-filter_complex transpose=dir=' . $_dir . ' '; return $this; } /** * 拼接多個視頻 * 須要php的ffmpeg擴展 * @return $this Class 此類 */ public function videoConcat(){ if(empty(get_extension_funcs('ffmpeg'))){ $this->setErrMessage('ffmpeg Extension does not exist'); }else{ if( empty( $this->InputFilePath ) ){ $this->ErrMessage[] = 'Line 583 , The inputFiles count empty!!'; } if( sizeof( $this->InputFilePath ) < 2 ){ $this->ErrMessage[] = 'Line 586 , The inputFiles count must be bigger than 1!!'; } $biggerWidth = 0; $biggerHeight = 0; for( $i = 0 ; $i < sizeof( $this->InputFilePath ) ; $i++ ){ $ffmpeg = new \ffmpeg_movie( $this->InputFilePath[$i] ); if( $ffmpeg->getFrameWidth() > $biggerWidth ){ $biggerWidth = $ffmpeg->getFrameWidth(); } if( $ffmpeg->getFrameHeight() > $biggerHeight ){ $biggerWidth = $ffmpeg->getFrameHeight(); } } for( $i = 0 ; $i < sizeof( $this->InputFilePath ) ; $i++ ){ $ffmpeg = new \ffmpeg_movie( $this->InputFilePath[$i] ); if( $ffmpeg->getFrameHeight() == $biggerHeight && $ffmpeg->getFrameWidth() == $biggerWidth ){ continue; }else{ $heightDifference = $ffmpeg->getFrameHeight() - $biggerHeight; $widthDifference = $ffmpeg->getFrameWidth() - $biggerWidth; if( $heightDifference !== 0 ){ $heightDifference = $heightDifference/2; } if( $widthDifference !== 0 ){ $widthDifference = $widthDifference/2; } $savePath = substr( $this->InputFilePath[$i] , 0 , strrpos( $this->InputFilePath[$i] , '.' , 0 ) ) . '1' . substr( $this->InputFilePath[$i] , strrpos( $this->InputFilePath[$i] , '.' , 0 ) + 1 ); $ffmpegStr = 'ffmpeg -y -i ' . $this->InputFilePath[$i] . ' -vf pad=' . $biggerWidth . ':' . $biggerHeight . ':' . $widthDifference . ':' . $heightDifference . ':black ' . $savePath; $this->execute( $ffmpegStr ); $this->InputFilePath[$i] = $savePath; } } $this->OutFileOptions .= "-filter_complex concat=n=" . sizeof( $this->InputFilePath ) . ' '; } return $this; } /** * 添加水印,水印圖片爲png圖片,透明度用繪圖軟件調整 * @param $_operation string 操做類型,有normal(正常:需輸入x,y偏移值),lefttop(左上角),righttop(右上角),leftbottom(左下角),rightbottom(右下角),center(中心) * @param $_offestX (x偏移值) * @param $_offestY (y偏移值) * @return $this Class 此類 */ public function videoOverlay( $_operation , $_offestX , $_offestY ){ switch( $_operation ){ case 'normal': $offestX = $_offestX; $offestY = $_offestY; break; case 'lefttop': $offestX = 0; $offestY = 0; break; case 'righttop': $offestX = 'main_w-overlay_w'; $offestY = 0; break; case 'leftbottom': $offestX = 'main_w-overlay_w'; $offestY = 'main_h-overlay_h'; break; case 'rightbottom': $offestX = 0; $offestY = 'main_h-overlay_h'; break; case 'center': $offestX = '(main_w-overlay_w)/2'; $offestY = '(main_h-overlay_h)/2'; break; default: $offestX = 0; $offestY = 0; break; } $this->OutFileOptions .= "-filter_complex overlay=" . $offestX . ':' . $offestY . ' '; return $this; } public function setAphaser( ){ $this->OutFileOptions .= "-filter_complex blend=all_mode=normal "; return $this; } /** * 修改視頻速率(只修改視頻,音頻依舊是原速率) * @param $_speed 速率 * @return $this Class 此類 */ public function videoSetpts($_speed){ (empty($_speed))? $this->ErrMessage[] = 'videoSpeed is null': $this->OutFileOptions .= "-filter:v setpts=PTS*('.$_speed.')' "; return $this; } /** * 同時修改音頻與視頻速率 */ public function changeVideoSpeed($_speed){ $_speed = explode('/',$_speed); if(empty($_speed)){ $this->ErrMessage[] = 'speed is null'; }elseif(($_speed[0]/$_speed[1] > 2) || ($_speed[0]/$_speed[1] < 1/2)){ $this->ErrMessage[] = 'The rate is only 2/1(2.0) to 1/2(0.5)'; }else{ $videoSpeed = '('.$_speed[0].'/'.$_speed[1].')'; $audioSpeed = '('.$_speed[1].'/'.$_speed[0].')'; $this->OutFileOptions .= "-filter_complex [0:v]setpts=".$videoSpeed."*PTS[v];[0:a]atempo=".$audioSpeed."[a] -map [v] -map [a] "; } return $this; } /** * 視頻單獨分離 * @return $this Class 此類 */ public function separateVideo(){ $this->OutFileOptions .= '-vcodec copy -an '; return $this; } /** * 音頻單獨分離 * @return $this Class 此類 */ public function separateAudio(){ $this->OutFileOptions .= '-acodec copy -vn '; return $this; } /** * 修改視頻尺寸 參考 640x480 * @param $Width 視頻寬度 * @param $Height 視頻高度 * @return $this */ public function changeAudioSize($Width,$Height){ (empty($Width) || empty($Height))? $this->ErrMessage[] = 'width or height is null': $this->OutFileOptions .= '-s '.$Width.'x'.$Height.' '; return $this; } /* * 轉換黑白 */ public function videoBlackWhite(){ $this->OutFileOptions .= '-vf lutyuv="u=128:v=128" '; return $this; } /** * 生成gif * @return $this */ public function makeGif(){ $this->OutFileOptions .='-pix_fmt rgb24 '; return $this; } ////////////////////////////錯誤處理,運行ffmpeg方法//////////////////////////// /** * 獲取執行錯誤信息 * @return array 錯誤信息,包括錯誤行數和錯誤內容 */ public function setErrMessage($message){ $this->ErrMessage[] = $message; } public function getErrorMessage(){ return($this->ErrMessage); } /** * 執行ffmpeg命令 * @return string 執行結果信息 */ public function exec( ){ if(!empty($this->ErrMessage)){ return false; } //amr文件輸出方式跟其餘文件不一樣,須要分開處理 if( $this->OutFileTybe == 'amr' ){ $acIndex = strrpos( $this->OutFileOptions , '-ac' , 0 ); $arIndex = strrpos( $this->OutFileOptions , '-ar' , 0 ); $this->OutFileOptions = $acIndex === false ? $this->OutFileOptions . ' -ac 1 ' : $this->OutFileOptions; $this->OutFileOptions = $arIndex === false ? $this->OutFileOptions . ' -ar 8000 ' : $this->OutFileOptions; } //輸入文件內容 $inputString = ''; //將輸入條件與對應文件進行匹配 foreach ($this->InputFileOptions as $value) { $inputString .= $value; } //將執行語句拼接 $this->ExecString .= $this->GlobalOptions . $inputString . $this->OutFileOptions . $this->OutFilePath; //執行ffmpeg命令 exec( $this->ExecString,$execInfo,$execCode); //執行後清空本次執行選項,防止干擾下次使用 $this->ExecString = 'ffmpeg '; $this->GlobalOptions = ''; $this->InputFileOptionsString = ''; $this->InputFileOptions = array(); $this->InputFilePath = array(); $this->OutFileOptions = ''; $this->OutFilePath = ''; $this->OutFileTybe = ''; //檢查exec語句運行是否成功,若是不成功返回失敗 if(!is_array($execInfo) && $execCode!=0){ $this->setErrMessage('exec error!!'); return false; }else { return true; } } /** * 此方法用來解決沒法用戶沒法經過瀏覽器執行exec命令(此方法只能在windos上使用) * @param $batPath bat文件路徑 * @return bool */ public function execute($batPath){ if(!empty($this->ErrMessage)){ return false; } if( $this->OutFileTybe == 'amr' ){ $acIndex = strrpos( $this->OutFileOptions , '-ac' , 0 ); $arIndex = strrpos( $this->OutFileOptions , '-ar' , 0 ); $this->OutFileOptions = $acIndex === false ? $this->OutFileOptions . ' -ac 1 ' : $this->OutFileOptions; $this->OutFileOptions = $arIndex === false ? $this->OutFileOptions . ' -ar 8000 ' : $this->OutFileOptions; } //輸入文件內容 $inputString = ''; //將輸入條件與對應文件進行匹配 foreach ($this->InputFileOptions as $value) { $inputString .= $value; } //將執行語句拼接 $this->ExecString .= $this->GlobalOptions . $inputString . $this->OutFileOptions . $this->OutFilePath; $bat = fopen($batPath,'w+'); if(!$bat){ $this->setErrMessage('batFile can not open'); return false; } fwrite($bat, $this->ExecString); fclose($bat); exec($batPath,$execInfo,$execCode); $this->ExecString = 'ffmpeg '; $this->GlobalOptions = ''; $this->InputFileOptionsString = ''; $this->InputFileOptions = array(); $this->InputFilePath = array(); $this->OutFileOptions = ''; $this->OutFilePath = ''; $this->OutFileTybe = ''; //檢查exec語句運行是否成功,若是不成功返回失敗 if(!is_array($execInfo) && $execCode!=0){ $this->setErrMessage('exec error!!'); return false; }else { return true; } } }

有些功能有衝突是不能同時使用的,好比音頻分離跟修改速率是不能同時執行的
ffmpeg是一個功能十分強大的開源庫,我這裏只列舉一部分功能,並且這個類還有許多能夠優化的地方,這個類寫出來主要是爲了拋磚引玉 :D

下面附上ffmpeg參數說明
http://www.cnblogs.com/chen1987lei/archive/2010/12/03/1895242.html

 
參考:PHP的ffmpeg使用 - CSDN博客 https://blog.csdn.net/qq_20329253/article/details/51420661
相關文章
相關標籤/搜索