FFMPEG是特别强大的专门用于处理音视频的开源库。你既可以使用它的API对音视频进行处理,也可以使用它提供的工具,如 ffmpeg, ffplay, ffprobe,来编辑你的音视频文件。

命令基本格式及参数

ffmpeg [global_options] {[input_file_options] -i input_url} ...
                         {[output_file_options] output_url} ...

ffmpeg 通过 -i 选项读取输任意数量的输入“文件”(可以是常规文件,管道,网络流,抓取设备等,并写入任意数量的输出“文件。

可以将 FFMPEG 命令分成以下几类:

基本信息查询命令

FFMPEG 可以使用下面的参数进行基本信息查询。例如,想查询一下现在使用的 FFMPEG 都支持哪些 filter,就可以用 ffmpeg -filters 来查询。详细参数说明如下:

命令 作用

FFmpeg -version 显示版本  
-formats    显示可用的格式(包括设备)  
-demuxers   显示可用的demuxers  
-muxers 显示可用的muxers  
-devices    显示可用的设备  
-codecs 显示已知的所有编解码器  
-decoders   显示可用的解码器  
-encoders   显示所有可用的编码器  
-bsfs   显示可用的比特流filter  
-protocols  显示可用的协议  
-filters    显示可用的过滤器  
-pix_fmts   显示可用的像素格式  
-sample_fmts    显示可用的采样格式  
-layouts    显示channel名称和标准channel布局  
-colors 显示识别的颜色名称  

录制

首先通过下面的命令查看一下 linux 上都有哪些设备。

ffmpeg -f avfoundation -list_devices true -i ""

录屏

ffmpeg -f avfoundation -i 1 -r 30 out.yuv

-f 指定使用 avfoundation 采集数据。 -i 指定从哪儿采集数据,它是一个文件索引号。在我的MAC上,1代表桌面(可以通过上面的命令查询设备索引号)。 -r 指定帧率。按ffmpeg官方文档说-r与-framerate作用相同,但实际测试时发现不同。-framerate 用于限制输入,而-r用于限制输出。 注意,桌面的输入对帧率没有要求,所以不用限制桌面的帧率。其实限制了也没用。

录屏+声音

ffmpeg -f avfoundation -i 1:0 -r 29.97 -c:v libx264 -crf 0 -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k out.flv

-i 1:0 冒号前面的 “1” 代表的屏幕索引号。冒号后面的"0"代表的声音索相号。
-c:v 与参数 -vcodec 一样,表示视频编码器。c 是 codec 的缩写,v 是video的缩写。
-crf 是 x264 的参数。 0 表式无损压缩。
-c:a 与参数 -acodec 一样,表示音频编码器。
-profile 是 fdk_aac 的参数。 aac_he_v2 表式使用 AAC_HE v2 压缩数据。
-b:a 指定音频码率。 b 是 bitrate的缩写, a是 audio的缩与。

录视频

ffmpeg -framerate 30 -f avfoundation -i 0 out.mp4

-framerate 限制视频的采集帧率。这个必须要根据提示要求进行设置,如果不设置就会报错。
-f 指定使用 avfoundation 采集数据。
-i 指定视频设备的索引号。

录音

ffmpeg -f avfoundation -i :0 out.wav

录制音频裸数据

ffmpeg -f avfoundation -i :0 -ar 44100 -f s16le out.pcm

分解/复用

抽取音频流

ffmpeg -i input.mp4 -acodec copy -vn out.aac

acodec: 指定音频编码器,copy 指明只拷贝,不做编解码。 vn: v 代表视频,n 代表 no 也就是无视频的意思。

抽取视频流

ffmpeg -i input.mp4 -vcodec copy -an out.h264

vcodec: 指定视频编码器,copy 指明只拷贝,不做编解码。 an: a 代表视频,n 代表 no 也就是无音频的意思。

转格式

ffmpeg -i out.mp4 -vcodec copy -acodec copy out.flv

上面的命令表式的是音频、视频都直接 copy,只是将 mp4 的封装格式转成了flv。

音视频合并

ffmpeg -i out.h264 -i out.aac -vcodec copy -acodec copy out.mp4

处理原始数据

提取YUV数据

ffmpeg -i input.mp4 -an -c:v rawvideo -pixel_format yuv420p out.yuv ffplay -s wxh out.yuv

-c:v rawvideo 指定将视频转成原始数据 -pixel_format yuv420p 指定转换格式为yuv420p

YUV转H264

ffmpeg -f rawvideo -pix_fmt yuv420p -s 320x240 -r 30 -i out.yuv -c:v libx264 -f rawvideo out.h264

提取PCM数据

ffmpeg -i out.mp4 -vn -ar 44100 -ac 2 -f s16le out.pcm ffplay -ar 44100 -ac 2 -f s16le -i out.pcm

滤镜

在编码之前,ffmpeg可以使用libavfilter库中的过滤器处理原始音频和视频帧。 几个链式过滤器形成一个过滤器图形。 ffmpeg区分两种类型的过滤器图形:简单和复杂。 添加水印

ffmpeg -i out.mp4 -vf "movie=logo.png,scale=64:48[watermask];[in][watermask] overlay=30:10 [out]" water.mp4

-vf中的 movie 指定logo位置。scale 指定 logo 大小。overlay 指定 logo 摆放的位置。

删除水印

先通过 ffplay 找到要删除 LOGO 的位置

ffplay -i test.flv -vf delogo=x=806:y=20:w=70:h=80:show=1

使用 delogo 滤镜删除 LOGO

ffmpeg -i test.flv -vf delogo=x=806:y=20:w=70:h=80 output.flv

视频缩小一倍

ffmpeg -i out.mp4 -vf scale=iw/2:-1 scale.mp4

-vf scale 指定使用简单过滤器 scale,iw/2:-1 中的 iw 指定按整型取视频的宽度。 -1 表示高度随宽度一起变化。

视频裁剪

ffmpeg -i VR.mov -vf crop=in_w-200:in_h-200 -c:v libx264 -c:a copy -video_size 1280x720 vr_new.mp4

crop 格式:crop=out_w:out_h: x :y

out_w: 输出的宽度。可以使用 in_w 表式输入视频的宽度。 out_h: 输出的高度。可以使用 in_h 表式输入视频的高度。 x : X坐标 y : Y坐标 如果 x和y 设置为 0,说明从左上角开始裁剪。如果不写是从中心点裁剪。

倍速播放

ffmpeg -i out.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" speed2.0.mp4

-filter_complex 复杂滤镜,[0:v]表示第一个(文件索引号是0)文件的视频作为输入。setpts=0.5*PTS表示每帧视频的pts时间戳都乘0.5 ,也就是差少一半。[v]表示输出的别名。音频同理就不详述了。 map 可用于处理复杂输出,如可以将指定的多路流输出到一个输出文件,也可以指定输出到多个文件。"[v]" 复杂滤镜输出的别名作为输出文件的一路流。上面 map的用法是将复杂滤镜输出的视频和音频输出到指定文件中。

对称视频

ffmpeg -i out.mp4 -filter_complex "[0:v]pad=w=2*iw[a];[0:v]hflip[b];[a][b]overlay=x=w" duicheng.mp4

画中画

ffmpeg -i out.mp4 -i out1.mp4 -filter_complex "[1:v]scale=w=176:h=144:force_original_aspect_ratio=decrease[ckout];[0:v][ckout]overlay=x=W-w-10:y=0[out]" -map "[out]" -movflags faststart new.mp4

录制画中画

ffmpeg -f avfoundation -i "1" -framerate 30 -f avfoundation -i "0:0" -r 30 -c:v libx264 -preset ultrafast -c:a libfdk_aac -profile:a aac_he_v2 -ar 44100 -ac 2 -filter_complex "[1:v]scale=w=176:h=144:force_original_aspect_ratio=decrease[a];[0:v][a]overlay=x=W-w-10:y=0[out]" -map "[out]" -movflags faststart -map 1:a b.mp4

多路视频拼接

ffmpeg -f avfoundation -i "1" -framerate 30 -f avfoundation -i "0:0" -r 30 -c:v libx264 -preset ultrafast -c:a libfdk_aac -profile:a aac_he_v2 -ar 44100 -ac 2 -filter_complex "[0:v]scale=320:240[a];[a]pad=640:240[b];[b][1:v]overlay=320:0[out]" -map "[out]" -movflags faststart -map 1:a c.mp4

滤镜加水印

ffmpeg -i killer.mp4 -filter_complex "movie=./logo/daka.png,scale=64:48[w];[0:v]curves=vintage[o];[o][w]overlay=30:10[out]" -map "[out]" -map 0:a test1.mp4

切割与合并

裁剪

ffmpeg -i out.mp4 -ss 00:00:00 -t 10 out1.mp4

-ss 指定裁剪的开始时间,精确到秒 -t 被裁剪后的时长。

视频合并

首先创建一个 inputs.txt 文件,文件内容如下: file '1.flv' file '2.flv' file '3.flv'

然后执行下面的命令:

ffmpeg -f concat -i inputs.txt -c copy output.flv

音频合并

ffmpeg -i text.mp3 -i silenceall.mp3 -filter_complex '[0:0] [1:0] concat=n=2:v=0:a=1 [a]' -map [a] test.mp3

音频混音

ffmpeg -i test.mp4 -i test.mp3 -filter_complex "[0:a] [1:a]amerge=inputs=2[aout]" -map "[aout]" -ac 2 mix_amerge.aac

hls切片

ffmpeg -i out.mp4 -c:v libx264 -c:a libfdk_aac -strict -2 -f hls out.m3u8

-strict -2 指明音频使有AAC。 -f hls 转成 m3u8 格式。

图/视互转

视频转JPEG

ffmpeg -i test.flv -r 1 -f image2 image-%3d.jpeg

视频转gif

ffmpeg -i out.mp4 -ss 00:00:00 -t 10 out.gif

图片转视频

ffmpeg -f image2 -i image-%3d.jpeg images.mp4

视频流处理

推流

ffmpeg -re -i out.mp4 -c copy -f flv rtmp://server/live/streamName

拉流保存

ffmpeg -i rtmp://server/live/streamName -c copy dump.flv

转流

ffmpeg -i rtmp://server/live/originalStream -c:a copy -c:v copy -f flv rtmp://server/live/h264Stream

实时推流

ffmpeg -framerate 15 -f avfoundation -i "1" -s 1280x720 -c:v libx264 -f flv rtmp://localhost:8080/live/room

本文链接:http://nix.pub/article/ffmpeg/