FFMpeg for PHP
PHP使用FFMpeg来转换视频格式。Github上搜索FFMPEG,到https://github.com/PHP-FFMpeg/PHP-FFMpeg。
For Windows users : Please find the binaries at http://ffmpeg.zeranoe.com/builds/.详细使用过程,见我上一篇博客。
以下操作,默认是在Linux服务器环境下进行的。
安装
建议通过Composer来安装PHP-FFMpeg
$ composer require php-ffmpeg/php-ffmpeg
基本使用
$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\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支持的任意资源。
注意:如果你想列出你用的FFmpeg支持的所有资源类型, 使用 -protocols
命令:
ffmpeg -protocols
使用
FFMpeg\FFMpeg::open 方法来打开一个资源。
$ffmpeg->open('video.mpeg');
两种类型的视频可以被处理: FFMpeg\Media\Audio
和 FFMpeg\Media\Video。第三种类型
FFMpeg\Media\Frame
, 可以通过视频来处理。
Video
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' );
Filters
你可以使用 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)
Synchronize(同步)
同步的音频和视频
一些容器使用延迟可能会导致不同步的输出。过滤器可以解决这个问题。
$video->filters()->synchronize();
Clip(修剪)
在想要的点减掉视频。
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(30), FFMpeg\Coordinate\TimeCode::fromSeconds(15));
The clip filter(修剪的过滤器)需要两个参数:
$start
, 一个FFMpeg\Coordinate\TimeCode实例
, 指定开始剪切的点$duration
, 可选, 一个FFMpeg\Coordinate\TimeCode实例
, 指定要持续的时间
Audio(音频)
FFMpeg\Media\Audio
可以被转码, ie: 改变编码解码器, 隔离视频和音频。帧可以被提取。
Transcoding(转码)
你可以用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文档了解更多。
Filters(过滤器)
你可以用FFMpeg\Media\Audio::addFilter
在FFMpeg\Media\Audio
上应用过滤器的效果。只接受音频过滤器。
你可以创建你自己的过滤器并且PHP-FFMpeg也附带了一些,你可以通过 FFMpeg\Media\Audio::filters
方法来使用它们。
Metadata(元数据)
向音频文件中添加元数据。你可以数组的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输出
Resample(重采样)
重采样一个音频文件。
$audio->filters()->resample($rate);
重采样过滤器需要两个参数:
$rate
, a valid audio sample rate value (integer)
帧
帧是视频文件在某一个时间点的图片,看API了解更多。
你可以使用 FFMpeg\Media\Frame::save
方法来保存帧。
$frame->save('target.jpg');
这个方法还有一个可选的布尔类型的参数。设置这个参数为true可以获得更加精确的图片,可能稍微花多一点的时间去执行。
Gif
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图片。
Concatenation(串联)
这个特性能够让你用混合的资源来生成一个视频或者音频。
现在有两种串联视频的方式,根据资源的编码解码器。如果你的资源都是采用的同一种编码解码器的话,你使用 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.
Formats(格式)
格式要实现 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');
为事件提供的回调函数可以随时调用。
Add additional parameters
你可以根据你的视频格式为你的编码提供额外的参数。
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');
}
}
Coordinates(坐标)
FFMpeg 使用很多单元来确定时间和空间坐标。
FFMpeg\Coordinate\AspectRatio
表示长宽比FFMpeg\Coordinate\Dimension
表示一个维度FFMpeg\Coordinate\FrameRate
表示帧速率FFMpeg\Coordinate\Point
表示一个点FFMpeg\Coordinate\TimeCode
表示一个时间码
FFProbe
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
使用 Silex Microframework
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,
));
------------------------------------------------------------------------------------------------------------------------------
购买阿里云服务优惠链接:
https://chuangke.aliyun.com/invite?userCode=ff3mpiie
FFMpeg for PHP的更多相关文章
- FFmpeg学习6:视音频同步
在上一篇文章中,视频和音频是各自独立播放的,并不同步.本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的.主要有以下几个方面的内容 视音频同步的简单介绍 DTS 和 ...
- FFmpeg 中AVPacket的使用
AVPacket保存的是解码前的数据,也就是压缩后的数据.该结构本身不直接包含数据,其有一个指向数据域的指针,FFmpeg中很多的数据结构都使用这种方法来管理数据. AVPacket的使用通常离不开下 ...
- FFmpeg + SoundTouch实现音频的变调变速
本文使用FFmpeg + SoundTouch实现将音频解码后,进行变调变速处理,并将处理后的结果保存为WAV文件. 主要有以下内容: 实现一个FFmpeg的工具类,保存多媒体文件所需的解码信息 将解 ...
- 用ffmpeg快速剪切和合并视频
如果直接找视频剪切和合并视频的软件,通常出来的都是大的视频编辑软件或者是有图形界面的剪切软件,大型一点的功能太多安装麻烦,小型一点的功能可能不齐全. 只是简单的剪切或者一下合并一下,还是ffmpeg这 ...
- ffmpeg用法及如何使用fluent-ffmpeg
http://ffmpeg.org/ 官网 ffmpeg(命令行工具) 是一个快速的音视频转换工具. 1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an o ...
- FFmpeg学习4:音频格式转换
前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...
- FFmpeg学习5:多线程播放视音频
在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...
- FFmpeg数据结构:AVPacket解析
本文主要从以下几个方面对AVPacket做解析: AVPacket在FFmpeg中的作用 字段说明 AVPacket中的内存管理 AVPacket相关函数的说明 结合AVPacket队列说明下AVPa ...
- FFmpeg学习3:播放音频
参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...
- FFmpeg学习2:解码数据结构及函数总结
在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...
随机推荐
- Effective Java 第三版——29. 优先考虑泛型
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- linkinFrame--用maven搭项目结构
OK,老早想写一套自己的web框架,然后也一直在看开源的一些框架源码.今天开始正式开始写自己的javaWeb框架,暂时就定义linkinFrame好了. 为什么要写一套自己的框架? 其实这是一个比较矛 ...
- 转-HTTP POST GET SOAP本质区别详解
原文链接:HTTP POST GET SOAP本质区别详解 一 原理区别 一般在浏览器中输入网址访问资源都是通过GET方式:在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认 ...
- 在Tomcat中配置连接池和数据源
1.DataSource接口介绍 (1)DataSource 概述 JDBC1.0原来是用DriverManager类来产生一个对数据源的连接.JDBC2.0用一种替代的方法,使用DataSource ...
- 错误:You can't specify target table 'xxx' for update in FROM clause的解决
问题: 今天在MySQL数据库删除重复数据的时候遇到了一个问题.如下脚本: DELETE FROM tempA WHERE tid IN ( SELECT MAX(tid) AS tid FROM t ...
- 错误:The request sent by the client was syntactically incorrect的解决
问题: 错误400-The request sent by the client was syntactically incorrect. springMVC中,某个页面提交时报400错误,如下图. ...
- PhpStudy 升级 MySQL 版本到5.7
1:备份当前数据库数据. 最好是导成 SQL 文件 2:备份 PhpStudy 下的 MySQL 文件夹.以防升级失败.还可以使用旧版本的数据库 3:下载MySQL5.7.解压.然后放在 PhpStu ...
- Android内核三大核心功能之一AMS内部原理
上面类是AmS的全称,另外两大核心功能是WindowManagerService.java和View.java AmS提供的主要功能: 统一调度各应用程序 内存管理 进程管理 AmS中定义了几个重要的 ...
- HTML5入门要点
要点 HTML5是HTML的最新版本.通过引入心的标签.新的语义和媒体元素,同时要依赖一组支持Web应用的JavaScript库 XHTML不再是Web页面开发标准.开发人员和W3C组织觉决定还是继续 ...
- shell获取字符串长度
方法1: 使用wc -L命令 wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l则是获取当前字符串内容的行数. 代码如下: echo "abc& ...