1.ffmpeg介绍
FFMPEG 目录及作用
- libavcodec: 提供了一系列编码器的实现。
- libavformat: 实现在流协议,容器格式及其本IO访问。
- libavutil: 包括了hash器,解码器和各利工具函数。
- libavfilter: 提供了各种音视频过滤器。
- libavdevice: 提供了访问捕获设备和回放设备的接口。
- libswresample: 实现了混音和重采样。
- libswscale: 实现了色彩转换和缩放工能。
FFMPEG基本概念
-
音/视频流
在音视频领域,我们把一路音/视频称为一路流。如我们小时候经常使用DVD看港片,在里边可以选择粤语或国语声音,其实就是CD视频文件中存放了两路音频流,用户可以选择其中一路进行播放。
-
容器
我们一般把 MP4、 FLV、MOV等文件格式称之为容器。也就是在这些常用格式文件中,可以存放多路音视频文件。以 MP4 为例,就可以存放一路视频流,多路音频流,多路字幕流。
-
channel
channel是音频中的概念,称之为声道。在一路音频流中,可以有单声道,双声道或立体声。
2.ffmpeg命令
1.ffmpeg命令简介
FFmpeg的bin目录中提供了3个命令(可执行程序),可以直接在命令行上使用。
ffmpeg:
ffmpeg的主要作用:对音视频进行编解码。
# 将MP3文件转成WAV文件
ffmpeg -i xx.mp3 yy.wav
当输入命令ffmpeg时,可以看到ffmpeg命令的使用格式是:
ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
简化一下,常用格式是:
ffmpeg arg1 arg2 -i arg3 arg4 arg5
- arg1:全局参数
- arg2:输入文件参数
- arg3:输入文件
- arg4:输出文件参数
- arg5:输出文件
ffprobe:
ffprobe的主要作用:查看音视频的参数信息。
# 可以查看MP3文件的采样率、比特率、时长等信息
ffprobe xx.mp3
当输入命令ffprobe时,可以看到ffprobe命令的使用格式是:
ffprobe [OPTIONS] [INPUT_FILE]
# OPTIONS:参数
# INPUT_FILE:输入文件
ffplay:
ffplay的主要作用:播放音视频。
# 播放MP3文件
ffplay xx.mp3
当输入命令ffplay时,可以看到ffplay命令的使用格式是:
ffplay [options] input_file
# options:参数
# input_file:输入文件
**补充:*增加-hide_bannder*参数可以隐藏一些冗余的描述信息,可以去实践比较以下2条命令的区别。
2.ffmpeg音视频处理流程
3.ffmpeg命令分类
FFmpeg主要参数
参数 | 说明 |
---|---|
-f fmt(输入/输出) | 强制输入或输出文件格式。 格式通常是自动检测输入文件,并从输出文件的文件扩展名中猜测出来,所以在大多数情况下这个选项是不需要的。 |
-i url(输入) | 输入文件的网址 |
-y(全局参数) | 覆盖输出文件而不询问。 |
-n(全局参数) | 不要覆盖输出文件,如果指定的输出文件已经存在,请立即退出。 |
-c [:stream_specifier] codec(输入/输出,每个流) | 选择一个编码器(当在输出文件之前使用)或解码器(当在输入文件之前使用时)用于一个或多个流。codec 是解码器/编码器的名称或 copy(仅输出)以指示该流不被重新编码。如:ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT |
-codec [:stream_specifier]编解码器(输入/输出,每个流) | 同 -c |
-t duration(输入/输出) | 当用作输入选项(在-i之前)时,限制从输入文件读取的数据的持续时间。当用作输出选项时(在输出url之前),在持续时间到达持续时间之后停止输出。 |
-ss位置(输入/输出) | 当用作输入选项时(在-i之前),在这个输入文件中寻找位置。 请注意,在大多数格式中,不可能精确搜索,因此ffmpeg将在位置之前寻找最近的搜索点。 当转码和-accurate_seek被启用时(默认),搜索点和位置之间的这个额外的分段将被解码和丢弃。 当进行流式复制或使用-noaccurate_seek时,它将被保留。当用作输出选项(在输出url之前)时,解码但丢弃输入,直到时间戳到达位置。 |
-frames [:stream_specifier] framecount(output,per-stream) | 停止在帧计数帧之后写入流。 |
-filter [:stream_specifier] filtergraph(output,per-stream) | 创建由filtergraph指定的过滤器图,并使用它来过滤流。filtergraph是应用于流的filtergraph的描述,并且必须具有相同类型的流的单个输入和单个输出。在过滤器图形中,输入与标签中的标签相关联,标签中的输出与标签相关联。有关filtergraph语法的更多信息,请参阅ffmpeg-filters手册。 |
视频参数
参数 | 说明 |
---|---|
-vframes num(输出) | 设置要输出的视频帧的数量。对于-frames:v,这是一个过时的别名,您应该使用它。 |
-r [:stream_specifier] fps(输入/输出,每个流) | 设置帧率(Hz值,分数或缩写)。作为输入选项,忽略存储在文件中的任何时间戳,根据速率生成新的时间戳。这与用于-framerate选项不同(它在FFmpeg的旧版本中使用的是相同的)。如果有疑问,请使用-framerate而不是输入选项-r。作为输出选项,复制或丢弃输入帧以实现恒定输出帧频fps。 |
-s [:stream_specifier]大小(输入/输出,每个流) | 设置窗口大小。作为输入选项,这是video_size专用选项的快捷方式,由某些分帧器识别,其帧尺寸未被存储在文件中。作为输出选项,这会将缩放视频过滤器插入到相应过滤器图形的末尾。请直接使用比例过滤器将其插入到开头或其他地方。格式是’wxh’(默认 - 与源相同)。 |
-aspect [:stream_specifier] 宽高比(输出,每个流) | 设置方面指定的视频显示宽高比。aspect可以是浮点数字符串,也可以是num:den形式的字符串,其中num和den是宽高比的分子和分母。例如“4:3”,“16:9”,“1.3333”和“1.7777”是有效的参数值。如果与-vcodec副本一起使用,则会影响存储在容器级别的宽高比,但不会影响存储在编码帧中的宽高比(如果存在)。 |
-vn(输出) | 禁用视频录制。 |
-vcodec编解码器(输出) | 设置视频编解码器。这是-codec:v的别名。 |
-vf filtergraph(输出) | 创建由filtergraph指定的过滤器图,并使用它来过滤流。 |
音频参数
参数 | 说明 |
---|---|
-aframes(输出) | 设置要输出的音频帧的数量。这是-frames:a的一个过时的别名。 |
-ar [:stream_specifier] freq(输入/输出,每个流) | 设置音频采样频率。对于输出流,它默认设置为相应输入流的频率。对于输入流,此选项仅适用于音频捕获设备和原始分路器,并映射到相应的分路器选件。 |
-ac [:stream_specifier]通道(输入/输出,每个流) | 设置音频通道的数量。对于输出流,它默认设置为输入音频通道的数量。对于输入流,此选项仅适用于音频捕获设备和原始分路器,并映射到相应的分路器选件。 |
-an(输出) | 禁用录音。 |
-acodec编解码器(输入/输出) | 设置音频编解码器。这是-codec的别名:a。 |
-sample_fmt [:stream_specifier] sample_fmt(输出,每个流) | 设置音频采样格式。使用-sample_fmts获取支持的样本格式列表。 |
-af filtergraph(输出) | 创建由filtergraph指定的过滤器图,并使用它来过滤流。 |
4.基本信息查询命令
FFMPEG 可以使用下面的参数进行基本信息查询。例如,想查询一下现在使用的 FFMPEG 都支持哪些 filter,就可以用 ffmpeg -filters 来查询。详细参数说明如下:
*参数* | *说明* |
---|---|
-version | 显示版本。 |
-formats | 显示可用的格式(包括设备)。 |
-demuxers | 显示可用的demuxers。 |
-muxers | 显示可用的muxers。 |
-devices | 显示可用的设备。 |
-codecs | 显示libavcodec已知的所有编解码器。 |
-decoders | 显示可用的解码器。 |
-encoders | 显示所有可用的编码器。 |
-bsfs | 显示可用的比特流filter。 |
-protocols | 显示可用的协议。 |
-filters | 显示可用的libavfilter过滤器。 |
-pix_fmts | 显示可用的像素格式。 |
-sample_fmts | 显示可用的采样格式。 |
-layouts | 显示channel名称和标准channel布局。 |
-colors | 显示识别的颜色名称。 |
5.录制命令
查看dshow支持的设备: ffmpeg -f avfoundation -list_devices true -i ''
录制屏幕:
// 录制屏幕
ffmpeg -f avfoundation -i 1 -r 30 out.yuv
// 播放
ffplay -s 2500x1600 -pix_fmt uyvy422 out.yuv
录制音频:
// 录制声音
ffmpeg -f avfoundation -i:0 out.yuv
// 播放
ffplay out.yuv
录屏幕+声音:
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
录视频+音频:
ffmpeg -framerate 30 -f avfoundation -i 0:0 out.mp4
录制音频裸数据:
ffmpeg -f avfoundation -i :0 -ar 44100 -f s16le out.pcm
6.分解/复用命令
流拷贝是通过将 copy 参数提供给-codec选项来选择流的模式。它使得ffmpeg省略了指定流的解码和编码步骤,所以它只能进行多路分解和多路复用。 这对于更改容器格式或修改容器级元数据很有用。
由于没有解码或编码,速度非常快,没有质量损失。 但是,由于许多因素,在某些情况下可能无法正常工作。 应用过滤器显然也是不可能的,因为过滤器处理未压缩的数据。
抽取音频流
fmpeg -i input.mp4 -acodec copy -vn out.aac
- acodec: 指定音频编码器,copy 指明只拷贝,不做编解码
- vn: v 代表视频,n 代表 no 也就是无视频的意思。
抽取视频流
ffmpeg -i input.mp4 -vcodec copy -an out.h264
转格式
ffmpeg -i out.mp4 -vcodec copy -acodec copy out.flv
音视频合并
ffmpeg -i out.h264 -i out.aac -vcodec copy -acodec copy out.mp4
7.处理原始数据命令
提取YUV数据
ffmpeg -i input.mp4 -an -c:v rawvideo -pixel_format yuv420p out.yuv
ffplay -s wxh out.yuv
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
PCM转WAV
ffmpeg -f s16be -ar 8000 -ac 2 -acodec pcm_s16be -i input.raw output.wav
8.滤镜命令
简单滤镜 :简单的过滤器图是那些只有一个输入和输出,都是相同的类型。
复杂滤镜 : 复杂的过滤器图是那些不能简单描述为应用于一个流的线性处理链的过滤器图。
添加水印
ffmpeg -i out.mp4 -vf "movie=logo.png,scale=64:48[watermask];[in][watermask] overlay=30:10 [out]" water.mp4
删除水印
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
倍速播放
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 -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
9.裁剪与合并命令
裁剪
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 out1.mp4
合并
首先创建一个 inputs.txt 文件,文件内容如下:
file '1.flv'
file '2.flv'
file '3.flv'
然后执行下面的命令:
ffmpeg -f concat -i inputs.txt -c copy output.flv
hls切片
ffmpeg -i out.mp4 -c:v libx264 -c:a libfdk_aac -strict -2 -f hls out.m3u8
- -strict -2 指明音频使有AAC。
- -f hls 转成 m3u8 格式
10.图片与视频互转
视频转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
11.直播相关命令
推流
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:1935/live/room
播放YUV 数据
ffplay -pix_fmt nv12 -s 192x144 1.yuv
播放YUV中的 Y平面
ffplay -pix_fmt nv21 -s 640x480 -vf extractplanes='y' 1.yuv