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 ...
随机推荐
- Linuxc - 操作系统内存分配
静态变量是存储在数据段的,在函数中可以共用. 全局变量也是存储在数据段的,在全局中可以共用. 指针变量本质上是地址,数组变量本质上也是地址. 数组是可靠的,不可变的地址.指针变量是不可靠的,可变的.数 ...
- Python用户输入和代码注释
一.用户输入 若你安装的是Python3.x版本,当你在Python IDLE(编辑器) 中输入以下代码: name = input('用户名:') print('Hello',name) 保存并执行 ...
- crontab 定时任务守护程序,停止服务器时出现 job for * canceled
(1)首先要在程序启动的时候加入定时任务到crontab #! /bin/shmkdir -p /home/apps/components/ams/ 2>/dev/nullcp ./amswat ...
- 【mac】ssh免登录密码
mac ssh免登录密码 在mac或者Linux上需要使用ssh登服务器,每次都需要输密码感觉很麻烦,搜了一下找到一个脚本,实践后发现可行. 1.创建脚本xx.sh $ vim xx.sh 输入: # ...
- Django的ORM实现数据库事务操作
在Django中实现数据库的事务操作 在学习MySQL数据库时,MySQL数据库是支持原子操作的. 什么是数据库的原子操作呢??打个比方,一个消费者在一个商户里刷信用卡消费. 交易正常时,银行在消费者 ...
- instanceof、isInstance、isAssignableFrom的区别
https://stackoverflow.com/questions/3949260/java-class-isinstance-vs-class-isassignablefrom 1. MyCla ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- linux指令札记
1.有关文件压缩解压缩:Linux下自带了一个unzip的程序可以解压缩文件,解压命令是:unzip filename.zip 同样也提供了一个zip程序压缩zip文件,命令是 zip filenam ...
- Linux设置DNS地址及清理DNS缓存方法
1.设置DNS地址 编辑vim /etc/resolv.conf 文件. 增加DNS地址:nameserver ip. 2.清理DNS缓存 清理dns缓存: 通过重启nscd服务来达到清理dns缓存的 ...
- 通过代码配置 Log4net来实现日志记录
通过代码来创建配置文件,优点看起来更为简洁,不过还得看需求吧,之前我博客也写了一篇通过读取不同的配置文件还实现配置不同日志类型. //记录异常日志数据库连接字符串 private const stri ...