一、FFmpeg的介绍和安装
FFmpeg是什么?
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。
FFmpeg怎么安装?
在官网下载安装包,这里我们选择最新的版本即可,首先解压安装包
tar -xjvf ffmpeg-3.3.4.tar.bz2
cd ffmpeg-3.3.4/
执行configure配置命令
./configure --enable-shared --prefix=/monchickey/ffmpeg
make
make install
这里有坑儿
执行configure配置的话,可能会出现错误:
yasm/nasm not found or too old. Use --disable-yasm for a crippled build.
If you think configure made a mistake, make sure you are using the latest
version from Git. If the Latest version fails, report the problem to the
f fmpeg-useraf fmpeg.org mailing list or IRC #ffmpeg on irc. freenode . net .
Include the Log file”config.log" produced by configure as this will help
solve the problem.
意思就是 yasm/nasm 包不存在或者很旧,可以使用–disable-yasm禁用这个选项编译或者可以安装一下yasm
在官网下载最新的yasm安装包
tar -xvzf yasm-1.3.0.tar.gz
cd yasm-1.3.0/
./configure
make
make install
编译参数都是默认的,直接安装到系统中即可
安装FFmpeg
安装成功之后继续回到ffmpeg解压后的目录,执行下面命令编译并安装
./configure --enable-shared --prefix=/monchickey/ffmpeg
make
make install
确认安装文件是否存在
make和make install会把ffmpeg相关执行程序、头文件、lib库安装在/monchickey/ffmpeg/下
cd /monchickey/ffmpeg/查看一下发现有bin,include,lib,share这4个目录:
(1) bin是ffmpeg主程序二进制目录
(2) include是C/C++头文件目录
(3) lib是编译好的库文件目录
(4) share是文档目录
进入bin,执行命令
./ffmpeg -version
这里有坑儿
查看FFmpeg版本时,可能会出现错误:
libavdevice.so.57: cannot open shared object file: No such file or directory
遇到这个问题不要慌,原因是lib目录未加载到链接到系统库中。
如何解决
进入/etc/ld.so.conf.d/目录
vim /etc/ld.so.conf.d/ffmpeg.conf
最后添加 /xxxx/ffmpeg/lib ,xxxx为自己的目录
二、FFmpeg命令介绍
FFmpeg命令
查看文件信息
ffmpeg -i input.mp4
我们在拿到视频文件时,可以通过这个命令看到视频的码率,分辨率等信息
转换编码格式
ffmpeg -i [input.file] -c:v libx264 output.mp4
ffmpeg -i [input.file] -c:v libx265 output.mp4
视频格式转换
ffmpeg -i out.mp4 -y out.avi
视频转Gif
ffmpeg -i out.mp4 -y out.gif
从0开始截10s转Gif
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 -y out.gif
视频转多张图片
每秒生成一个张图片
ffmpeg -i input_test.mp4 -vf fps=1 out%03d.png
每分钟生成一张图片
ffmpeg -i input_test.mp4 -vf fps=1/60 out%03d.png
截取视频中的某段视频
截取从2s开始10秒的视频
ffmpeg -ss 2 -i test.mp4 -t 10 -y -f out_test.mp4
视频分片(把视频切为一段一段)
ffmpeg -i test.mp4 -c copy -map 0 -f segment -segment_time 10 video/part-%d.mp4
截取视频中某个时间段的单张图片或多张图片
ffmpeg -ss 2 -i test.mp4 -r 1 -t 2 -y -f image2 image-%3.jpeg
单张图片或多张图片转视频
ffmpeg -loop 1 -i img%3d.png -t 10-y output.mp4
Gif转视频
ffmpeg -i input.gif -y output.mp4
多个视频合并
ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4
修改视频分辨率
ffmpeg -i input_test.mp4 -s 320*240 out_test.mp4
给视频添加音频
ffmpeg -i input.mp4 -i input1.mp3 -y output.mp4
提取视频中的音频
ffmpeg -i test.mp4 -vn -a:c copy out.mp3
视频静音
ffmpeg -i input.mp4 -an -vcodec copy output.mp4
音频合并
ffmpeg -i "concat:test1.mp3|test2.mp3" -acodec copy output.mp3
拼接视频
ffmpeg -i "concat:1.mp4|2.mp4|3.mp4" -c copy output.mp4
三、附录:FFmpeg的基本字符命令
-i 输入文件的地址
-y 表示直接覆盖已经存在的输出文件
-n 表示若某个输出文件已经存在则退出(若没有设置-y或-n选项,且某个输出文件已经存在ffmpeg会询问是否要覆盖输出文件)
-codec(-c) 指定输入输出的解码编码器 copy 则将输入流直接复制到输出流不进行编解码操作
-c:v 或-vcodec 可以为所有视频流指定编码器,-c:v:1为第2个视频流指定编解码器。xvid(使用XVID编码压缩视频,不能改的)
-c:a 或-acodec可以为所有音频流指定编码器,-c:a:12为第13个视频流指定编解码器。
-vol 音量
-ss 选项用于设置流的开始时间,可以设置输入输出或者滤镜。在开始时间之前的帧将被跳过不被处理(输入不被解码,输出不被编码,滤镜不被处理)。
例:ffmpeg -ss 2 -t 10 -i test.mp4 test.mov
时长的格式:如-t 10, -t 23.167 时分秒: 如-t 10:23, -t 21:31:00.233
-s 设置帧的大小 例:ffmpeg -i test.mp4 -s 1080x680 out.mp4
-t 选项用于用于设置输入输出,-t在-i前可以限制输入时长,-t在输出文件前可以限制输出时长
-to 选项类似于-t选项,不同的是-to指定结束时刻,-t指定持续时间
-f 强制设置输入输出的文件格式,默认情况下ffmpeg会根据文件后缀名判断文件格式
-filter / -filter_complex 使用过滤器对流进行处理 复杂过滤器
-vf 代替-filter:v处理视频流
-b-b:a 指定音频码率。 b 是 bitrate的缩写, a是 audio的缩写
-b:v 指定视频码率。 b 是 bitrate的缩写, v是 video的缩写
-threads 设置处理线程数 例:ffmpeg -threads 8 -i test.mp4 out.mp4
-vframes 设置要输出的视频帧的数量: 例:ffmpeg -i test.mp4 -vframes 10 test.mov
-aframes 设置要输出的音频帧的数量。这是-frames:a的一个过时的别名。
-shortest 当最短的输入流结束后即停止编码和输出 例:ffmpeg -i bgm.mp3 -i test.mp4 -shortest output.mp4
-r 设置某个流的帧率按ffmpeg官方文档说-r与-framerate作用相同,但实际测试时发现不同。-framerate 用于限制输入,而-r用于限制输出 例:ffmpeg -i test.mp4 -r:v 30 test.mov
-aspect -aspect [:stream_specifier] 宽高比(输出,每个流) 设置方面指定的视频显示宽高比。aspect可以是浮点数字符串,也可以是num:den形式的字符串,其中num和den是宽高比的分子和分母。例如“4:3”,“16:9”,“1.3333”和“1.7777”是有效的参数值。如果与-vcodec副本一起使用,则会影响存储在容器级别的宽高比,但不会影响存储在编码帧中的宽高比(如果存在)。
-vn 不将视频流写到输出文件中无视频的意思 例:ffmpeg -i test.mp4 -vn -a:c copy out.mp3
-an 不将音频流写到输出文件中无音频的意思 例:ffmpeg -i test.mp4 -v:c copy -an out.mp4
四、业务知识
关于音视频需要了解的东西
音/视频流
在音视频领域,我们把一路音/视频称为一路流。如我们小时候经常使用VCD看港片,在里边可以选择粤语或国语声音,其实就是CD视频文件中存放了两路音频流,用户可以选择其中一路进行播放。
容器
我们熟悉的mp4,rmvb,mkv,avi是多媒体容器文件格式(或称多媒体封装格式),所谓容器是指将不同的数据流(视频流,音频流,字幕流等)封装在一个文件(载体)中。 播放时各种流分别进行解码等处理后,然后输出到显示器和音响等设备进行播放。多媒体容器格式不同于编码格式,一个容器中可以封装多种编码格式的媒体流。 流封装了实际的媒体数据,如视频流,音频流和字幕流等。一般情况下,流中的数据只能使用一种编码格式。
channel
是音频中的概念,称之为声道。在一路音频流中,可以有单声道,双声道或立体声。
帧率
帧率(frames per second, fps)是每秒画面刷新的次数,帧率越高视频越流畅。一般来说30fps就是可以接受的,60fps则可以明显提升交互感和逼真感,但是一般超过75fps一般就不容易察觉到有明显的流畅度提升了。
分辨率
分辨率表示画面的精细程度,通常用像素密度来表示,常用的单位为ppi(像素每英寸)。通常像素密度越高画面越精细,模糊程度越低。对于视频文件而言,像素密度是无法控制的(由播放器和显示设备决定)。我们通常用视频的像素数来表示它的分辨率如1080x640, 640x320等。
比特率
比特率(bit rate)又称码率,表示多媒体流每秒输出的字节数,单位为KB/s,Kbps等。同样的压缩算法下,比特率越高音视频的质量越好。
可变码率(Variable Bitrate, VBR)
指的是编码器的输出码率可以根据输入源信号的复杂度进行自适应调整,以在输出质量保持不变的条件下尽可能减少数据量。VBR适用于存储,不太适用流式传输。
固定码率(Constant Bitrate, CBR)
指的是编码器输出码率固定,CBR不适合存储,对于复杂内容可能没有足够码率进行编码,从而导致质量下降,同时会在简单内容部分浪费一些码率。
采样率
每秒钟对音频信号的采样次数,采样频率越高声音还原度越高,声音更加自然,单位是赫兹 Hz。音频文件一般使用的采样率是 44.1kHz,也就是一秒钟采样44100次,实验发现低于这个值就会有较明显的损失,而高于这个值人的耳朵已经很难分辨,而且增大了数字音频所占用的空间。
视频编码
视频流可以看做图片的序列,我们把这个序列中的一张图片称为一帧。若存储视频中所有帧则会数据量过大,不便于存储和传输。所幸统计表明大多数视频相邻帧之间的区别并不大,所以对于一段变化不大的视频,我们可以先完整编码帧A,其后的B帧只需要编码与A帧不同的部分,B帧后的C帧则只编码与B帧的差异。如此递推,将一段视频编码为一个序列。当某个图像与之前的图像变化很大无法参考前面的帧来生成,我们就结束上一个序列将该帧完整编码开始一个新的序列。
H264是目前流行的一种视频编码算法,它定义了三种帧:完整编码的I帧,参考I帧生成只包含差异的P帧,以及以及参考前后帧编码的B帧。
H264采用的核心算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压缩是生成B帧和P帧的算法。通常,我们也把完整编码的I帧称为关键帧。因为解码非关键帧需要解码其参考的帧,因此在截图等不需要全部解码的操作中,经常截取关键帧以提升性能。
推荐比特率
阿里云给的建议