本文目录一览:
FFmpeg工具
ffmpeg在做音视频编解码时非常方便,所以很多场景下转码使用的是ffmpeg,通过ffmpeg –-help可以看到ffmpeg常见的命令大概分为六部分:
命令格式如下:
下面罗列一些ffmpeg常用的信息查询命令:
1、查询版本信息
2、ffmpeg查询是否支持对应的视频文件格式
使用ffmpeg转吗,有时候可能会遇到无法解析的视频文件或者无法生成视频文件,报错提示不支持生成对应的视频文件,这时候就需要查看当前使用的ffmpeg是否支持对应的视频文件格式,需要使用ffmpeg -formats参数来查看:-ffplay播放多个文件
根据上面输出的信息可以看到,输出的内容分为3个部分,具体如下。
输出信息中包含了三部分内容,具体如下。
输出信息的内容分为四列,具体如下。
从输出的帮助信息中可以看到,FLV的muxer的信息包含两大部分,具体如下。
从输出的帮助信息可以看到,FLV的demuxer的信息包含两大部分:
从帮助信息可以看到,H.264(AVC)的编码参数包含两大部分,具体如下。
从帮助信息可以看到,H.264(AVC)的解码参数查看包括两大部分,具体如下:
从帮助信息可以看到,colorkey滤镜查看信息包含两大部分,具体如下。
ffmpeg的封装转换(转封装)功能包含在AVFormat模块中,通过libavformat库进行Mux和Demux操作;多媒体文件的格式有很多种,这些格式中的很多参数在Mux与Demux的操作参数中是公用的,下面来详细介绍一下这些公用的参数。-ffplay播放多个文件
通过查看ffmpeg --help full信息,找到AVFormatContext参数部分,该参数下的所有参数均为封装转换可使用的参数。下表列出了ffmpeg AVFormatContext的主要参数及说明。-ffplay播放多个文件
这些都是通用的封装、解封装操作时使用的参数,后续章节中介绍转封装操作、解封装操作、封装操作时,上述参数可以与对应的命令行参数搭配使用。
ffmpeg编解码部分的功能主要是通过模块AVCodec来完成的,通过libavcodec库进行Encode与Decode操作。多媒体编码格式的种类有很多,但是还是有很多通用的基本操作参数设置,下面来详细介绍这些公用的参数。-ffplay播放多个文件
通过命令ffmpeg --help full可以看到AVCodecContext参数列表信息。该选项下面的所有参数均为编解码可以使用的参数。
ffmpeg还有一些更细化的参数,本节中并未详细提及,可以根据本节中提到的查看方法查看ffmpeg的帮助文件以查看更多的内容,本节中介绍的是重点及常用的通用参数,后续章节中介绍编码操作时,上述参数可以配合对应的例子使用。-ffplay播放多个文件
ffmpeg工具的主要用途为编码、解码、转码以及媒体格式转换,ffmpeg常用于进行转码操作,使用ffmpeg转码的主要原理如图
通过之前介绍的参数,可以设置转码的相关参数,如果转码操作频涉及封装的改变,则可以通过设置AVCodec与AVFormat的操作参数进行封装与编码的改变,下面示例:
从输出信息中可以看到,以上输出的参数中使用了前面介绍过的参数,具体如下。
在 FFmpeg套件中,除了ffmpeg作为多媒体处理工具之外,还有ffprobe多媒体信息查看工具,ffprobe主要用来查看多媒体文件的信息,下面就来看一下ffprobe中常见的基本命令。
usage: ffprobe [OPTIONS] [INPUT_FILE] the other
ffprobe常用的参数比较多,可以通过ffprobe --help来查看详细的帮助信息。
这些输出的帮助信息既是ffprobe常用的操作参数,也是ffrpobe的基础参数。例如查看log,查看每一个音频数据包信息或者视频数据包信息,查看节目信息,查看流信息,查看每一个流有多少帧以及每一个流有多少个音视频包,查看视频像素点的格式等。下面就来根据以上的输出参数重点列举几个例子。-ffplay播放多个文件
1)使用下面的命令,查看多媒体数据包信息:
通过show_packets查看的多媒体数据包信息使用PACKET标签括起来,其中包含的信息主要如下:
2)除了以上字段和信息之外,还可以通过如下的组合参数来查看包中的具体数据:
和上面的比起来多了一个data字段,具体如下
[PACKET]
codec_type=video
stream_index=0
pts=379904
pts_time=24.733333
dts=379904
dts_time=24.733333
duration=512
duration_time=0.033333
size=2010
pos=3272564
flags=__
data=
00000000: 0000 07d6 419a cc21 3ffa 5800 0031 9893 ....A..!?.X..1..
00000010: d7e7 0641 039b 27c5 e0f8 5175 1abc 0e4f ...A..'...Qu...O
00000020: d710 f401 3224 0093 a2e5 c07e 9c30 0003 ....2$.....~.0..
略过一大段数据
00000770: 1ebe 840a 5ac2 4f9a 614c 5697 8eab fef8 ....Z.O.aLV.....
00000780: 0b59 9647 cc6d 8a4b f8c0 89e8 798e f569 .Y.G.m.K....y..I
00000790: 2aca ec22 e1f5 d2e5 31b1 010e 7725 e127 *.."....1...w%.'
000007a0: c5f4 7051 f07b 8449 649f 3fab 6a3d 3913 ..pQ.{.Id.?.j=9.
000007b0: d9e4 bdd6 0f22 fa77 2b32 35f5 f4f7 5393 .....".w+25...S.
000007c0: 1c9d fe72 1550 ba41 c774 5031 96d5 aef5 ...r.P.A.tP1....
000007d0: f1b9 77a7 ad54 0800 010f ..w..T....
[/PACKET]
从输出的内容中可以看到多媒体包中包含的数据,那么我们可以根据上述输出内容中的pos,也就是文件偏移位置来查看,pos的值为3272564,将其转换为十六进制位置为0x31EF74,这就是这个包在flv文件中的偏移量,可以使用Linux下的xxd 1.mp4命令进行查看:-ffplay播放多个文件
0031ef70: 0000 000e 0000 07d6 419a cc21 3ffa 5800 ........A..!?.X.
0031ef80: 0031 9893 d7e7 0641 039b 27c5 e0f8 5175 .1.....A..'...Qu
0031ef90: 1abc 0e4f d710 f401 3224 0093 a2e5 c07e
0031efa0: 9c30 0003 389a 06b7 f211 fb06 362c 95a9 .0..8.......6,..
0031efb0: 0020 8f32 e280 6773 015e 78d2 87a3 e114 . .2..gs.^x.....
0031efc0: f3b3 9d2d ffd7 b202 2233 923f 3d42 bc7f ...-...."3.?=B..
可以看到从0x31EF74开始的数据和上面一致:0000 07d6 419a cc21 3ffa 5800。
通过ffprobe读取packets来进行对应的数据分析,使用show_packets与show_data配合可以进行更加精确的分析。
3)除了packets与data之外,ffprobe还可以分析多媒体的封装格式,其使用FORMAT标签括起来显示:
[FORMAT]
filename=1.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=25.704000
size=3307949
bit_rate=1029551
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2avc1mp41
TAG:encoder=Lavf55.33.100
[/FORMAT]
下面是对输出信息关键字段的说明:
4)使用下面的命令可以查看视频文件的帧信息,输出的帧信息将使用FRAME标签括起来:
[FRAME]
media_type=video
stream_index=0
key_frame=1
pts=0
pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
best_effort_timestamp=0
best_effort_timestamp_time=0.000000
pkt_duration=512
pkt_duration_time=0.033333
pkt_pos=22995
pkt_size=1888
width=720
height=1280
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
color_range=tv
color_space=bt709
color_primaries=bt709
color_transfer=bt709
chroma_location=left
[/FRAME]
通过-show-frames参数可以查看每一帧的信息,下面就来介绍一下其中重要的信息,
在Windows下常用的Elecard StreamEye工具中打开查看MP4时,会很直观地看到帧类型显示,用ffprobe的pict_type同样可以看到视频的帧是I帧,P帧或者B帧;每一帧的大小同样也可以通过ffprobe的pkt_size查看到。-ffplay播放多个文件
5)通过-show_streams参数可以查看到多媒体文件中的流信息,流的信息将使用STREAM标签括起来:
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=Main
codec_type=video
codec_tag_string=avc1
codec_tag=0x31637661
width=720
height=1280
coded_width=720
coded_height=1280
closed_captions=0
film_grain=0
has_b_frames=0
sample_aspect_ratio=N/A
display_aspect_ratio=N/A
pix_fmt=yuv420p
level=42
color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709
chroma_location=left
field_order=progressive
refs=1
is_avc=true
nal_length_size=4
id=0x1
r_frame_rate=30/1
avg_frame_rate=30/1
time_base=1/15360
start_pts=0
start_time=0.000000
duration_ts=388608
duration=25.300000
bit_rate=964695
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=759
nb_read_frames=N/A
nb_read_packets=N/A
extradata_size=39
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
DISPOSITION:captions=0
DISPOSITION:descriptions=0
DISPOSITION:metadata=0
DISPOSITION:dependent=0
DISPOSITION:still_image=0
TAG:language=und
TAG:handler_name=VideoHandler
TAG:vendor_id=[0][0][0][0]
[/STREAM]
如以上输出内容所示,从中可以看到流的信息,具体属性及说明如下表
fprobe 使用前面的参数可以获得key-value格式的显示方式,但是阅读起来因为习惯不同,可能有的人会认为方便,有的人认为不方便;如果要进行格式化的显示,这样就需要用到ffprobe -print_format 或者 ffprobe -of 参数来进行相应的格式输出,而-print_format 支持多种格式输出,包括XML,INI,JSON,CSV,FLAT等。下面列举几种常见的格式输出的例子 -ffplay播放多个文件
?xml version="1.0" encoding="UTF-8"?
ffprobe
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.33.100
Duration: 00:00:25.70, start: 0.000000, bitrate: 1029 kb/s
Stream #0:0 0x1 : Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 720x1280, 964 kb/s, 30 fps, 30 tbr, 15360 tbn (default)-ffplay播放多个文件
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1 0x2 : Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 72 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
streams
stream index="0" codec_name="h264" codec_long_name="H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" profile="Main" codec_type="video" codec_tag_string="avc1" codec_tag="0x31637661" width="720" height="1280" coded_width="720" coded_height="1280" closed_captions="0" film_grain="0" has_b_frames="0" pix_fmt="yuv420p" level="42" color_range="tv" color_space="bt709" color_transfer="bt709" color_primaries="bt709" chroma_location="left" field_order="progressive" refs="1" is_avc="true" nal_length_size="4" id="0x1" r_frame_rate="30/1" avg_frame_rate="30/1" time_base="1/15360" start_pts="0" start_time="0.000000" duration_ts="388608" duration="25.300000" bit_rate="964695" bits_per_raw_sample="8" nb_frames="759" extradata_size="39"-ffplay播放多个文件
disposition default="1" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0" captions="0" descriptions="0" metadata="0" dependent="0" still_image="0"/-ffplay播放多个文件
tag key="language" value="und"/
tag key="handler_name" value="VideoHandler"/
tag key="vendor_id" value="[0][0][0][0]"/
/stream
stream index="1" codec_name="aac" codec_long_name="AAC (Advanced Audio Coding)" profile="LC" codec_type="audio" codec_tag_string="mp4a" codec_tag="0x6134706d" sample_fmt="fltp" sample_rate="44100" channels="2" channel_layout="stereo" bits_per_sample="0" id="0x2" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/44100" start_pts="0" start_time="0.000000" duration_ts="1133511" duration="25.703197" bit_rate="72863" nb_frames="1107" extradata_size="2"-ffplay播放多个文件
disposition default="1" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0" captions="0" descriptions="0" metadata="0" dependent="0" still_image="0"/-ffplay播放多个文件
tag key="language" value="und"/
tag key="handler_name" value="SoundHandler"/
tag key="vendor_id" value="[0][0][0][0]"/
/stream
/streams
/ffprobe
从输出的内容可以看到,输出的内容格式为XML格式,如果原有的业务本身就可以解析XML格式,那么就不需要更改解析引擎,直接将输出内容输出为XML格式即可,解析引擎解析Packet信息是会更方便。
输出INI格式:
输出FLAT格式:
输出JSON格式:
输出CSV格式:
通过各种格式的输出,可以使用对应的绘图方式绘制出可视化图形。
CSV格式输出后可以使用Excel打开表格形式
可以在命令行中自行输出,输出的frame信息全部为视频相关的信息。
使用ffprobe还可以查看很多信息,我们可以通过本节介绍的help方法查看更多更详细的信息
在FFmpeg中通常使用ffplay作为播放器,其实ffplay同样也可作为很多音视频的图形化分析工具,通过ffplay可以看到视频图像的运动估计方向、音频数据的波形等,以下将介绍更多参数并举例说明。-ffplay播放多个文件
1)ffplay常用参数
ffplay不仅仅是播放器,同时也是测试ffmpeg的codec引擎、format引擎,以及filter引擎的工具,并且还可以进行可视化的媒体参数分析。其可以通过ffplay --help进行查看:-ffplay播放多个文件
Simple media player
usage: ffplay [options] input_file
Main options:
-L show license
-h topic show help
-? topic show help
-help topic show help
--help topic show help
-version show version
-buildconf show build configuration
-formats show available formats
-muxers show available muxers
-demuxers show available demuxers
-devices show available devices
-codecs show available codecs
-decoders show available decoders
-encoders show available encoders
-bsfs show available bit stream filters
-protocols show available protocols
-filters show available filters
-pix_fmts show available pixel formats
-layouts show standard channel layouts
-sample_fmts show available audio sample formats
-dispositions show available stream dispositions
-colors show available color names
-loglevel loglevel set logging level
-v loglevel set logging level
-report generate a report
-max_alloc bytes set maximum size of a single allocated block
-sources device list sources of the input device
-sinks device list sinks of the output device
-x width force displayed width
-y height force displayed height
-s size set frame size (WxH or abbreviation)
-fs force full screen
-an disable audio
-vn disable video
-sn disable subtitling
-ss pos seek to a given position in seconds
-t duration play "duration" seconds of audio/video
-bytes val seek by bytes 0=off 1=on -1=auto
-seek_interval seconds set seek interval for left/right keys, in seconds
-nodisp disable graphical display
-noborder borderless window
-alwaysontop window always on top
-volume volume set startup volume 0=min 100=max
-f fmt force format
-window_title window title set window title
-af filter_graph set audio filters
-showmode mode select show mode (0 = video, 1 = waves, 2 = RDFT)
-i input_file read specified file
-codec decoder_name force decoder
-autorotate automatically rotate video
这只是Main options里面的部分,另外还有Advanced options,AVCodecContext AVOptions等等很多内容。就上述帮助信息的输出所示,有些是前面已经介绍过的参数,这里就不再一一赘述,一些未介绍的参数说明见下表-ffplay播放多个文件
常见参数可以手动进行尝试,下面列举几个示例。
*如果希望从视频的第5秒开始播放,播放5秒钟的文件,则可以使用如下命令
*如果希望视频播放时播放器的窗口显示标题为自定义标题,则可以使用如下命令
*如果希望使用ffplay打开网络直播流,则可以使用如下命令:
可以看出ffplay可以支持的协议有多种,ramp,rtmp,http等等都支持。
显示如下窗口内容
下面将这些参数与前面介绍过的一些参数进行组合,举几个例子。
1⃣️从10秒播放一个视频,播放时长为5秒,播放完毕后自动退出ffplay,播放器的窗口标题为“Hello World”,为了确认播放时长正确,可以通过系统命令time查看命令运行时长:
可以看到输出结果如下:
ffplay -window_title "Hello World" -ss 10 -t 5 -autoexit 1.mp4 0.94s user 0.52s system 22% cpu 6.502 total-ffplay播放多个文件
2⃣️如果强制使用H.264解码器解码MPEG4的视频,将会报错
我们这个视频是h264编码,所以可以正常播放。
查看视频编码可以使用
查看ffmpeg支持的解码格式
下面这个方式解码就会报错
前面举过的例子中,我们看到的比较多的是单节目的流,多节目的流,常用于广电行业的视频。当视频中出现多个Program时,播放Program与常规的播放方式有所不同,需要指定对应的流,可以通过vst,ast,sst参数来指定,例如希望播放Program 13中的音视频流,视频编号为4,音频编号为5,则可以通过如下命令进行制定:-ffplay播放多个文件
有条件的朋友可以自己找视频来查看。
3⃣️如果使用ffplay播放视频时希望加载字幕文件,则可以通过加载ASS或者SRT字幕文件来解决,下面列举一个加载SRT字幕的例子,首先编辑SRT字幕文件,内容如下:
1
00:00:01.000 -- 00:00:05.000
这是我 我是谁
2
00:00:05.001 -- 00:00:10.000
我爱中国
3
00:00:10.001 -- 00:00:15.000
为人民服务
4
00:00:18.001 -- 00:00:20.000
疫情早日结束,国泰民安!
然后通过filter将字幕文件加载到播放数据中,使用命令如下:
播放的效果如下:
可以看出,视频中已经将SRT格式的文字字幕加入到视频中并展现了出来。
2)ffplay的数据可视化分析应用
使用ffplay除了可以播放视频流媒体文件之外,还可以作为可视化的视频流媒体分析工具,例如播放音频文件时,如果不确定文件的声音是否正常,则可以直接使用ffplay播放音频文件,播放的时候其将会把解码后的音频数据以音频波形的形式显示出来,-ffplay播放多个文件
命令行执行后的效果如下:
从图中可以看到,音频播放时的波形可以通过振幅显示出来,可以用来查看音频的播放情况。
当播放视频时想要体验解码器是如何解码每个宏块的,可以使用如下命令
新版FFmpeg此方法已经不再支持啦,可参考
我们可以使用ffmpeg或者ffplay来分析视频文件中的运动向量。ffmpeg的早期版本(2017年10月之前)也允许分析宏块,但此选项已被删除。
'codecview'过滤器可用于将运动向量显示为每个宏块的小箭头。它采用一个叫mv的选项,它指定了要绘制的运动向量的类型:
你可以使用如下的命令
第一条命令是直接用ffplay显示视频。
第二条命令是把生成的带有运动向量的视频保存到output.mp4中。
显示效果如下:
ffplay如何播放pcm文件
pcm文件是模拟音频信号经过数模转换后直接形成的二进制序列。这是一种十分罕见的音频文件格式。
可以通过以下步骤播放:
1、右键菜单第一个选项是“打开”,是因为我安装了可以打开该文件的Au。也可以直接双击打开。
2、之后就会有导入配置的选择
3、如果声道重合,波形就会叠加。听起来是粗犷的。
4、声音调整正常后,可以导出成文件,以后可以使用音频播放器直接播放。依次选择“文件-导出-文件”,或者直接快捷Ctrl加Shift加E,打开导出设置。
5.点击“格式设置”右侧的“更改”进行格式更改。格式设置界面,选择“波形音频”,导出的会是WAV文件。
6、直接在导出设置界面点击“格式”的下拉菜单,选择“MP3音频”。这里面也有无损输出的,选择“WavePCM”即是。
7、选择完成后,点击“确定”开始到处,等待导出完成即可。有损导出会有有损导出的警告提示弹窗,点击“是”继续即可。
8、最后就可以使用ffply进行播放了。
怎样播放DFF格式的音频文件
方法/步骤
首先,我们要百度一下,下载FOOBAR200程序,绿色版和安装包都可以,安装完毕,路径自选。
下载DFF解码包,文件不大,解压下来就是几个*.dll的文件。
解压文件到你FOOBAR2000安装目录下的components文件夹内。默认路径是:C:\Program Files\foobar2000
解压完成之后,我们进入FOOBAR2000选择文件并打开,按住shift可多选。
然后选择文件播放就可以尽情享受高品质音乐了。
ffmpeg 基本用法
1、libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能,包含demuxers和muxer库;
2、libavcodec:用于各种类型声音/图像编解码;
3、libavutil:包含一些公共的工具函数;
4、libswscale:用于视频场景比例缩放、色彩映射转换;
5、libpostproc:用于后期效果处理;
6、ffmpeg:是一个命令行工具,用来对视频文件转换格式,也支持对电视卡实时编码;
7、ffsever:是一个HTTP多媒体实时广播流服务器,支持时光平移;
8、ffplay:是一个简单的播放器,使用ffmpeg 库解析和解码,通过SDL显示;
在这组成部分中,需要熟悉基础概念有
容器(Container)
容器就是一种文件格式,比如flv,mkv等。包含下面5种流以及文件头信息。
流(Stream)
是一种视频数据信息的传输方式,5种流:音频,视频,字幕,附件,数据。
帧(Frame)
帧代表一幅静止的图像,分为I帧,P帧,B帧。
编解码器(Codec)
是对视频进行压缩或者解压缩,CODEC =COde (编码) +DECode(解码)
复用/解复用(mux/demux)
把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)
把不同的流从某种容器中解析出来,这种行为叫做解复用(demux)
1、FFmpeg程序把-i参数指定的若干文件内容读入到内存,按照输入的参数或者程序默认的参数来处理并且把结果写入到若干的文件中。输入和输出文件可以是计算机文件、管道、网络流、捕获设备等。
2、FFmpeg用libavformat包调用解复用器(demuxers)来读取输入文件中被编码的数据包(packets),如果有多个输入文件,FFmpeg以有效输入流的最小时间戳来同步,
3、然后解码器(decoder)从已编码的数据包中产生未被压缩的帧(frame),在那之后调用可选的过滤器。
4、这些帧被传递到编码器,编码器会产生新的编码包
5、把新的编码包传递给复用器(muxer)处理并且把结果写入到输出文件中。
在多媒体处理中,filter的意思是被编码到输出文件之前用来修改输入文件内容的一个软件工具。如:视频翻转,旋转,缩放等。
语法:[input_link_label1]… filter_name=parameters [output_link_label1]…
1、视频过滤器 -vf
如input.mp4视频按顺时针方向旋转90度
ffplay -i input.mp4 -vf transpose=1
如input.mp4视频水平翻转(左右翻转)
ffplay -i input.mp4 -vf hflip
2、音频过滤器 -af
实现慢速播放,声音速度是原始速度的50%
offplay input.mp3 -af atempo=0.5
过滤器链(Filterchain)
Filterchain = 逗号分隔的一组filter
语法:“filter1,filter2,filter3,…filterN-2,filterN-1,filterN”
顺时针旋转90度并水平翻转
ffplay -i input.mp4 -vf transpose=1,hflip
过滤器图(Filtergraph)
第一步: 源视频宽度扩大两倍。
ffmpeg -i jidu.mp4 -t 10 -vf pad=2*iw output.mp4
第二步:源视频水平翻转
ffmpeg -i jidu.mp4 -t 10 -vf hflip output2.mp4
第三步:水平翻转视频覆盖output.mp4
ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlay=w compare.mp4
是不是很复杂?
用带有链接标记的过滤器图(Filtergraph)只需一条命令
基本语法
Filtergraph = 分号分隔的一组filterchain
“filterchain1;filterchain2;…filterchainN-1;filterchainN”
Filtergraph的分类
1、简单(simple) 一对一
2、复杂(complex)多对一, 多对多
简单过滤器图处理流程:
复杂过滤器图处理流程:
对于刚才用三步处理的方式,用过滤器图可以这样做:
ffplay -f lavfi -i testsrc -vf split[a][b];[a]pad=2*iw[1];[b]hflip[2];[1][2]overlay=w
F1: split过滤器创建两个输入文件的拷贝并标记为[a],[b]
F2: [a]作为pad过滤器的输入,pad过滤器产生2倍宽度并输出到[1].
F3: [b]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[2].
F4: 用overlay过滤器把 [2]覆盖到[1]的旁边.
一些多媒体容器比如AVI,mkv,mp4等,可以包含不同种类的多个流,如何从容器中抽取各种流呢?
语法:
-map file_number[:stream_type][:stream_number]
这有一些特别流符号的说明:
1、-map 0 选择第一个文件的所有流
2、-map i:v 从文件序号i(index)中获取所有视频流, -map i:a 获取所有音频流,-map i:s 获取所有字幕流等等。
3、特殊参数-an,-vn,-sn分别排除所有的音频,视频,字幕流
tip:对比上面的图,可以知道,假设有两个文件ffmpeg -i fist.mp4 -i second.mp4 ..output.mp4
如果想去两个文件的音视频流 ffmpeg -i fist.mp4 -i second.mp4 map:0 -map 1 output.mp4
如果想去第一个文件的视频流,第二个文件的音频流ffmpeg -i fist.mp4 -i second.mp4 -map:v:0 -map:a:0 output.mp4
可用的bit流 :ffmpeg –bsfs
可用的编解码器:ffmpeg –codecs
可用的解码器:ffmpeg –decoders
可用的编码器:ffmpeg –encoders
可用的过滤器:ffmpeg –filters
可用的视频格式:ffmpeg –formats
可用的声道布局:ffmpeg –layouts
可用的license:ffmpeg –L
可用的像素格式:ffmpeg –pix_fmts
可用的协议:ffmpeg -protocals
码率和帧率是视频文件的最重要的基本特征,对于他们的特有设置会决定视频质量。如果我们知道码率和时长那么可以很容易计算出输出文件的大小。
帧率:帧率也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。
码率:比特率(也叫码率,数据率)是一个确定整体视频/音频质量的参数,秒为单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用bps来表达。
设置帧率
1、用 -r 参数设置帧率
ffmpeg –i input.mp4 –r fps output.mp4
2、用fps filter设置帧率
ffmpeg -i clip.mpg -vf fps=fps=25 clip.webm
设置码率 –b 参数
-b
ffmpeg -i film.avi -b 1.5M film.mp4
音频:-b:a 视频: - b:v
设置视频码率为1500kbps
ffmpeg -i input.avi -b:v 1500k output.mp4
控制输出文件大小
-fs (file size首字母缩写)
ffmpeg -i input.avi -fs 1024K output.mp4
计算输出文件大小
(视频码率+音频码率) * 时长 /8 = 文件大小K
用-s参数设置视频分辨率,参数值wxh,w宽度单位是像素,h高度单位是像素
ffmpeg -i input_file -s 320x240 output_file
2、预定义的视频尺寸
下面两条命令有相同效果
ffmpeg -i input.avi -s 640x480 output.avi
ffmpeg -i input.avi -s vga output.avi
下表列出了所有的预定义尺寸
Scale filter调整分辨率
Scale filter的优点是可以使用一些额外的参数
语法:
Scale=width:height[:interl={1|-1}]
下表列出了常用的额外参数
下面两条命令有相同效果
ffmpeg -i input.mpg -s 320x240 output.mp4
ffmpeg -i input.mpg -vf scale=320:240 output.mp4
对输入视频成比例缩放
改变为源视频一半大小
ffmpeg -i input.mpg -vf scale=iw/2:ih/2 output.mp4
改变为原视频的90%大小:
ffmpeg -i input.mpg -vf scale=iw 0.9:ih 0.9 output.mp4
在未知视频的分辨率时,保证调整的分辨率与源视频有相同的横纵比。
宽度固定400,高度成比例:
ffmpeg -i input.avi -vf scale=400:400/a
ffmpeg -i input.avi -vf scale=400:-1
相反地,高度固定300,宽度成比例:
ffmpeg -i input.avi -vf scale=-1:300
ffmpeg -i input.avi -vf scale=300*a:300
从输入文件中选取你想要的矩形区域到输出文件中,常见用来去视频黑边。
语法:crop:ow[:oh[:x[:y:[:keep_aspect]]]]
裁剪输入视频的左三分之一,中间三分之一,右三分之一:
ffmpeg -i input -vf crop=iw/3:ih :0:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3*2:0 output
裁剪帧的中心
当我们想裁剪区域在帧的中间时,裁剪filter可以跳过输入x和y值,他们的默认值是
Xdefault = ( input width - output width)/2
Ydefault = ( input height - output height)/2
ffmpeg -i input_file -v crop=w:h output_file
裁剪中间一半区域:
ffmpeg -i input.avi -vf crop=iw/2:ih/2 output.avi
比较裁剪后的视频和源视频比较
ffplay -i jidu.mp4 -vf split[a][b];[a]drawbox=x=(iw-300)/2:(ih-300)/2:w=300:h=300:c=yellow[A];[A]pad=2 iw[C];[b]crop=300:300:(iw-300)/2:(ih-300)/2[B];[C][B]overlay=w 2.4:40-ffplay播放多个文件
自动检测裁剪区域�
cropdetect filter 自动检测黑边区域
ffplay jidu.mp4 -vf cropdetect
填充视频(pad)
在视频帧上增加一快额外额区域,经常用在播放的时候显示不同的横纵比
语法:pad=width[:height:[:x[:y:[:color]]]]
创建一个30个像素的粉色宽度来包围一个SVGA尺寸的图片:
ffmpeg -i photo.jpg -vf pad=860:660:30:30:pink framed_photo.jpg
同理可以制作input.mp4视频用30个像素粉色包围视频
ffplay -i input.mp4 -vf pad=iw+60:ih+60:30:30:pink
4:3到16:9
一些设备只能播放16:9的横纵比,4:3的横纵比必须在水平方向的两边填充成16:9,
高度被保持,宽度等于高度乘以16/9,x(输入文件水平位移)值由表达式(output_width - input_width)/2来计算。
4:3到16:9的通用命令是:
ffmpeg -i input.mp4 -vf pad=ih 16/9:ih :(ow-iw)/2:0:color output.mp4
eg:ffplay -f input.mp4 -vf pad=ih 16/9:ih:(ow-iw)/2:0:pink
16:9到4:3
为了用4:3的横纵比来显示16:9的横纵比,填充输入文件的垂直两边,宽度保持不变,高度是宽度的3/4,y值(输入文件的垂直偏移量)是由一个表达式(output_height-input_height)/2计算出来的。-ffplay播放多个文件
16:9到4:3的通用命令:
ffmpeg -i input.mp4-vf pad=iw :iw 3/4:0:(oh-ih)/2:color output.mp4
eg:ffplay -i input.mp4 =size=320x180 -vf pad=iw:iw 3/4:0:(oh-ih)/2:pink
水平翻转语法: -vf hflip
ffplay -f lavfi -i testsrc -vf hflip
垂直翻转语法:-vf vflip
ffplay -f lavfi -i testsrc -vf vflip
语法:transpose={0,1,2,3}
0:逆时针旋转90°然后垂直翻转
1:顺时针旋转90°
2:逆时针旋转90°
3:顺时针旋转90°然后水平翻转
模糊
语法:boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]
ffplay -f lavfi -i testsrc -vf boxblur=1:10:4:10
注意:luma_r和alpha_r半径取值范围是0~min(w,h)/2, chroma_r半径的取值范围是0~min(cw/ch)/2
锐化
语法:-vf unsharp=l_msize_x:l_msize_y:l_amount:c_msize_x:c_msize_y:c_amount
所有的参数是可选的,默认值是5:5:1.0:5:5:0.0
l_msize_x:水平亮度矩阵,取值范围3-13,默认值为5
l_msize_y:垂直亮度矩阵,取值范围3-13,默认值为5
l_amount:亮度强度,取值范围-2.0-5.0,负数为模糊效果,默认值1.0
c_msize_x:水平色彩矩阵,取值范围3-13,默认值5
c_msize_y:垂直色彩矩阵,取值范围3-13,默认值5
c_amount:色彩强度,取值范围-2.0-5.0,负数为模糊效果,默认值0.0
eg:
使用默认值,亮度矩阵为5x5和亮度值为1.0
ffmpeg -i input.mp4 -vf unsharp output.mp4
高斯模糊效果(比较强的模糊):
ffplay -i input.mp4 -vf unsharp=13:13:-2
语法:overlay[=x[:y]
所有的参数都是可选,默认值都是0
Logo在左上角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay output.mp4
右上角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w output.mp4
左下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=0:H-h output.mp4
右下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:H-h output.mp4
删除logo
语法:-vf delogo=x:y:w:h[:t[:show]]
x:y 离左上角的坐标
w:h logo的宽和高
t: 矩形边缘的厚度默认值4
show:若设置为1有一个绿色的矩形,默认值0.
ffplay -i jidu.mp4 -vf delogo=50:51:60:60:100:0
语法:
drawtext=fontfile=font_f:text=text1[:p3=v3[:p4=v4[…]]]
常用的参数值
x:离左上角的横坐标
y: 离左上角的纵坐标
fontcolor:字体颜色
fontsize:字体大小
text:文本内容
textfile:文本文件
t:时间戳,单位秒
n:帧数开始位置为0
draw/enable:控制文件显示,若值为0不显示,1显示,可以使用函数
1、在左上角添加Welcome文字
ffplay -i color=c=white -vf drawtext=fontfile=arial.ttf:text=Welcom
2、在中央添加Good day
ffplay -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Goodday':x=(w-tw)/2:y=(h-th)/2"
3、设置字体颜色和大小
ffplay -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Happy Holidays':x=(w-tw)/2:y=(h-th)/2:fontcolor=green:fontsize=30"-ffplay播放多个文件
动态文本
用 t (时间秒)变量实现动态文本
1、顶部水平滚动
ffplay -i jidu.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=w-t 50:fontcolor=darkorange:fontsize=30"-ffplay播放多个文件
2、底部水平滚动
ffplay -i jidu.mp4 -vf drawtext="fontfile=arial.ttf:textfile=textfile.txt:x=w-t 50:y=h-th:fontcolor=darkorange:fontsize=30"-ffplay播放多个文件
3、垂直从下往上滚动
ffplay jidu.mp4 -vf drawtext="textfile=textfile:fontfile=arial.ttf:x=(w-tw)/2:y=h-t*100:fontcolor=white:fontsize=30“-ffplay播放多个文件
在右上角显示当前时间 localtime
ffplay jidu.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}'“-ffplay播放多个文件
每隔3秒显示一次当前时间
ffplay jidu.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}':enable=lt(mod(t,3),1)"-ffplay播放多个文件
FFmpeg支持绝大多数图片处理, 除LJPEG(无损JPEG)之外,其他都能被解码,除了EXR,PIC,PTX之外,所有的都能被编码。
截取一张图片使用 –ss(seek from start)参数.
ffmpeg -ss 01:23:45 -i jidu.mp4 image.jpg
从视频中生成GIF图片
ffmpeg -i jidu.mp4 -t 10 -pix_fmt rgb24 jidu.gif
转换视频为图片(每帧一张图)
ffmpeg -i clip.avi frame%4d.jpg
图片转换为视频
ffmpeg -f image2 -i img%4d.jpg -r 25 video.mp4
和视频一样,图片也可以被裁剪和填充
裁剪
ffmpeg -f lavfi -i rgbtestsrc -vf crop=150:150 crop_rg.png
填充
ffmpeg -f lavfi -i smptebars -vf pad=360:280:20:20:orange pad_smpte.jpg
和视频一样图片同样能翻转,旋转和覆盖
翻转
ffmpeg -i orange.jpg -vf hflip orange_hfilp.jpg
ffmpeg -i orange.jpg -vf vflip orange_vfilp.jpg
旋转
ffmpeg -i -vf transpose=1 image_rotated.png
覆盖
ffmpeg -f lavfi -i rgbtestsrc -s 400x300 rgb .png
ffmpeg -f lavfi -i smptebars smpte.png
ffmpeg -i rgb .png -i smpte.png -filter_complex overlay= (W-w)/2:(H-h)/2 rgb_smpte.png
屏幕录像
显示设备名称
ffmpeg -list_devices 1 -f dshow -i dummy
调用摄像头
ffplay -f dshow -i video="Integrated Camera"
保存为文件
ffmpeg -y -f dshow -s 320x240 -r 25 -i video="Integrated Camera" -b:v 800K -vcodec mpeg4 new.mp4
添加字幕subtitles
语法 –vf subtitles=file
ffmpeg -i jidu.mp4 -vf subtitles=rgb.srt output.mp4
视频颤抖、色彩平衡
视频颤抖
ffplay –i jidu.mp4 -vf crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2) sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2) sin(n/7)-ffplay播放多个文件
色彩平衡
ffplay -i jidu.mp4 -vf curves=vintage
色彩变幻
ffplay -i jidu.mp4 -vf hue="H=2 PI t: s=sin(2 PI t)+1“
彩色转换黑白
ffplay -i jidu.mp4 -vf lutyuv="u=128:v=128"
设置音频视频播放速度
3倍视频播放视频
ffplay -i jidu.mp4 -vf setpts=PTS/3
¾速度播放视频
ffplay -i jidu.mp4 -vf setpts=PTS/(3/4)
2倍速度播放音频
ffplay -i speech.mp3 -af atempo=2
截图
每隔一秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=fps=1 out%d.png
每隔20秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=fps=1/20 out%d.png
注意:ffmpeg version N-57961-gec8e68c版本最多可以每隔20s截一张图。
多张截图合并到一个文件里(2x3) 每隔一千帧(秒数=1000/fps25)即40s截一张图
ffmpeg -i jidu.mp4 -frames 3 -vf "select=not(mod(n,1000)),scale=320:240,tile=2x3" out.png
本篇文章主要记录ffmpeg的一些基础指令操作,该资料的来源是源于网上的一个ppt文档,感谢文档的总结。
第三章 FFmpeg的介绍与使用
FFmpeg名称中的mpeg来自视频编码标准MPEG,而前缀FF是Fast Forward的首字母缩写。
目录
默认的编译会生成 4 个可执行文件和 8 个静态库。可执行文件包括用于 转码 、 推流 、Dump媒体文件的 ffmpeg 、用于播放媒体文件的 ffplay 、 用于获取媒体文件信息的 ffprobe ,以及作为简单流媒体服务器的 ffserver 。-ffplay播放多个文件
8个静态库其实就是FFmpeg的8个模块,具体包括如下内容。
比如AAC编码,常见的有两种封装格式
AAC 的 bit stream filter 常常应用在 编码 的过程中。
与音频的AAC编码格式相对应的是视频中的 H264编码 ,它也有两种封装格式
FFmpeg中也提供了对应的 bit stream filter ,称 H264_mp4toannexb ,可以将MP4封装格式的H264数据包转换为annexb封装格式的H264数据 (其实就是裸的H264的数据)包。-ffplay播放多个文件
H264 的 bit stream filter 常常应用于视频解码过程中。
ffmpeg 是进行媒体文件转码的命令行工具
ffprobe 是用于查看媒体 文件头信息的工具
ffplay 则是用于播放媒体文件的工具
1.首先用ffprobe查看一个音频的文件
2.输出格式信息format_name、时间长度duration、文件 大小size、比特率bit_rate、流的数目nb_streams等。
3.以JSON格式的形式输出具体每一个流 最详细 的信息
4.显示帧信息的命令如下:
5.查看包信息的命令如下:
ffplay是以FFmpeg框架为基础,外加渲染音视频 的库libSDL来构建的媒体文件播放器。
业界内开源的 ijkPlayer 其实就是基于 ffplay 进行改造的播放器,当然其做了硬件解码以及很多兼容性的工作。
在 ffplay中音画同步的实现方式其实有三种。分别是
并且在 ffplay 中默认的对齐方式也是以 音频 为基准进行对齐的。
首先要声明的是,播放器接收到的视频帧或者音频帧,内部都会有 时间戳(PTS时钟) 来标识它实际应该在什么时刻进行展示。
实际的对齐策略如下:比较视频当前的播放时间和音频当前的播放时间
关键就在于音视频时间的比较以及延迟的计算,当然在比较的过程中会设 置一个 阈值(Threshold) ,若超过预设的阈值就应该做调整(丢帧渲染 或者重复渲染),这就是整个对齐策略。
ffmpeg 就是强大的媒体文件转换工具。它可以转换任何格式的媒体文件,并且还可以用自己的 AudioFilter 以及 VideoFilter 进行处理和编辑。
接下来介绍一个解码的实例,该实例实现的功能非常单一,就是把一个视频文件解码成单独的音频PCM文件和视频YUV文件。
AVFormatContext是API层直接接触到的结构体,它会进行格式的封 装与解封装。
该结构体包含的就是与实际的 编解码 有关的部分。
3.3.1 av_register_all
所以该函数的内部实现会先调用 avcodec_register_all 来注册所有config.h里面开放的编解码器,然后会注册所有的 Muxer 和 Demuxer (也就是封装格式),最后注册所有的 Protocol (即协议层的东西)。-ffplay播放多个文件
3.3.2 av_find_codec
这里面其实包含了两部分的内容:一部分是寻找 解码器 ,一部分是寻找 编码器 。
3.3.3 avcodec_open2
该函数是打开编解码器(Codec)的函数,无论是编码过程还是解码过程,都会用到该函数。
avformat_open_input
根据所提供的文件路径判断文件的格 式,其实就是通过这一步来决定使用的到底是哪一个 Demuxer 。
avformat_find_stream_info
该方法的作用就是把所有 Stream 的 MetaData 信息填充好。
av_read_frame
使用该方法读取出来的数据是 AVPacket 。
对于 音频流 ,一个 AVPacket 可能包含 多 个 AVFrame ,但是对于 视频流 ,一个 AVPacket 只包含 一 个 AVFrame ,该函数最终只会返回一个 AVPacket 结构体。-ffplay播放多个文件
avcodec_decode
该方法包含了两部分内容:一部分是 解码视频 ,一部分是 解码音频 , 解码 是会委托给对应的解码器来实施的。
avformat_close_input
该函数负责释放对应的资源。
avformat_alloc_output_context2
该函数内部需要调用方法avformat_alloc_context来分配一个 AVFormatContext 结构体。
avio_open2
编码的阶段了,开发者需要将手动封装好的 AVFrame 结构体,作为 avcodec_encode_video 方法的输入,将其编码成为 AVPacket ,然后调用 av_write_frame 方法输出到媒体文件中。-ffplay播放多个文件
本文参考 音视频开发进阶指南
项目源码地址 - FFmpegDecoder