PHP使用FFMpeg來轉換視頻格式。Github上搜索FFMPEG,到https://github.com/PHP-FFMpeg/PHP-FFMpeg。php
For Windows users : Please find the binaries at http://ffmpeg.zeranoe.com/builds/.詳細使用過程,見我上一篇博客。
html
如下操做,默認是在Linux服務器環境下進行的。git
建議經過Composer來安裝PHP-FFMpeg github
$ composer require php-ffmpeg/php-ffmpegweb
$ffmpeg = FFMpeg\FFMpeg::create(); $video = $ffmpeg->open('video.mpg'); $video ->filters() ->resize(new FFMpeg\Coordinate\Dimension(320, 240)) ->synchronize(); $video ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) ->save('frame.jpg'); $video ->save(new FFMpeg\Format\Video\X264(), 'export-x264.mp4') ->save(new FFMpeg\Format\Video\WMV(), 'export-wmv.wmv') ->save(new FFMpeg\Format\Video\WebM(), 'export-webm.webm');
這個文檔是對API進行的引導介紹。建議去閱讀源代碼和配套的文檔。數組
FFMpeg\FFMpeg
是操做媒體主要的對象。可使用靜態調用FFMpeg\FFMpeg::create
來建立。
服務器
$ffmpeg = FFMpeg\FFMpeg::create();
FFMpeg會自動探測 ffmpeg和ffprobe的二進制文件。若是你想給出確切的二進制文件路徑, 能夠經過一個數組來設置。 A Psr\Logger\LoggerInterface
can also be passed to log binary executions.網絡
$ffmpeg = FFMpeg\FFMpeg::create(array( 'ffmpeg.binaries' => '/opt/local/ffmpeg/bin/ffmpeg', 'ffprobe.binaries' => '/opt/local/ffmpeg/bin/ffprobe', 'timeout' => 3600, // The timeout for the underlying process 'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use ), $logger);
FFMpeg\FFMpeg根據
URIs來建立媒體. URIs能夠是本地的系統資源, HTTP網絡資源,FFmpeg支持的任意資源。app
注意:若是你想列出你用的FFmpeg支持的全部資源類型, 使用 -protocols
命令:composer
使用
ffmpeg -protocols
FFMpeg\FFMpeg::open 方法來打開一個資源。
$ffmpeg->open('video.mpeg');
兩種類型的視頻能夠被處理: FFMpeg\Media\Audio
和 FFMpeg\Media\Video。第三種類型
FFMpeg\Media\Frame
, 能夠經過視頻來處理。
FFMpeg\Media\Video
能夠被轉碼, ie: change codec, isolate audio or video. 幀能夠提取。
你能夠經過FFMpeg\Media\Video:save方法對視頻進行轉碼,你將經過
FFMpeg\Format\FormatInterface來實現。
請注意視頻或音頻的比特率須要在格式中設置。
$format = new Format\Video\X264(); $format->on('progress', function ($video, $format, $percentage) { echo "$percentage % transcoded"; }); $format -> setKiloBitrate(1000) -> setAudioChannels(2) -> setAudioKiloBitrate(256); $video->save($format, 'video.avi');
轉碼的過程能夠被實時監控, 看下面有關Format的文檔瞭解更過信息。
你能夠用FFMpeg\Media\Video::frame 方法來提取任意時間的幀畫面。
代碼返回了一個媒體文件第42秒所對應的FFMpeg\Media\Frame
實例。你可使用 FFMpeg\Coordinate\TimeCode 做爲參數
, 看專業文檔瞭解更多。
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42)); $frame->save('image.jpg');
若是你想從視頻中獲取多種圖片,你可使用下邊的過濾器
$video ->filters() ->extractMultipleFrames(FFMpeg\Filters\Video\ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, '/path/to/destination/folder/') ->synchronize(); $video ->save(new FFMpeg\Format\Video\X264(), '/path/to/new/file');
你可使用 FFMpeg\Media\Audio::waveform
方法來從音頻文件中生成一個波。
代碼返回一個 FFMpeg\Media\Waveform
實例。你能夠設置不一樣的尺寸做爲參數, 查看API文檔瞭解更多。
輸出文件必須使用PNG extension.
$waveform = $audio->waveform(640, 120); $waveform->save('waveform.png');
若是你想從視頻文件中獲得一個波, 須要先把視頻文件轉換成音頻文件。
// Open your video file $video = $ffmpeg->open( 'video.mp4' ); // Set an audio format $audio_format = new FFMpeg\Format\Audio\Mp3(); // Extract the audio into a new file $video->save('audio.mp3'); // Set the audio file $audio = $ffmpeg->open( 'audio.mp3' ); // Create the waveform $waveform = $audio->waveform(); $waveform->save( 'waveform.png' );
你可使用 FFMpeg\Media\Video::addFilter
方法在 FFMpeg\Media\Video上
使用過濾器。 視頻接受視頻和音頻的過濾器。
你能夠建立你本身的過濾器而且PHP-FFMpeg也附帶了一些,你能夠經過 FFMpeg\Media\Video::filters
方法來使用它們。
過濾器是能夠連接的
$video ->filters() ->resize($dimension, $mode, $useStandards) ->framerate($framerate, $gop) ->synchronize();
用給定的角度來旋轉視頻。
$video->filters()->rotate($angle);
$angle
的參數必須是下面的一個常量:
FFMpeg\Filters\Video\RotateFilter::ROTATE_90
: 90° clockwiseFFMpeg\Filters\Video\RotateFilter::ROTATE_180
: 180°FFMpeg\Filters\Video\RotateFilter::ROTATE_270
: 90° counterclockwise按照給定的尺寸調整視頻的大小。
$video->filters()->resize($dimension, $mode, $useStandards);
調整尺寸的過濾器須要三個參數:
$dimension
, 一個 FFMpeg\Coordinate\Dimension實例
$mode
, FFMpeg\Filters\Video\ResizeFilter::RESIZEMODE_*
constants常量中的一個。$useStandards
, 是否強制使用最新的比率標準的布爾若是你想要視頻處在一個非標準的比率, 你可使用padding 過濾器 調整視頻大小到想要的尺寸,包上黑色的條。
$video->filters()->pad($dimension);
pad 過濾器須要一個參數 :
$dimension
, FFMpeg\Coordinate\Dimension的實例
而後的話不要忘記保存。
$video->save(new FFMpeg\Format\Video\X264(), $new_file);
用給定的圖片給視頻文件添加水印。
$video ->filters() ->watermark($watermarkPath, array( 'position' => 'relative', 'bottom' => 50, 'right' => 50, ));
watermark 過濾器須要兩個參數:
$watermarkPath
, 你水印文件的路徑; $coordinates
, 一個定義水印放置位置的數組。你可使用相對路徑像上面展現的那樣。或者使用絕對路徑像這樣:
$video ->filters() ->watermark($watermarkPath, array( 'position' => 'absolute', 'x' => 1180, 'y' => 620, ));
改變視頻的幀頻
$video->filters()->framerate($framerate, $gop);
framerate(幀頻)過濾器須要兩個參數:
$framerate
, FFMpeg\Coordinate\Framerate的實例
$gop
, a GOP value (integer)同步的音頻和視頻
一些容器使用延遲可能會致使不一樣步的輸出。過濾器能夠解決這個問題。
$video->filters()->synchronize();
在想要的點減掉視頻。
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(30), FFMpeg\Coordinate\TimeCode::fromSeconds(15));
The clip filter(修剪的過濾器)須要兩個參數:
$start
, 一個FFMpeg\Coordinate\TimeCode實例
, 指定開始剪切的點$duration
, 可選, 一個 FFMpeg\Coordinate\TimeCode實例
, 指定要持續的時間FFMpeg\Media\Audio
能夠被轉碼, ie: 改變編碼解碼器, 隔離視頻和音頻。幀能夠被提取。
你能夠用FFMpeg\Media\Audio:save
方法來給音頻文件轉碼。你能夠經過FFMpeg\Format\FormatInterface 來實現。
Please note that audio kilobitrate is set on the audio format.
$ffmpeg = FFMpeg\FFMpeg::create(); $audio = $ffmpeg->open('track.mp3'); $format = new FFMpeg\Format\Audio\Flac(); $format->on('progress', function ($audio, $format, $percentage) { echo "$percentage % transcoded"; }); $format -> setAudioChannels(2) -> setAudioKiloBitrate(256); $audio->save($format, 'track.flac');
轉碼過程能夠被實時監控, 看API文檔瞭解更多。
你能夠用FFMpeg\Media\Audio::addFilter
在FFMpeg\Media\Audio
上應用過濾器的效果。只接受音頻過濾器。
你能夠建立你本身的過濾器而且PHP-FFMpeg也附帶了一些,你能夠經過 FFMpeg\Media\Audio::filters
方法來使用它們。
向音頻文件中添加元數據。你能夠數組的key=value鍵值對的形式添加你想要的元數據。若是過濾器中沒有任何參數傳遞進來,那麼全部的元數據將被從輸入文件中刪除。目前支持的數據有 title, artist, album, artist, composer, track, year, description, artwork
$audio->filters()->addMetadata(["title" => "Some Title", "track" => 1]); //remove all metadata and video streams from audio file $audio->filters()->addMetadata();
向音頻文件中添加artwork
$audio->filters()->addMetadata(["artwork" => "/path/to/image/file.jpg"]);
注意: 當前ffmpeg (version 3.2.2) only supports 只支持 .mp3 文件的artwork輸出
重採樣一個音頻文件。
$audio->filters()->resample($rate);
重採樣過濾器須要兩個參數:
$rate
, a valid audio sample rate value (integer)幀是視頻文件在某一個時間點的圖片,看API瞭解更多。
你可使用 FFMpeg\Media\Frame::save
方法來保存幀。
$frame->save('target.jpg');
這個方法還有一個可選的布爾類型的參數。設置這個參數爲true能夠得到更加精確的圖片,可能稍微花多一點的時間去執行。
GIf是從視頻文件中提取的一系列的動畫圖片。
你可使用 FFMpeg\Media\Gif::save
方法來保存gif文件。
$video = $ffmpeg->open( '/path/to/video' ); $video ->gif(FFMpeg\Coordinate\TimeCode::fromSeconds(2), new FFMpeg\Coordinate\Dimension(640, 480), 3) ->save($new_file);
這個方法有一個可選的布爾類型的參數,就是動畫的持續時間。若是設置的話,能夠獲得一個確切的gif圖片。
這個特性可以讓你用混合的資源來生成一個視頻或者音頻。
如今有兩種串聯視頻的方式,根據資源的編碼解碼器。若是你的資源都是採用的同一種編碼解碼器的話,你使用 FFMpeg\Media\Concatenate::saveFromSameCodecs
更好一些。 若是你的資源採用不一樣的編碼解碼器, 你要用到 FFMpeg\Media\Concatenate::saveFromDifferentCodecs
.
The first function will use the initial codec as the one for the generated file. With the second function, you will be able to choose which codec you want for the generated file.
You also need to pay attention to the fact that, when using the saveFromDifferentCodecs method, your files MUST have video and audio streams.
In both cases, you will have to provide an array of files.
To concatenate videos encoded with the same codec, do as follow:串聯採用相同編碼解碼器的視頻文件的話,參照下邊的方法:
// In order to instantiate the video object, you HAVE TO pass a path to a valid video file. // We recommand that you put there the path of any of the video you want to use in this concatenation. $video = $ffmpeg->open( '/path/to/video' ); $video ->concat(array('/path/to/video1', '/path/to/video2')) ->saveFromSameCodecs('/path/to/new_file', TRUE);
保存函數中的布爾參數能讓你使用拷貝的參數,這個參數能夠大福度提升編碼文件的生成過程。
To concatenate videos encoded with the same codec, do as follow:
// In order to instantiate the video object, you HAVE TO pass a path to a valid video file. // We recommand that you put there the path of any of the video you want to use in this concatenation. $video = $ffmpeg->open( '/path/to/video' ); $format = new FFMpeg\Format\Video\X264(); $format->setAudioCodec("libmp3lame"); $video ->concat(array('/path/to/video1', '/path/to/video2')) ->saveFromDifferentCodecs($format, '/path/to/new_file');
在 FFMPEG中更多關於串聯的細節 可看這裏 here, here and here.
格式要實現 FFMpeg\Format\FormatInterface。
用FFMpeg\Format\VideoInterface來保存視頻文件
, 用 FFMpeg\Format\AudioInterface 來保存音頻文件。
FFMpeg\Format\ProgressableInterface的話能夠得到轉碼的實時信息。
預約義的格式已經提供了事件的過程信息。
$format = new Format\Video\X264(); $format->on('progress', function ($video, $format, $percentage) { echo "$percentage % transcoded"; }); $video->save($format, 'video.avi');
爲事件提供的回調函數能夠隨時調用。
你能夠根據你的視頻格式爲你的編碼提供額外的參數。
setAdditionalParameters 方法的參數是一個數組。
$format = new Format\Video\X264(); $format->setAdditionalParameters(array('foo', 'bar')); $video->save($format, 'video.avi');
建立一種新的格式最簡單的方法就是集成抽象類 FFMpeg\Format\Video\DefaultVideo
and FFMpeg\Format\Audio\DefaultAudio,而且實現下面的方法。
class CustomWMVFormat extends FFMpeg\Format\Video\DefaultVideo { public function __construct($audioCodec = 'wmav2', $videoCodec = 'wmv2') { $this ->setAudioCodec($audioCodec) ->setVideoCodec($videoCodec); } public function supportBFrames() { return false; } public function getAvailableAudioCodecs() { return array('wmav2'); } public function getAvailableVideoCodecs() { return array('wmv2'); } }
FFMpeg 使用不少單元來肯定時間和空間座標。
FFMpeg\Coordinate\AspectRatio
表示長寬比FFMpeg\Coordinate\Dimension
表示一個維度FFMpeg\Coordinate\FrameRate
表示幀速率FFMpeg\Coordinate\Point
表示一個點FFMpeg\Coordinate\TimeCode
表示一個時間碼FFMpeg\FFMpeg
內部使用FFMpeg\FFProbe
來檢查媒體文件。你也能夠用它提取元數據。
$ffprobe = FFMpeg\FFProbe::create(); $ffprobe ->streams('/path/to/video/mp4') // extracts streams informations ->videos() // filters video streams ->first() // returns the first video stream ->get('codec_name'); // returns the codec_name property
$ffprobe = FFMpeg\FFProbe::create(); $ffprobe ->format('/path/to/video/mp4') // extracts file informations ->get('duration'); // returns the duration property
Service provider is easy to set up:
$app = new Silex\Application(); $app->register(new FFMpeg\FFMpegServiceProvider()); $video = $app['ffmpeg']->open('video.mpeg');
下面是一些可能的選項:
$app->register(new FFMpeg\FFMpegServiceProvider(), array( 'ffmpeg.configuration' => array( 'ffmpeg.threads' => 4, 'ffmpeg.timeout' => 300, 'ffmpeg.binaries' => '/opt/local/ffmpeg/bin/ffmpeg', 'ffprobe.timeout' => 30, 'ffprobe.binaries' => '/opt/local/ffmpeg/bin/ffprobe', ), 'ffmpeg.logger' => $logger, ));
------------------------------------------------------------------------------------------------------------------------------
購買阿里雲服務優惠連接: