目录
0 前言
1 语法 Synopsis
2 描述 Description
3 选项 Options
3.1 流指定器 Stream specifiers
3.2 通用选项 Generic options
3.3 主要选项 Main options
3.3.1 -x width
3.3.2 -yheight
3.3.3 -s size
3.3.4-fs
3.3.5 -left x pos
3.3.6 -top y pos
3.3.7-window_title window title
3.3.8 -nodisp
3.3.9 -noborder
3.3.10 -ss pos
3.3.11 -t duration
3.3.12 -volume volume
3.3.13 -an
3.3.14 -vn
3.3.15 -sn
3.3.16 -loop loop count
3.3.17 -bytes val
3.3.18 -showmode mode
3.3.19 -f fmt
3.3.20 -seek_interval
3.3.21 -vf filtergraph
3.3.22 -af filtergraph
3.3.23 -i input_url
3.4 高级选项 Main options
3.4.1 -autoexit
3.4.2 -exitonkeydown
3.4.3 -exitonmousedown
3.4.4 -autorotate
3.4.5 -pix_fmt format
3.4.6 -codec:media_specifier codec_name
3.4.7 -acodec decoder_name
3.4.8 -scodec decoder_name
3.4.9 -vcodec decoder_name
3.4.10 -vst stream_specifier
3.4.11 -ast stream_specifier
3.4.12 -sst stream_specifier
3.4.13 -fast
3.4.14 -genpts
3.4.15 -drp
3.4.16 -sync type
3.4.17 -framedrop
3.4.18 -infbuf
3.4.19 -find_stream_info
3.4.20 -stats
4 播放过程中的按键控制 While playing
0 前言
本文主要参考 ffplay documentation,以及《FFMPEG入门到精通》一书。
本文中的示例将尽量详尽,每个示例也将经过实测。
ffplay版本4.1 3月1日记之。
1 语法 Synopsis
ffplay [options] [input_url]
2 描述 Description
ffplay为ffmpeg的简单可移植的多媒体播放器,使用ffmpeg库以及SDL库。它大多数时候用于测试ffmpeg的API。
3 选项 Options
所有数字选项,如果没有特别指明的话,接受一个字符串来替代数字作为输入,一般是数字后跟随一个SI单位,比如‘K’,‘M’,‘G’。
如果‘i’跟随在SI单位之后出现,那么数字大小将被解释为以1024为基础的而非1000。如果'B'跟随在SI单位后出现,那么值将乘以8。将会出现‘KB’, ‘MiB’, ‘G’ 和 ‘B’作为数字的后缀。
没有参数的选项是bool选项,将设置相关的参数为true。相关参数可以被设置为false,通过在相应的选项前加个‘no’。比如,使用‘-nofoo’选项,将会使得‘-foo’选项设置的参数为false。
3.1 流指定器 Stream specifiers
一些选项可以应用于每个流。流指定器用来精确指定选项作用于哪个流。
流指定器一般是跟随选项的字符串,用‘:’来隔开。比如 “-codec:a:1 ac3”包含了流指定器 a:1,匹配第二个音频流。因此作用是对第二个音频流使用ac3的编解码器。
一个流指定器可以匹配多个流,因此选项可以应用到这些多个流中。比如,“-b:a 128k”中的流指定器匹配所有的音频流。
一个空的流指定器匹配所有流。比如,-codec copy 或者 -codec: copy将会匹配所有的流。
流指定器可能的格式:
stream_index 匹配流序号。比如,-threads:1 4 将设置处理第二个流的线程数为4。如果stream_index用于指定器的追加参数,那么将会选择匹配的相应序号的流stream_type[:additional_stream_specifier] stream_type是指:音频流类型使用'a',字幕流类型使用's',数据流类型使用'd',附加类型使用't',视频流类型使用'v'或者'V',小'v'匹配所有的视频流,大'V'仅匹配非附加图片,视频缩略图,艺术封面图。当additional_stream_specifier被使用的,那么将匹配type:index一致的单个流,如果不使用additional_stream_specifier,那么将匹配所有和type一致的流。p:program_id[:additional_stream_specifier] 匹配节目id相应的流。#stream_id or i:stream_id 匹配流通过流id(比如MPEG-TS容器中的PID)m:key[:value] 匹配流的metadata中相应tag(key)含有指定值的流。如果value没有给出,那么匹配所有含有指定tag的所有流u 匹配具有可用配置的流,必须定义编解码器,并且必须提供诸如视频维度或音频采样率等基本信息。
注意,在ffmpeg中匹配meatdata只会对输入文件工作正常。
3.2 通用选项 Generic options
通用选项部分参见ffplay documentation 以及 [总结]FFMPEG命令行工具之ffprobe详解
3.3 主要选项 Main options
3.3.1 -x width
func:force displayed width
example:视频1.mp4分辨率为1280x720。尝试分别将width设置为500 1280 1500,视频展示如下:
ffplay -i 1.mp4 -x 500
ffplay -i 1.mp4 -x 1280
ffplay -i 1.mp4 -x 1500
在只设置宽度的情况下,视频宽度按照设置大小显示,视频也将进行相应的缩放,保持DAR 16:9的宽高比显示。
3.3.2-yheight
func:force displayed height
example:按照-x参数的逻辑,在只设置-y参数的情况下,分别设置-y参数为500,720,900,得出的结论与1.1.1是类似的,所以此处不再将同样效果的图片贴出,节省空间。
注意:在这儿尝试下将-x -y同时设置看看将输出什么效果的图像
测试参数:宽高比大于原始宽高比,宽高比等于原始宽高比,宽高比小于原始宽高比。
ffplay -i 1.mp4 -x 1000 -y 300 -window_title "1000x300"
ffplay - i 1.mp4 -x 640 -y 360 -window_title "640x360"
ffplay - i 1.mp4 -x 640-y 500-window_title "640x500"
PS: 由本组测试数据可知窗体大小会按照-x -y指定大小显示,但是若二者之比与原始视频的宽高不成比例时,那么将出现左右,或者上下的黑边,中间的视频仍将按照DAR(display aspect ratio)所示比例正常显示。
3.3.3 -s size
func:set frame size (WxH or abbreviation), needed for videos which do not contain a header with the frame size like raw YUV. This option has been deprecated in favor of private options, try -video_size.
example:此命令时同时设置宽高,但是执行结果却让人感到意外,提示-s这个参数已经被弃用,请使用-video_size,紧接着又输出-vide_size参数不存在的消息。
但搜索ffplay -h输出可以找到-video_size,如下图所示:
于是我又执行ffplay -i 1.mp4 -video_size 1200x400,得到仍是无法找到-video_size。这是否是个bug?
3.3.4-fs
fuc:Start in fullscreen mode.
example:视频窗口将按全屏显示,窗体的标题栏也将被隐藏,若是电脑显示器的纵横比和视频本身的DAR不一致时,窗体上也将出现黑边。本人电脑为16:9的显示器,测试媒体文件1.mp4的DAR也为16:9,因此全屏显示此视频不出现黑边。如下图所示
3.3.5 -left x pos
fuc:Set the x position for the left of the window (default is a centered window).
example:设置播放器窗体在电脑屏幕的初始横坐标,单位为像素。
3.3.6 -top y pos
fuc: set the y position for the top of the window
example:设置播放器窗体在电脑屏幕的初始纵坐标,单位为像素。
例: ffplay -i 1.mp4 -left 100 -top 100
播放器窗体初始显示位置,将是在距离屏幕左上角纵横都为100像素的地方显示。这儿其实没什么太多要讲的,其实就是控制一个窗体在电脑屏幕上的位置,在-left -top设置不同值时会导致窗体在屏幕上显示不全或者完全不在屏幕显示范围内的情况出现,做过界面开发的人都很容易理解,此处也就不再多做赘述。
3.3.7-window_title window title
func:Set window title (default is the input filename).
example:ffplay -i 1.mp4 -window_title "600x300"
设置窗体标题栏显示名称,若没有设置,默认窗体标题栏为文件名。效果参见3.3.2
3.3.8 -nodisp
func:disable graphical display
example:ffplay -i 1.mp4 -nodisp
窗体将被隐藏,但声音正常能播放。
3.3.9 -noborder
func:borderless window
example:ffplay -i 1.mp4 -noborder
窗体无边框显示,效果如下图
3.3.10 -ss pos
func:Seek to pos. Note that in most formats it is not possible to seek exactly, soffplay
will seek to the nearest seek point to pos.
example:ffplay -i 1.mp4 -ss 12
跳转到pos位置开始播放,单位s。但是由于大多数文件格式无法支持精确跳转,ffplay将跳转到离pos最新的随机访问点(即关键帧的位置)。比如示例要跳转到12s开始播放,但是其实播放时间如左下角的红色矩形区域所示为10.11s
使用Elecard Stram Eye工具查看此视频文件,会发现在10.00s的位置有一个关键帧,15s的位置有个关键帧,离12最近的就是10s这个关键帧,因此会跳转到10s这个关键帧开始播放。实际上,跳转的位置若不超过15,则一直都会从10s开始播放,超过15会从15s开始播放。
3.3.11 -t duration
func:play "duration" seconds of audio/video
example:ffplay -i 1.m4 -ss 14 -t 10
一般配合ss使用,表示从14s位置开始播放10s钟结束。但是我们知道ss的不精确性导致视频会从第10s开始播放,那么视频是播放到预计的24s结束呢?还是确实就是播放10s钟在20s的位置结束呢? 来,我们看效果
视频播放开始
、
视频播放结束
注意:由实际操作会发现,视频播放开始会根据-t参数计算出视频播放的结束时间,播放到这个时刻停止播放,而非确确实实在播放过程中去计算播放了多久再根据设置的播放时长决定是否停止。
3.3.12 -volume volume
func:Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values are treated as 0, values above 100 are treated as 100.
example:ffplay -i 1.mp4 -volume 50
设置播放时的初始音量,这个貌似没有什么太多要讲的,但是要注意一点,不管这个值设置为多大,播放器的最大音量默认为系统音量。
volume设置为2
volume设置为100
3.3.13 -an
func:disable audio
example:ffplay -i 1.mp4 -an
视频正常播放,没有声音,与-volume 0效果一致,但实际不一致,-an应该是音频就不解码了,而-volume 0音频数据应该会继续解码。
3.3.14 -vn
func:disable video
example:ffplay -i 1.mp4 -vn
音频正常播放,视频不解码,但是播放窗体依然会出现,界面渲染成如下这样
奇怪~~为啥不是纯黑色的呢? 这显示的是个啥?请见-showmode的解释。
3.3.15 -sn
func:disable subtitling
example:ffplay -i 1.mp4 -sn
禁用字幕。
3.3.16 -loop loop count
func:Loops movie playback <number> times. 0 means forever.
example:ffplay -i 1.mp4 -loop 2 -ss 10 -t 5
loop用来控制循环播放次数,上诉命令产生的效果就是从视频的第10s开始播放,播放5s时长,然后又从10s开始播放,播放5s后结束播放。
3.3.17 -bytes val
func:seek by bytes 0=off 1=on -1=auto
example:ffplay -i 1.mp4 -bytes 1
此参数用来控制是否可以 按照字节数进行seek,0表示不能,1表示能, -1表示自动,自动是什么意思还没有太明白。
注意:mp4文件不能按照bytes进行seek,因此在启用字节seek时,按左右键,ffplay会输出如下错误信息“1.mp4: error while seeking”。
3.3.18 -showmode mode
func:“Set the show mode to use. Available values for mode are: ‘0, video’ show video; ‘1, waves’ show audio waves; ‘2, rdft’ show audio frequency band using RDFT ((Inverse) Real Discrete Fourier Transform). Default value is "video", if video is not present or cannot be played "rdft" is automatically selected. You can interactively cycle through the available show modes by pressing the key w.”
example:-showmode这个选项可以控制播放器显示模式。-showmode 0表示显示视频, -showmode 1表示显示音频波形,-showmode 2表示显示音频带宽(实时离散傅里叶变换)。默认显示视频,当视频流不存在或无法显示时,将自动切换显示rdft(这就是-vn时,播放器界面不是显示黑色的原因)。在ffplay播放视频时,可以通过按键w来控制显示模式切换。
ffplay -i 1.mp4 -x 640 -y 360 -showmode 0
ffplay -i 1.mp4 -x 640 -y 360 -showmode 1
ffplay -i 1.mp4 -x 640 -y 360 -showmode 2
3.3.19 -f fmt
func:force format
example:ffplay -i 1.mp4 -f mov
本参数强制按照fmt格式来解析文件,若是按照1.MP4适配格式mov m4a 3gp 3g2 mj2这些来解析的话,文件是可以正常播放的。
若是按照flv,mpegts格式来解析会报出不同样的错误信息出来:
3.3.20 -seek_interval
func:Set custom interval, in seconds, for seeking using left/right keys. Default is 10 seconds.
example:这个选项用来控制视频播放过程中,左右按键控制跳转时的跳转间隔,默认是10s,也即右键按一下,视频跳转到10s后的位置播放。但是,实测过程中,发现4.1版本的ffplay并没有这个选项,可能是在这个版本已经去掉了相关的选项,而ffplay的帮助文档没有进行修改。
3.3.21 -vf filtergraph
func:Create the filtergraph specified by filtergraph and use it to filter the video stream.
filtergraph is a description of the filtergraph to apply to the stream, and must have a single video input and a single video output. In the filtergraph, the input is associated to the labelin
, and the output to the labelout
. See the ffmpeg-filters manual for more information about the filtergraph syntax.
You can specify this parameter multiple times and cycle through the specified filtergraphs along with the show modes by pressing the key w.
example:ffplay -i 1.mp4 -vf "chop=100:100:100:100" -vf "chop=200:200:200:200"
按照-vf选项的解释,得到的结果应该是:显示视频的(100, 100)位置宽高各100的视频->按w键切换显示(200, 200)位置的宽高各200的视频(chop滤镜为裁剪视频)->按w键切换到音频波形->按w键切换到音频频谱(RDFT)->循环。而实际测试为:显示视频的(100, 100)位置宽高各100的视频->不变->按w键切换到音频波形->按w键切换到音频频谱(RDFT)->循环。实际上第二个滤镜的效果并未呈现,可能是bug????
3.3.22 -af filtergraph
func:filtergraph is a description of the filtergraph to apply to the input audio. Use the option "-filters" to show all the available filters (including sources and sinks).
example:这儿不知道如何呈现~~
3.3.23 -i input_url
func:Read input_url.
example:指定输入文件url。输入文件可以是本地文件,管道,也可以是网络流,比如ffplay -i rtmp:///live_bak/x_3_0_0 就是拉的rtmp实时网络流。
3.4 高级选项 Main options
3.4.1 -autoexit
func:Exit when video is done playing.
example:ffplay -i 1.mp4 -t 5 -autoexit
此命令控制视频播放5s后,播放窗体自动关闭。注意,ffplay播放结束后,默认是停留在最后一帧画面的。
3.4.2 -exitonkeydown
func:exit on key down
example:ffplay -i 1.mp4-exitonkeydown
此命令使得ffplay视频播放窗体在按下键盘任意键就退出
3.4.3 -exitonmousedown
func:exit on mouse down
example:ffplay -i 1.mp4 -exitonmousedown
此命令使得ffplay视频播放窗体在按下鼠标左键,中间滚轴(不是滚动,而是按下),右键时都会退出播放。
3.4.4 -autorotate
func:automatically rotate video
example:ffplay -i1.mp4 -autorotate
居然没有什么特别效果,这是为啥呢? 来看ffplay documentation的对此参数的解释:
“Automatically rotate the video according to file metadata. Enabled by default, use-noautorotateto disable it.”
大意是: 视频将根据文件的metadata信息来决定自动旋转效果,也就是如果文件的metadata没包含视频旋转信息,那么这个参数设置没有其效果。若有旋转信息,则此参数会使视频播放时,视频自动按照metadata中的信息进行旋转,当然不设置这个参数也默认生效,要使其不生效可以使用-noautorotate参数。
1. 为了测试这个效果,我们先使用ffmpeg -i 1.mp4 -metadata:s:v rotate="90" -codec copy 2.mp4,得到一个旋转90的视频2.mp4
如上图,2.mp4文件的rotate为270,明明我设置的是90啊,难道是因为rotate="90"使得视频逆时针旋转90度,相当于顺时针的270度吗?
2.使用ffplay -i 2.mp4 -x 360 -y 640 来看视频播放时的旋转情况:果然视频逆时针旋转了90度~,并且注意一点,视频本身是1280x720的,旋转后宽高置换,设置-x 360 -y 640才能保证窗体比例跟视频一致而不留黑边
3. 使用ffplay -i 2.mp4 -x 640 -y 360 -noautorotate,视频又能“正“着播放了。注意此时-x 640 -y 360与上面的不同之处
3.4.5 -pix_fmt format
func:set pixel format
example:ffplay -i 1.mp4 -pix_fmt yuv420p
这个参数作用是“Set pixel format. This option has been deprecated in favor of private options, try -pixel_format.”,如果转换成中文理解是设置pixel格式,但是文件中pixel格式是已经确定的,作用是按照此格式来解析文件中存储的像素格式?运行此命令得到的结果是:
这个是没有搞明白的一个参数,留待以后?????
3.4.6-codec:media_specifier codec_name
func:Force a specific decoder implementation for the stream identified by media_specifier, which can assume the valuesa
(audio),v
(video), ands
subtitle
example:ffplay -i 1.mp4 -codec:v h264
强制使用h264解码器实现来实现1.mp4视频流解码。
首先,使用ffprobe -i 1.mp4 -hide_banner可以知道,此文件的视频码率是H.264格式的:
其次,使用ffprobe -codecs -hide_banner| find "h264",我们可以找到当前ffmpeg支持的h264解码器实现为h264,h264_qsv,h64_cuvid。
最后,我们使用ffplay -i 1.mp4 -codec:v h264或者ffplay -i 1.mp4 -codec:v h264_qsv或者ffplay -i 1.mp4 -codec:v h264_cuvid来尝试解码,发现使用解码器h264和h264_qsv是可以解码的,但是h264_cuvid不能解码。
h264: cpu软解码.
h264_qsv:英特尔Quick Sync Video(QSV),这是intel的GPU解码技术
h264_cuvid:这是nvidia显卡的硬件解码技术
网上查找这个错误的原因是NVIDIA显卡驱动不是最新的,可以升级显卡驱动解决这个问题。但实际上发现本机显卡驱动已经是最新的了,因此这个n卡不能硬解的原因就还没找到。
3.4.7 -acodec decoder_name
func:force audio decoder
3.4.8-scodec decoder_name
func:force subtitle decoder
3.4.9-vcodec decoder_name
func:force video decoder
以上三个命令就是1.3.3的分解,因此这儿不再赘述。
3.4.10-vst stream_specifier
func:select desired video stream
example:ffplay -i 1.mp4 -vst v:0
指定解码的视频流,其他码流走默认的,一并正常解码,注意stream_specifier的格式为v:0。若指定到不存在的流,比如1.mp4只有一个视频流,那么指定视频流为v:1的话,那么视频是无法正常播放的,但其他流没有问题。
3.4.11 -ast stream_specifier
func:select desired audio stream
3.4.12 -sst stream_specifier
func:select desired subtitle stream
同3.4.10,这儿不赘述了,只是注意音频和字幕的stream_specifier的格式为a:0, s:0,若有2个音频流,那么a:1也是有效的。
3.4.13 -fast
func:non spec compliant optimizations
example:这个命令查了很久资料没有找到合适的解释,只能根据字面意思来看: "不合规范的编译优化"。具体指什么需看源码分析。等看过源码来填这个坑?????
3.4.14 -genpts
func:generate pts
example:ffplay -i 1.mp4 -genpts
按命令字面意思是产生pts,但是跟不加此参数没有区别,播放时间是ffplay输出的第一个参数。等看过源码来填这个坑?????
3.4.15 -drp
func: let decoder reorder pts 0=off 1=on -1=auto
example:等看过源码来填这个坑?????
3.4.16-sync type
func:“Set the master clock to audio (type=audio
), video (type=video
) or external (type=ext
). Default is audio. The master clock is used to control audio-video synchronization. Most media players use audio as master clock, but in some cases (streaming or high quality broadcast) it is necessary to change that. This option is mainly used for debugging purposes.”
example:设置主时钟可以为音频时钟 (type=audio
), 视频时钟 (type=video
) 或者 外部时钟 (type=ext
). 主时钟主要是控制音视频播放同步的。绝大多数播放器使用音频的时钟作为主时钟 ,但是在一些情况,比如流媒体或者高质量的广播情况下使用其他同步方式。ffplay的-sync参数主要是用于debugging用途。
3.4.17 -framedrop
func:Drop video frames if video is out of sync. Enabled by default if the master clock is not set to video. Use this option to enable frame dropping for all master clock sources, use -noframedrop to disable it.
example:ffplay -i 1.mp4 -framedrop 当音视频不同步时,将丢弃视频帧,当主时钟不是视频时钟时,这个功能时默认的开启的。这个参数的作用是不管主时钟是什么类型的,都会开启不同步时丢弃视频帧的功能,可以使用-noframedrop来关闭这个音画不同步时丢弃视频帧的功能。
3.4.18 -infbuf
func:Do not limit the input buffer size, read as much data as possible from the input as soon as possible. Enabled by default for realtime streams, where data may be dropped if not read in time. Use this option to enable infinite buffers for all inputs, use -noinfbuf to disable it.
example:ffplay -i 1.mp4 -infbuf 不限制输入缓存区大小,让播放器尽快地读取数据。当播放实时流,比如rtmp://ip:port/appname/streamname这种格式的流时默认会开启这个功能,如果不这样,会由于读取数据不实时导致拿到的数据是过时的而被丢弃。这个选项可以使各输入缓存区都是无限的,可以使用-noinfbuf关闭此功能。
3.4.19 -find_stream_info
func:read and decode the streams to fill missing information with heuristics
example:ffplay -i 1.mp4 -find_stream_info
没看出加不加此参数有什么变化,等看过源码来填这个坑?????
3.4.20 -stats
func:Print several playback statistics, in particular show the stream duration, the codec parameters, the current position in the stream and the audio/video synchronisation drift. It is on by default, to explicitly disable it you need to specify-nostats
.
example:打印一些播放的统计输出,特别是显示流的时长,编码器参数,当前在流中的播放位置,音画同步偏移值。这个功能是默认开启的,如果要显示关闭的话使用参数-nostats
4 播放过程中的按键控制 While playing
如果觉得《[总结]FFMPEG命令行工具之ffplay详解》对你有帮助,请点赞、收藏,并留下你的观点哦!