Laravel 下使用 FFmpeg 处理多媒体文件
说明
最近在项目里使用 FFmpeg 做音频格式转换, 这里做个笔记.
什么是 FFmpeg?
- FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影、转换、流功能,包含了libavcodec ─这是一个用于多个项目中音频和视频的解码器库,以及libavformat——一个音频与视频格式转换库。
- 这个项目最初是由Fabrice Bellard发起的,而现在是由Michael Niedermayer在进行维护。许多FFmpeg的开发者同时也是MPlayer项目的成员,FFmpeg在MPlayer项目中是被设计为服务器版本进行开发。
- -- 上面的解释引自 Wiki
应用领域
- FFmpeg 被许多开源项目采用,比如 ffmpeg2theora, VLC, MPlayer, HandBrake, Blender, Google Chrome等。
- 还有 DirectShow/VFW 的 ffdshow(external project) 和 QuickTime 的 Perian (external project) 也采用了FFmpeg。
- KMPlayer、格式工厂、暴风影音、QQ影音、KMP、GOM Player、PotPlayer(2010)都在其列。
安装 FFmpeg 命令
下面是 Ubuntu 14 LTS 的安装方法:
sudo apt-add-repository ppa:mc3man/trusty-media
sudo apt-get update
sudo apt-get install -y ffmpeg gstreamer0.10-ffmpeg
安装成功后测试:
$ ffmpeg -version
PHP-FFMpeg
PHP-FFMpeg 是 FFMpeg 和 FFProbe 命令的 PHP 面对对象 Wrapper.
安装
项目根目录下:
$ composer require "php-ffmpeg/php-ffmpeg:~0.5"
使用
创建 FFMpeg\FFMpeg
对象:
$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);
视频处理
视频转码
$video = $ffmpeg->open('video.mpeg');
$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, public_path().'/uploads/video/video.avi');
视频截图
// 在视频 42 秒的地方截图
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42));
$frame->save('image.jpg');
视频旋转
$video->filters()->rotate($angle)->synchronize();
$angle
参数的选项从下面选取:
- FFMpeg\Filters\Video\RotateFilter::ROTATE_90 : 90° 顺时针方向
- FFMpeg\Filters\Video\RotateFilter::ROTATE_180 : 180°
- FFMpeg\Filters\Video\RotateFilter::ROTATE_270 : 90° 逆时针方向
synchronize
方法是触发保存的动作, 因为 filters
可以多个链接起来, 如下:
$video
->filters()
->resize($dimension, $mode, $useStandards)
->framerate($framerate, $gop)
->synchronize();
调整视频尺寸
$video->filters()->resize($dimension, $mode, $useStandards);
传参见: 文档
视频帧速率
$video->filters()->framerate($framerate, $gop);
传参见: 文档
视频裁剪
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(30), FFMpeg\Coordinate\TimeCode::fromSeconds(15));
传参见: 文档
音频处理
音频格式转换
$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, public_path().'/uploads/video/track.flac');
音频采样率
$audio->filters()->resample(16000);
音频转换示例
在我的项目中, 需要把 8khz 采样率, 单声道的 amr 文件
转换为 16khz 采样率, 单声道的 wav 文件
, 下面是实例代码:
$audio_path = public_path().'/uploads/audio/';
$random_string = str_random(10);
$amr_filename = $random_string.'.amr';
$wav_filename = $random_string.'.wav';
Input::file('audio_file')->move($audio_path, $amr_filename);
$audio = $ffmpeg->open($audio_path.$amr_filename);
$format = new FFMpeg\Format\Audio\Wav();
$format->setAudioChannels(1);
$audio->filters()->resample('16000');
$audio->save($format, $audio_path.$wav_filename);
总结
利用此工具, 可以对多媒体文件进行自由修改, 在很多应用场景下都能应用上, 把 TA 放到你的工具箱里面吧 :sparkles: .
本帖已被设为精华帖!
@fasthold 你遇到问题了? 能分享下细节不.
@fasthold 多谢你的分享, 很宝贵的经验,
aac
还是挺常见的格式, 我在项目里面只用到amr
与wav
之间的互转.报错Unable to load FFProbe
改怎么解决?
laravel 5.6 安装php-ffmpeg
$sudo composer require "php-ffmpeg/php-ffmpeg"
[sudo] password for mrchen:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Using version ^0.12.0 for php-ffmpeg/php-ffmpeg
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
Conclusion: remove symfony/console v4.1.3
安装不上,这是不兼容还是,人有碰到过吗,应该怎样解决呢???
转码3.2GB的mp4文件,快完的时候报这个错误,请问有人碰以过吗??
message Encoding failed
exception FFMpeg\Exception\RuntimeException
file /data/VirtualData/web/company/Star-Video-Control/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/AbstractVideo.php
line 106
@yxiawen 解决了么?我今天也遇到了
在windows上使用是不是需要给php安装.dll文件的扩展?我在官网下载下来的是.exe。github上的说的是:For Windows users: Please find the binaries at http://ffmpeg.zeranoe.com/builds/. 这个binaries是什么??怎么用???在此先谢过各位!
@qingyi https://www.cnblogs.com/love-snow/articles...
config/element.php:
<?php
return [
'ffmpegpath' =>'E:/谷歌浏览器下载/ffmpeg-20181105-beaa350-win64-static/bin/ffmpeg.exe -i "%s" 2>&1',
'ffmpeg' =>'E:/谷歌浏览器下载/ffmpeg-20181105-beaa350-win64-static/bin/ffmpeg.exe',
'ffprobe' =>'E:/谷歌浏览器下载/ffmpeg-20181105-beaa350-win64-static/bin/ffprobe.exe',
];
使用:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Validator;
use FFMpeg;
use Config;
class IndexController extends Controller
{
public function index(Request $request)
{
$ffmpeg_path = Config::get("element.ffmpeg");//ffmpeg运行的路径
$ffprobe_path = Config::get("element.ffprobe");//ffprobe运行路径
$ffmpeg = FFMpeg\FFMpeg::create(array(
'ffmpeg.binaries' => $ffmpeg_path,
'ffprobe.binaries' => $ffprobe_path,
'timeout' => 30000, // The timeout for the underlying process
'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use
));
}
@xkcaaa 我用laravel5.7 window平台phpstudy php7.2+apache ,按照你说的配置 ,可以获取到 $ffmepg对象,但是在对文件进行转码时就包 服务器500错误了,我查看 error.log显示
[core:error] [pid 5268:tid 2132] [client 127.0.0.1:57428] End of script output before headers: index.php
@景哥哥
你的视频文件是多大的?换个小点的视频文件试一下?会不会是因为转码时间过长?之前我只是图快随意写在控制器里了,这种场景还是使用laravel新建一个命令来运行比较合适。
sudo apt-get install -y ffmpeg 后面版本是不该去了啊
@xkcaaa 可以 :+1:
如果只是两个音视频的简单合并,有什么好的方法推荐?
我的视频切割后有声音,无画面,要怎么解决呢,求大佬回复啊
FFMpeg \ Exception \ RuntimeException
Unable to save frame
Previous exceptions
ffmpeg failed to execute command '/usr/local/Cellar/ffmpeg/4.1.3_1/bin/ffmpeg' '-y' '-ss' '00:00:05.00' '-i' 'http://vfx.mtime.cn/Video/2019/02/04/mp4/1...' '-vframes' '1' '-f' 'image2' 'image1.mjpeg': Error Output: ffmpeg version 4.1.3 Copyright (c) 2000-2019 the FFmpeg developers built with Apple LLVM version 10.0.1 (clang-1001.0.46.4) configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.3_1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr libavutil 56. 22.100 / 56. 22.100 libavcodec 58. 35.100 / 58. 35.100 libavformat 58. 20.100 / 58. 20.100 libavdevice 58. 5.100 / 58. 5.100 libavfilter 7. 40.101 / 7. 40.101 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 3.100 / 5. 3.100 libswresample 3. 3.100 / 3. 3.100 libpostproc 55. 3.100 / 55. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'http://vfx.mtime.cn/Video/2019/02/04/mp4/1...': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : www.aliyun.com - Media Transcoding Duration:
$ffmpeg = FFMpeg::create(array(
'ffmpeg.binaries' => '/usr/local/Cellar/ffmpeg/4.1.3_1/bin/ffmpeg',
'ffprobe.binaries' => '/usr/local/Cellar/ffmpeg/4.1.3_1/bin/ffprobe',
'timeout' => 3600, // The timeout for the underlying process
'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use
));
不知道什么原因报楼上的错误
一个视频有多条音频,怎么提取特定的一条音频?
@Summer 根据该拓展包的issues,新版本的ffmpeg如果用格式转换需要这样用
ffmpeg 太占资源了。看到进程了出现ffmpeg就哆嗦,CPU直接满格
大佬 pcm怎么转wav
open打开失败
由于环境ubuntu版本不一样,用楼主的方法安装不了了,
环境是课程里的:
vagrant@homestead:~/code/myblog$ uname -a
Linux homestead 4.15.0-38-generic #41-Ubuntu SMP Wed Oct 10 10:59:38 UTC 2018 x86_64 x86_64 x86_64 GNU/Linu
后来参考这一篇:www.jianshu.com/p/d461a27edf0d
下载源码包,再解压。再按教程一步步。
code.videolan.org/videolan/x264#
安装x264
最后安装成功:
可以处理 http://…./video.mp4 网络的视频,
有同学一起学习讨论么。
补充:在转码时,报了错,后来发现是没有安装libx264, libmp3lame,
要安装libx264, 上面有网址
sudo apt-get install yasm libmp3lame-dev
安装之后,再进入ffmpeg源码目录编译:
./configure –prefix=/usr/local/ffmpeg –enable-shared –disable-static –disable-doc –enable-ffplay –enable-libmp3lame –enable-libx264 –enable-gpl –disable-asm
make (这个时间较长,10分钟)
sudo make install
在命令行,转码几个文件试试,就好了。