FFmpeg
FFmpeg 是处理多媒体内容(如音频、视频、字幕和相关元数据)的库(libraries)和工具(tools)的集合。
Libraries
-
libavcodec
音视频编解码模块,提供常用的编解码器。 -
libavformat
音视频格式封装模块,提供常用格式的封装和解封装能力,如 MP4、FLV等文件封装格式,RTMP、HLS 等网络协议封装格式。 -
libavutil
包括 hashers(散列), decompressors(解压缩) 和 miscellaneous(杂项) 等实用功能。 -
libavfilter
提供通过连接过滤器实现的有向图来改变解码音频和视频的方法,即提供一个通用的音频、视频、字幕等的处理框架。 -
libavdevice
提供一个抽象来访问捕获设备(麦克风、摄像头、桌面)和播放设备(扬声器、显示器)。 -
libswresample
实现音频混合和重采样例程。 -
libswscale
实现颜色和缩放例程。
Tools
stream specifiers
Stream specifiers (流说明符) 被用于精确地指定给定的选项(option)所应用的 stream 。
一个 stream specifier 通常是附加在选项名称后并用冒号与选项名称分隔的字符串。例如:-codec:a:1 ac3
包含 stream specifier a:1
即第二个音频流,它将为第二个音频流选择 ac3
编解码器。
stream specifier 可以匹配多个流,以便将该选项应用于所有流。例如 -b:a 128k
中 a
等价于匹配所有音频流。
空 stream specifier 匹配所有流。例如, -codec copy
或 -codec: copy
将复制所有流,而不需要重新编码。
stream specifier 的可能格式如下:
-
stream_index
- stream_index 的 stream number 是 基于 libavformat 检测到的流顺序;如果指定了
program_id
,stream number 基于程序中流的顺序。stream_index 可以用于匹配应用选项的流。例如-threads:1 4
会将第二个流的线程数设置为 4 。如果 stream_index 用作附加的流说明符(见下文的additional_stream_specifier
) (例如:-codec:a:1 ac3
的a:1
) ,那么它将从匹配的流中选择 stream_index 。
- stream_index 的 stream number 是 基于 libavformat 检测到的流顺序;如果指定了
-
stream_type[:additional_stream_specifier]
-
stream_type
的v
或V
指 video,a
指 audio,s
指 subtitle,t
指 attachments 。v
匹配所有视频流,V
只匹配没有附加图片、视频缩略图或封面艺术的视频流。如果使用additional_stream_specifier
,那么它将在 stream_type 指向的 streams 中匹配additional_stream_specifier
的流。additional_stream_specifier
是指定类型的 stream number (不是全局的 stream number)。
-
-
program_id[:additional_stream_specifier]
-
program_id
被用于匹配program_id
的 streams,如果使用additional_stream_specifier
,那么它将在该program_id
指向的 streams 中匹配additional_stream_specifier
的流。
-
ffmpeg 常用命令
ffmpeg [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ...
常用选项:
-i input_file input_file
-f fmt force format
-c codec codec name ('copy' to copy stream)
-
-i
指定输入文件 -
-c
指定输出的编码格式,'copy' 表示复制流,不重新解码和编码 -
-f
指定输出的封装格式
转码和转封装
_______ ______________
| | | |
| input | demuxer | encoded data | decoder
| file | ---------> | packets | -----+
|_______| |______________| |
v
_________
| |
| decoded |
| frames |
|_________|
________ ______________ |
| | | | |
| output | <-------- | encoded data | <----+
| file | muxer | packets | encoder
|________| |______________|
- 解封装
- 解码
- 重新编码
- 重新封装
示例
ffmpeg -i input.rmvb -vcodec mpeg4 -b:v 200k -an output.mp4
参数说明:
Video options:
-vframes number set the number of video frames to output
-r rate set frame rate (Hz value, fraction or abbreviation)
-fpsmax rate set max frame rate (Hz value, fraction or abbreviation)
-s size set frame size (WxH or abbreviation)
-aspect aspect set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)
-vn disable video
-vcodec codec force video codec ('copy' to copy stream)
-timecode hh:mm:ss[:;.]ff set initial TimeCode value.
-pass n select the pass number (1 to 3)
-vf filter_graph set video filters
-ab bitrate audio bitrate (please use -b:a)
-b bitrate video bitrate (please use -b:v)
-dn disable data
Audio options:
-aframes number set the number of audio frames to output
-aq quality set audio quality (codec-specific)
-ar rate set audio sampling rate (in Hz)
-ac channels set number of audio channels
-an disable audio
-acodec codec force audio codec ('copy' to copy stream)
-af filter_graph set audio filters
命令说明:
- 封装格式从 RMVB 格式 (
.rmvb
) 转为 MP4 格式 (.mp4
) - 视频编码转为 MPEG4 编码 (
-vcodec mpeg4
) - 视频码率转为 200 kbit/s (
-b:v 200k
) - 转码后的文件中不包括音频 (
-an
)
发布与录制 RTMP 流
可能用到的选项:
-re read input at native frame rate; equivalent to -readrate 1
-readrate speed read input at specified rate
-stream_loop times set number of times input stream shall be looped
-
-re
等价于-readrate 1
,采用媒体文件的原生帧率读取输入 -
-readrate speed
采用指定的 speed 读取输入 -
-stream_loop times
设置循环输入流的次数 (-1 表示无限循环)
RTMP 相关选项:
rtmpt AVOptions:
-rtmp_app <string> ED......... Name of application to connect to on the RTMP server
-rtmp_buffer <int> ED......... Set buffer time in milliseconds. The default is 3000. (from 0 to INT_MAX) (default 3000)
-rtmp_conn <string> ED......... Append arbitrary AMF data to the Connect message
-rtmp_flashver <string> ED......... Version of the Flash plugin used to run the SWF player.
-rtmp_flush_interval <int> E.......... Number of packets flushed in the same request (RTMPT only). (from 0 to INT_MAX) (default 10)
-rtmp_live <int> .D......... Specify that the media is a live stream. (from INT_MIN to INT_MAX) (default any)
any -2 .D......... both
live -1 .D......... live stream
recorded 0 .D......... recorded stream
-rtmp_pageurl <string> .D......... URL of the web page in which the media was embedded. By default no value will be sent.
-rtmp_playpath <string> ED......... Stream identifier to play or to publish
-rtmp_subscribe <string> .D......... Name of live stream to subscribe to. Defaults to rtmp_playpath.
-rtmp_swfhash <binary> .D......... SHA256 hash of the decompressed SWF file (32 bytes).
-rtmp_swfsize <int> .D......... Size of the decompressed SWF file, required for SWFVerification. (from 0 to INT_MAX) (default 0)
-rtmp_swfurl <string> ED......... URL of the SWF player. By default no value will be sent
-rtmp_swfverify <string> .D......... URL to player swf file, compute hash/size automatically.
-rtmp_tcurl <string> ED......... URL of the target stream. Defaults to proto://host[:port]/app.
-rtmp_listen <int> .D......... Listen for incoming rtmp connections (from INT_MIN to INT_MAX) (default 0)
-listen <int> .D......... Listen for incoming rtmp connections (from INT_MIN to INT_MAX) (default 0)
-tcp_nodelay <int> ED......... Use TCP_NODELAY to disable Nagle's algorithm (from 0 to 1) (default 0)
-timeout <int> .D......... Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1 (from INT_MIN to INT_MAX) (default -1)
常用参数:
-
-rtmp_app
: 指定 connect 的 RTMP server 的 application,用于 RTMP 的 connect command -
-rtmp_playpath
: 指定 play 或 publish 的流名 ,用于 RTMP 的 play/publish command -
-rtmp_tcurl
: 目标流的 url ,用于 RTMP 的 connect command
示例:
- 发布命令:
ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -f flv -rtmp_tcurl "mylive.com" -rtmp_app live -rtmp_playpath test_stream "rtmp://127.0.0.1"
- 录制命令:
ffmpeg -i -rtmp_tcurl "mylive.com" -rtmp_app live -rtmp_playpath test_stream "rtmp://127.0.0.1" -c copy -f flv output.flv
等价于:
- 发布命令:
ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -f flv "rtmp://mylive.com/live/test_stream"
- 录制命令:
ffmpeg -i "rtmp://mylive.com/live/test_stream" -c copy -f flv output.flv
录制 HTTP 流
http 相关选项:
http AVOptions:
-seekable <boolean> .D......... control seekability of connection (default auto)
-chunked_post <boolean> E.......... use chunked transfer-encoding for posts (default true)
-http_proxy <string> ED......... set HTTP proxy to tunnel through
-headers <string> ED......... set custom HTTP headers, can override built in default headers
-content_type <string> ED......... set a specific content type for the POST messages
-user_agent <string> .D......... override User-Agent header (default "Lavf/59.33.100")
-referer <string> .D......... override referer header
-multiple_requests <boolean> ED......... use persistent connections (default false)
-post_data <binary> ED......... set custom HTTP post data
-cookies <string> .D......... set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax
-icy <boolean> .D......... request ICY metadata (default true)
-auth_type <int> ED......... HTTP authentication type (from 0 to 1) (default none)
none 0 ED......... No auth method set, autodetect
basic 1 ED......... HTTP basic authentication
-send_expect_100 <boolean> E.......... Force sending an Expect: 100-continue header for POST (default auto)
-location <string> ED......... The actual location of the data received
-offset <int64> .D......... initial byte offset (from 0 to I64_MAX) (default 0)
-end_offset <int64> .D......... try to limit the request to bytes preceding this offset (from 0 to I64_MAX) (default 0)
-method <string> ED......... Override the HTTP method or set the expected HTTP method from a client
-reconnect <boolean> .D......... auto reconnect after disconnect before EOF (default false)
-reconnect_at_eof <boolean> .D......... auto reconnect at EOF (default false)
-reconnect_on_network_error <boolean> .D......... auto reconnect in case of tcp/tls error during connect (default false)
-reconnect_on_http_error <string> .D......... list of http status codes to reconnect on
-reconnect_streamed <boolean> .D......... auto reconnect streamed / non seekable streams (default false)
-reconnect_delay_max <int> .D......... max reconnect delay in seconds after which to give up (from 0 to 4294) (default 120)
-listen <int> ED......... listen on HTTP (from 0 to 2) (default 0)
-resource <string> E.......... The resource requested by a client
-reply_code <int> E.......... The http status code to return to a client (from INT_MIN to 599) (default 200)
-short_seek_size <int> .D......... Threshold to favor readahead over seek. (from 0 to INT_MAX) (default 0)
常用选项:
-seekable
在使用 FFmpeg 打开直播或点播文件时,可以通过 seek (-ss
)操作进行播放进度移动、定位等操作:
ffmpeg -ss 300 -seekable 1 -i "http://127.0.0.1/test.flv" -c copy output.flv
-headers
在使用 FFmpeg 拉取 HTTP 流时,可以设置 HTTP 的 header,例如:
ffmpeg -headers "referer: http://127.0.0.1/index.html" -i "http://127.0.0.1/test.flv" -c copy output.flv
-user_agent
在使用 FFmpeg 拉取 HTTP 流时,可以设置 HTTP 的 User-Agent。在流媒体中常见的 User-Agent 有 Android 的 StageFright、IOS 的 QuickTime 等,FFmpeg 也有自己的特殊的默认User-Agent:Lavf 。
ffmpeg -user_agent "my_user_agent" -i "http://127.0.0.1/test.flv" -c copy output.flv
当然,可以不使用上述的选项:
ffmpeg -i "http://127.0.0.1/test.flv" -c copy output.flv
ffplay 常用命令
在 FFmpeg 中通常使用 ffplay 作为播放器。不过,ffplay 不仅是播放器,并且可以进行可视化的媒体参数分析。
播放
ffplay input.mp4
ffplay "rtmp://mylive.com/live/test_stream"
ffplay "http://mylive.com/live/test_stream.flv"
更多参数详见:ffplay -h
数据可视化分析
显示音频波形:
ffplay -showmode 1 intput.mp3
显示宏块:
ffplay -debug vis_mb_type input.mp4
显示运动向量信息
ffplay -vismv pf input.mp4
-
pf
: P 帧向前运动估计显示 -
bf
: B 帧向前运动估计显示 -
bb
: B 帧向后运动估计显示
ffprobe 常用命令
ffprobe [options] input_file
常用选项:
-print_format format set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)
-of format alias for -print_format
-select_streams stream_specifier select the specified streams
-show_data show packets data
-show_format show format/container info
-show_frames show frames info
-show_packets show packets info
-show_streams show streams info
-
-print_format
设置输出格式,可以是csv
,json
,xml
等。 -
-select_streams stream_specifier
选择分析的 stream,stream_specifier 详见上文。 -
-show_data
查看媒体包数据 (-show_packets -show_data
一起使用)。 -
-show_format
查看媒体格式或容器的信息。 -
-show_frames
查看每一帧信息。 -
-show_packets
查看每一个数据包信息(不包含包的data)。 -
-show_streams
查看流信息。
示例:
- 查看视频流的帧信息:
ffprobe -show_frames -select_streams v input.flv
- 查看音频流的包信息(并包含data):
ffprobe -show_packets -show_data -select_streams a input.flv
- 查看流信息
ffprobe -show_streams input.flv
Filter
Filter 分为 simple filter 和 complex filter :
-
simple filter
仅支持相同类型的流的单个输入和单个输出,使用-filter
选项 -
complex filter
可支持不同类型的流的多个输入和多个输出,使用-filter_complex
选项
FFmpeg 使用 filter 的参数排列
"[输入流或标记名] filter_arg [临时标记名];[输入流或标记名] filter_arg [临时标记名]..."
simple filter
-filter[:stream_specifier] filtergraph_description (output,per-stream)
创建由 filtergraph_description
指定的 filtergraph 并使用它来 filter 流(per-stream 或stream_specifier)。filtergraph_description
是对要应用于流的 filtergraph 的描述。在 filtergraph_description
中,输入与标签 in
相关联,输出与标签 out
相关联。有关 filtergraph 语法的更多信息,请参阅 ffmpeg-filter 手册。
由于是simple filter
,因此必须具有相同类型的流的单个输入和单个输出(不同类型的多输入和多输出详见:complex filter
)。如果要创建具有多个输入和/或输出的过滤器图,请参阅 -filter_complex
选项。
其他选项
-vf filtergraph_description set video filters
等价于
-filter:v filtergraph_description
simple filtergraph
_________ ______________
| | | |
| decoded | | encoded data |
| frames |\ _ | packets |
|_________| \ /||______________|
\ __________ /
simple _\|| | / encoder
filtergraph | filtered |/
| frames |
|__________|
示例
文字水印:
ffmpeg -i input.mp4 -filter:v "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='hello world':x=20:y=20" output.mp4
图片水印:
ffmpeg -i input.mp4 -filter:v "movie=logo.png[wm]; [in][wm]overlay=30:10[out]" output.mp4
-
movie=logo.png[wm]
中movie
指定水印路径logo.png
,临时标记为wm
。 -
[in][wm]overlay=30:10[out]
中in
是输入标签即input.mp4
,out
是输出标签即output.mp4
,wm
是logo.png
的标记,logo.png
将显示在input.mp4
的 x 坐标 30、y 坐标 10 的位置。
complex filter
-filter_complex graph_description create a complex filtergraph
complex filtergraph
_________
| |
| input 0 |\ __________
|_________| \ | |
\ _________ /| output 0 |
\ | | / |__________|
_________ \| complex | /
| | | |/
| input 1 |---->| filter |\
|_________| | | \ __________
/| graph | \ | |
/ | | \| output 1 |
_________ / |_________| |__________|
| | /
| input 2 |/
|_________|
示例
图片水印:
ffmpeg -i input.mp4 -i logo.png -filter_complex "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" output.mp4
-
[1:v]scale=176:144[logo]
将[1:v]
表示的logo.png
图像流缩放为176:144
并标记为logo
。 -
[0:v][logo]overlay=x=0:y=0
将logo
铺在输入的视频input.mp4
的视频流[0:v]
的左上角。
FFmpeg 采集设备
Linux 平台设备操作
查看设备列表
ffmpeg -devices
Devices:
D. = Demuxing supported
.E = Muxing supported
--
DE fbdev Linux framebuffer
D lavfi Libavfilter virtual input device
DE oss OSS (Open Sound System) playback
DE video4linux2,v4l2 Video4Linux2 output device
fbdev
FrameBuffer 是 Linux 中专门用于图像展示操作。
FFmpeg 采集 Linux 下的 v412
设备时,主要用来采集终端中的图像(命令行操作)。
ffmpeg -framerate 30 -f fbdev -i /dev/fb0 output.mp4
v412
Linux 常见视频设备 video4linux2
缩写为 v4l2
。
FFmpeg 采集 Linux 下的 v4l2
设备时,主要用来采集摄像头。
ffmpeg -framerate 30 -f v4l2 -i /dev/video0 output.mp4
x11grab
FFmpeg 采集 Linux 下的 x11grab
设备时,主要用来采集桌面。
x11grab
的设备名规则:
[主机名]:显示编号id.屏幕编号id[+起始x轴, 起始y轴]
其中,主机名,起始x轴和起始y轴均为可选参数。
桌面录制:
ffmpeg -f x11grab -framerate 30 -video_size 1352x1288 -i :0.0 output.mp4
桌面录制指定起始位置
ffmpeg -f x11grab -framerate 30 -video_size 352x288 -i :0.0+300,200 output.mp4
OS X 平台设备操作
查看设备列表
ffmpeg -devices
D avfoundation AVFoundation input device
D lavfi Libavfilter virtual input device
D qtkit QTKit input device
avfoundation
采集内置摄像头:
ffmpeg -f avfoundation -i "FaceTime HD Camera (Built-in)" output.mp4
采集 OS X 桌面:
ffmpeg -f avfoundation -i "Capture screen 0" -r:v 30 output.mp4
采集麦克风:
ffmpeg -f avfoundation -i "0:0" output.aac
Windows 设备操作
使用 dshow
枚举和采集音视频设备
枚举设备:
./ffmpeg.exe -f dshow -list_devices true -i dummy
采集摄像头和麦克风:
./ffmpeg.exe -f dshow -i video="Integrated Camera" -f dshow -i audio="virtual-audio-capturer" output.mp4
使用 gdigrab
采集桌面或窗口
使用 gdigrab 采集整个桌面:
./ffmpeg.exe -f gdigrab -framerate 6 -i desktop output.mp4
使用 gdigrab 采集某个窗口:
./ffmpeg.exe -f gdigrab -framerate 6 -i title=ffmpeg output.mp4
-
-i title=
指定窗口的标题来进行窗口的查找
带偏移量(offset_x 和 offset_y)和大小(video_size)的采集:
./ffmpeg.exe -f gdigrab -framerate 6 -offset_x 50 -offset_y 50 -video_size 400x400 -i title=ffmpeg output.mp4
参考资料
《FFmpeg官方文档》
《FFmpeg从入门到精通》