Table of Contents
第一章 FFmpeg简介
FFmpege的定义
FF:Fast Forward。
mpeg:Moving Picture Experts Group。
FFmpeg的历史
创始人:Fabrice Bellard。
负责人:Michael Niedermayer。
FFmpeg的构成
- 封装模块AVFormat
只要支持MP4,FLV,KV,TS等文件封装格式;RTMP,RTSP,NMS,HLS等网络协议封装格式。 - 编解码模块AVCodec
自带的媒体编解码格式:MPEG4,AAC,MJPEG;
第三方的:使用X264编码器支持H.264(AVC);使用X265编码器支持H.265(HEVC);使用libmp3lame支持MP3(mp3lame)编码; - 滤镜模块(AVFilter)
AVFilter提供了一个通用的音频、视频、字幕等滤镜处理框架。 - 视频图像转换计算模块swscale
- 音频转换计算模块swsample
FFmpeg的基础命令
转格式
ffmpeg -i input.mp4 output.avi
上面没有明确指定输出文件的容器格式,如果要明确指定,需要用-f
参数指定:
ffmpeg -i input.mp4 -f avi output.dat
在ffmpeg的运行输出信息中的Input #0
和Output #0
可以分别看到输入和输出的格式。
比如ffmpeg -i 2020-09-05-171930.webm 2020-09-05-171930.avi
的输出信息如下:
ffmpeg version 4.1.3-0ppa1~18.04 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
configuration: --prefix=/usr --extra-version='0ppa1~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, matroska,webm, from '2020-09-05-171930.webm':
Metadata:
encoder : GStreamer matroskamux version 1.14.5
creation_time : 2020-09-05T09:19:30.000000Z
Duration: 00:00:11.20, start: 0.000000, bitrate: 1145 kb/s
Stream #0:0(eng): Video: vp8, yuv420p(progressive), 640x480, SAR 1:1 DAR 4:3, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Metadata:
title : Video
Stream #0:1(eng): Audio: vorbis, 44100 Hz, mono, fltp (default)
Metadata:
title : Audio
Stream mapping:
Stream #0:0 -> #0:0 (vp8 (native) -> mpeg4 (native))
Stream #0:1 -> #0:1 (vorbis (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, avi, to '2020-09-05-171930.avi':
Metadata:
ISFT : Lavf58.20.100
Stream #0:0(eng): Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc (default)
Metadata:
title : Video
encoder : Lavc58.35.100 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream #0:1(eng): Audio: mp3 (libmp3lame) (U[0][0][0] / 0x0055), 44100 Hz, mono, fltp (default)
Metadata:
title : Audio
encoder : Lavc58.35.100 libmp3lame
frame= 335 fps=0.0 q=12.6 Lsize= 527kB time=00:00:11.20 bitrate= 385.7kbits/s speed=26.7x
video:412kB audio:87kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 5.661337%
ffmpeg的主要工作流程:
- 解封装(Demuxing)
- 解码(Decoding)
- 编码(Encoding)
- 封装(Muxing)
封装解封装用libavformat,编解码用libavcodec,而中间解码之后的数据为YUV或PCM。
播放文件
ffplay 2020-09-05-171930.avi
多媒体分析器ffprobe
使用ffprobe可以获取媒体文件或者媒体流的编码格式、码率等信息。
ffprobe 2020-09-05-171930.mp4
ffmpeg的编译
第二章 FFmpeg工具使用基础
ffmpeg 常用命令
ffmpeg参数大概可以分为6种:
- ffmpeg信息查询
- ffmpeg公共操作
- 文件操作
- 视频操作
- 音频操作
- 字幕操作
信息查询
- 获取帮助信息
ffmpeg --help
ffmpeg --help long
ffmpeg --help full
这三个命令可以提供三个不同级别的帮助信息。 - 获取license支持信息
ffmpeg -L
- 获取格式支持信息
ffmpeg -formats
ffmpeg会详细列出对每种格式的mux,demux支持。 - 获取编解码器支持信息
ffmpeg -codecs
查看编解码器信息ffmpeg --encoders
只看编码器信息ffmpeg --decoders
只看解码器信息 - 获取滤镜支持信息
ffmpeg -filters
- 查看具体的某一种muxer/demuxer/encoder/decoder/filter支持信息
ffmpeg -h muxer=flv
ffmpeg -h demuxer=flv
ffmpeg -h encoder=h264
ffmpeg -h decoder=h264
ffmpeg -h filter=colorkey
格式封装转换参数
参数 | 类型 | 说明 |
---|---|---|
avioflags | 标记 | format的缓冲设置,默认为0,就是有缓冲 |
avioflags | direct | 无缓冲状态 |
probesize | 整数 | 在进行媒体数据处理前获得文件内容的大小,可用在预读取文件头时提高速度,也可以设置足够大的值来读取到足够多的音视频数据信息 |
fflags | 标记 | |
fflags | flush_packets | 立即将packets数据刷新写入到文件中 |
fflags | genpts | 输出时按照正常规则产生pts |
fflags | nofillin | 不填写可以精确计算缺失的值 |
fflags | igndts | 忽略dts |
fflags | discardcorrupt | 丢弃损坏的帧 |
fflags | sortdts | 尝试以dts的顺序为标准输出 |
fflags | keepside | 不合并数据 |
fflags | fastseek | 快速seek(定位)操作,但是不够精确 |
fflags | latm | 设置RTP MP4_LATM生效 |
fflags | nobuffer | 直接读取或写出,不存入buffer,用于在直播采集时降低延迟 |
fflags | bitexact | 不写入随机或者不稳定的数据 |
seek2any | 整数 | 支持随意位置seek,这个seek不以keyframe为参考 |
analyzeduration | 整数 | 指定解析媒体所需要花销的时间,这里设置的值越高,解析越准确,如果在直播中为了降低延迟,这个值可以设置得低一些 |
codec_whitelist | 列表 | 设置可以解析的codec的白名单 |
format_whitelist | 列表 | 设置可以解析的format的白名单 |
output_ts_offset | 整数 | 设置输出文件的起始时间 |
转码参数
参数 | 类型 | 说明 |
---|---|---|
b | 整数 | 设置音频与视频码率,可以认为是音视频加起来的码率,默认为200kbit/s 使用这个参数可以根据b:v设置视频码率,b:a设置音频码率 |
ab | 整数 | 设置音频的码率,默认是128kbit/s |
g | 整数 | 设置视频GOP(可以理解为关键帧间隔)大小,默认是12帧一个GOP |
ar | 整数 | 设置音频采样率,默认为0 |
ac | 整数 | 设置音频通道数,默认为0 |
bf | 整数 | 设置连续编码为B帧的个数,默认为0 |
maxrate | 整数 | 最大码率设置,与bufsize一同使用即可,默认为0 |
minrate | 整数 | 最小码率设置,配合maxrate与bufsize可以设置为CBR模式,平时很少使用,默认为0 |
bufsize | 整数 | 设置控制码率的buffer的大小,默认为0 |
keyint_min | 整数 | 设置关键帧最小间隔,默认为25 |
sc_threshold | 整数 | 设置场景切换支持,默认为0 |
mc_threshold | 整数 | 设置运动估计阈值,默认为0 |
mb_threshold | 整数 | 设置宏块阈值,默认为0 |
profile | 整数 | 设置音视频的profile,默认为-99 |
level | 整数 | 设置音视频的level,默认为-99 |
timecode_frame_start | 整数 | 设置GOP帧的开始时间,需要在non-drop-frame默认情况下使用 |
channel_layout | 整数 | 设置音频通道的布局格式 |
threads | 整数 | 设置编解码工作的线程数 |
ffmpeg转码例子
ffmpeg -i 2020-09-05-171930.webm -vcodec mpeg4 -b:v 400k -r 15 -an output.mp4
输出信息:
ffmpeg version 4.1.3-0ppa1~18.04 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
configuration: --prefix=/usr --extra-version='0ppa1~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, matroska,webm, from '2020-09-05-171930.webm':
Metadata:
encoder : GStreamer matroskamux version 1.14.5
creation_time : 2020-09-05T09:19:30.000000Z
Duration: 00:00:11.20, start: 0.000000, bitrate: 1145 kb/s
Stream #0:0(eng): Video: vp8, yuv420p(progressive), 640x480, SAR 1:1 DAR 4:3, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Metadata:
title : Video
Stream #0:1(eng): Audio: vorbis, 44100 Hz, mono, fltp (default)
Metadata:
title : Audio
File 'output.mp4' already exists. Overwrite ? [y/N] y
Stream mapping:
Stream #0:0 -> #0:0 (vp8 (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf58.20.100
Stream #0:0(eng): Video: mpeg4 (mp4v / 0x7634706D), yuv420p, 640x480 [SAR 1:1 DAR 4:3], q=2-31, 400 kb/s, 15 fps, 15360 tbn, 15 tbc (default)
Metadata:
title : Video
encoder : Lavc58.35.100 mpeg4
Side data:
cpb: bitrate max/min/avg: 0/0/400000 buffer size: 0 vbv_delay: -1
frame= 170 fps=0.0 q=2.3 Lsize= 655kB time=00:00:11.26 bitrate= 476.3kbits/s dup=0 drop=165 speed=54.2x
video:653kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.244187%
解释:
- 封装格式由webm变为mp4
- 视频编码从vp8变为MPEG4
- 原来没有单独指定视频的码率?但是输出的视频码率定为了400kbps
- 视频帧率从30变为了15
- 转码后的文件不包括音频(
-an
参数)
ffprobe常用命令
查看多媒体数据包
ffprobe -show_packets output.mp4
输出示例:
[PACKET]
codec_type=video
stream_index=0
pts=116736
pts_time=11.400000
dts=116736
dts_time=11.400000
duration=2048
duration_time=0.200000
convergence_duration=N/A
convergence_duration_time=N/A
size=2800
pos=368776
flags=__
[/PACKET]
packet字段说明:
字段 | 说明 |
---|---|
codec_type | 多媒体类型,如视频包,音频包等 |
stream_index | 多媒体的stream索引 |
pts | 多媒体的显示时间值 |
pts_time | 根据不同格式计算过后的多媒体的显示时间 |
dts | 多媒体解码时间值 |
dts_time | 根据不同格式计算过后的多媒体解码时间 |
duration | 多媒体包占用的时间值 |
duration_time | 根据不同格式计算过后的的多媒体包所占用的时间 |
size | 多媒体包的大小 |
pos | 多媒体包所在的文件偏移位置 |
flags | 多媒体包标记,如关键包与非关键包的标记 |
还可以把原始数据一起展示出来:
ffprobe -show_data -show_packets output.mp4
查看封装格式
ffprobe -show_format output.mp4
输出示例:
ffprobe version 4.1.3-0ppa1~18.04 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
configuration: --prefix=/usr --extra-version='0ppa1~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-nonfree --enable-libfdk-aac --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf58.20.100
Duration: 00:00:11.60, start: 0.000000, bitrate: 257 kb/s
Stream #0:0(eng): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 256 kb/s, 5 fps, 5 tbr, 10240 tbn, 5 tbc (default)
Metadata:
handler_name : VideoHandler
[FORMAT]
filename=output.mp4
nb_streams=1
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=11.600000
size=372678
bit_rate=257019
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2mp41
TAG:encoder=Lavf58.20.100
[/FORMAT]
format字段说明:
字段 | 说明 |
---|---|
filename | 文件名 |
nb_streams | 媒体中包含的流的个数 |
nb_programs | 节目数 |
format_name | 使用的封装模块的名称 |
format_long_name | 封装的完整名称 |
start_time | 媒体文件的起始时间 |
duration | 媒体文件的总时间长度 |
size | 媒体文件的大小 |
bit_rate | 媒体文件的码率 |
ffprobe查看视频文件中的帧信息
ffprobe -show_frames output.mp4
示例输出:
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=0
pkt_pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
best_effort_timestamp=0
best_effort_timestamp_time=0.000000
pkt_duration=2048
pkt_duration_time=0.200000
pkt_pos=44
pkt_size=8378
width=640
height=480
pix_fmt=yuv420p
sample_aspect_ratio=1:1
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
color_range=unknown
color_space=unknown
color_primaries=unknown
color_transfer=unknown
chroma_location=left
[SIDE_DATA]
side_data_type=QP table data
[/SIDE_DATA]
[SIDE_DATA]
side_data_type=QP table properties
[/SIDE_DATA]
[/FRAME]
frame字段说明:
属性 | 说明 | 值 |
---|---|---|
media_type | 帧的类型(视频、音频、字幕等) | video |
stream_index | 帧所在的索引区域 | 0 |
key_frame | 是否为关键帧 | 1 |
pkt_pts | Frame包的pts | 0 |
pkt_pts_time | Frame包的pts的时间显示 | 0.000000 |
pkt_dts | Frame包的dts | 0 |
pkt_dts_time | Frame包的dts的时间显示 | 0.000000 |
pkt_duration | Frame包的时长 | 2048 |
pkt_duration_time | Frame包的时长时间显示 | 0.200000 |
pkt_pos | Frame包所在文件的偏移位置 | 44 |
width | 帧显示的宽度 | 680 |
height | 帧显示的高度 | 480 |
pix_fmt | 帧的图像色彩格式 | yuv420p |
pict_type | 帧类型 | I |
ffprobe查看视频文件中的流信息
ffmpeg -show_streams output.mp4
示例输出:
[STREAM]
index=0
codec_name=mpeg4
codec_long_name=MPEG-4 part 2
profile=Simple Profile
codec_type=video
codec_time_base=1/5
codec_tag_string=mp4v
codec_tag=0x7634706d
width=640
height=480
coded_width=640
coded_height=480
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=4:3
pix_fmt=yuv420p
level=1
color_range=unknown
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
quarter_sample=false
divx_packed=false
id=N/A
r_frame_rate=5/1
avg_frame_rate=5/1
time_base=1/10240
start_pts=0
start_time=0.000000
duration_ts=118784
duration=11.600000
bit_rate=256228
max_bit_rate=400000
bits_per_raw_sample=N/A
nb_frames=58
nb_read_frames=N/A
nb_read_packets=N/A
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
TAG:language=eng
TAG:handler_name=VideoHandler
[/STREAM]
stream字段说明:
属性 | 说明 | 值 |
---|---|---|
index | 流所在的索引区域 | 0 |
codec_name | 编码名 | mpeg4 |
codec_long_name | 编码全名 | MPEG-4 part 2 |
profile | 编码的profile | Simple Profile |
level | 编码的level | 1 |
has_b_frames | 包含b帧信息 | 0 |
codec_type | 编码类型 | video |
codec_time_base | 编码的时间戳计算基础单位 | 1/5 |
pix_fmt | 图像显示的色彩格式 | yuv420p |
coded_width | 图i像的宽度 | 640 |
coded_height | 图像的高度 | 480 |
codec_tag_string | 编码的标签数据 | mp4v |
r_frame_rate | 实际帧率 | 5/1 |
avg_frame_rate | 平均帧率 | 5/1 |
time_base | 时间基数(用来进行timestamp计算) | 1/10240 |
bit_rate | 码率 | 200000 |
max_bit_rate | 最大码率 | 400000 |
nb_frames | 帧数 | 58 |
ffprobe设置输出格式
ffprobe可以换其他的格式输出上面查询的信息,并保存到相应文件。
ffprobe -of ini -show_streams output.mp4
ffprobe -of flag -show_streams output.mp4
ffprobe -of xml -show_streams output.mp4
ffprobe -of csv -show_streams output.mp4
ffprobe筛选stream
只看视频流:
ffprobe -show_frames -select_streams v -of xml output.mp4
ffplay常用命令
ffplay基础参数:
参数 | 说明 |
---|---|
x | 强制设置视频显示窗口的宽度 |
y | 强制设置视频显示窗口的高度 |
s | 设置视频显示的宽高 |
fs | 强制全屏显示 |
an | 屏蔽音频 |
vn | 屏蔽视频 |
sn | 屏蔽字幕 |
ss | 根据设置的秒进行定位拖动 |
t | 设置播放视频/音频的长度 |
bytes | 设置定位拖动的策略,0为不可拖动,1为可拖动,-1为自动 |
nodisp | 关闭图形化显示窗口 |
f | 强制使用设置的格式进行解析 |
window_tile | 设置显示窗口的标题 |
af | 设置音频的滤镜 |
codec | 强制使用设置的codec进行解码 |
autorotate | 自动旋转视频 |
ast | 设置将要播放的音频流 |
vst | 设置将要播放的视频流 |
sst | 设置将要播放的字幕流 |
stats | 输出多媒体播放状态 |
fast | 非标准化规范的多媒体兼容优化 |
sync | 音视频同步设置可根据音频时间、视频时间或者外部扩展时间进行参考 |
autoexit | 多媒体播放完毕之后自动退出ffplay,ffplay默认播放完毕之后不退出播放器 |
exitonkeydown | 当有鼠标按下事件产生时退出ffplay |
exitonmousedown | 当有鼠标按键事件产生时退出ffplay |
loop | 设置多媒体文件循环播放的次数 |
framedrop | 当CPU资源占用过高时,自动丢帧 |
infbuf | 设置无极限的播放器buffer,这个选项常见于实时流媒体播放场景 |
vf | 视频滤镜设置 |
acodec | 强制使用设置的音频解码器 |
vcodec | 强制使用设置的视频解码器 |
scodec | 强制使用设置的字幕解码器 |
- 从视频的第2秒开始播放,放5秒钟
ffplay -ss 2 -t 5 ouput.mp4
- 设置播放窗口的标题
ffplay -window_title "hello my title" output.mp4
- 播放rtmp流
ffplay rtmp://xxx
可以配合nginx的rtmp模块搞着玩。 - 对于广电行业的多节目流,需要指定音视频流编号
ffplay -vst 4 -ast 5 xx.ts
- 加载字幕文件
需要使用滤镜ffplay -vf "subtitles=input.srt" output.mp4
- 显示声音波形
ffplay -showmode 1 output.mp3
- 显示解码器如解码每个宏块
下面这个命令应该已经过时了ffplay -debug vis_mb_type output.mp4
貌似可以用(我测试时一片绿色….):ffplay output.mp4 -vf codecview=qp=true
- 显示B帧与P帧预测信息
这个命令也过时了。。。ffplay -vismv pf output.mp4
应该使用:ffplay -flags2 +export_mvs output.mp4 -vf codecview=mv=pf+bf+bb
第三章 FFmpeg转封装
音视频文件转MP4格式
MP4格式标准:ISO-14496 Part12、ISO-14496 Part14
MP4的几个概念:
- MP4文件由许多个Box与FullBox组成
- 每个Box由Header和Data组成
- FullBox是Box的扩展,其在Box结构的基础上,在Header中增加8位version标志和24位的flags标志
- Header包含了整个Box的长度的大小(size)和类型(type),当size等于0时,代表这个Box是文件的最后一个Box。当size等于1时,说明Box长度需要更多的位来描述,在后面会定义一个64位的largesize来描述Box的长度。当type为uuid时,说明这个Box中的数据是用户自定义扩展类型。
- Data为Box的实际数据,可以是纯数据,也可以是更多的子Box
- 当一个Box中Data是一系列的子Box时,这个Box又可以称为Container(容器)Box
MP4常用参考标准排列方式:
(赶时间,暂时懒得抄了。。。)
- moov容器
- mvhd子容器
- trak子容器
- tkhd容器
- mdia容器
- mdhd容器
- hdlr容器
- minf容器
- vmhd容器
- smhd容器
- dinf容器
- stbl容器
- edts容器
MP4分析工具
- Elecard streamEye
貌似是款商业产品。。。 - mp4box
sudo apt install gpac
可以针对媒体文件进行合成、分解等操作。
装好后命令名是MP4Box,基本操作:MP4Box -info output.mp4
示例输出:* Movie Info * Timescale 1000 - Duration 00:00:11.600 1 track(s) Fragmented File: no File Brand isom - version 512 Created: UNKNOWN DATE Modified: UNKNOWN DATE File has no MPEG4 IOD/OD iTunes Info: Encoder Software: Lavf58.20.100 1 UDTA types: meta (1) Track # 1 Info - TrackID 1 - TimeScale 10240 - Media Duration 00:00:11.600 Track has 1 edit lists: track duration is 00:00:11.600 Media Info: Language "eng (eng)" - Type "vide:mp4v" - 58 samples 1 UDTA types: name (1) Visual Track layout: x=0 y=0 width=640 height=480 MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x20 MPEG-4 Visual Size 640 x 480 - Simple Profile @ Level 1 Pixel Aspect Ratio 1:1 - Indicated track size 640 x 480 Self-synchronized RFC6381 Codec Parameters: mp4v.20.1 Average GOP length: 11 samples
其他的使用例子。 - mp4info
sudo apt install mp4v2-utils
为啥我装的这个mp4info命令很弱鸡。。。
原来书上说的mp4info是一个windows下的工具,linux下的应该可以用下这个[MediaParser][https://github.com/ksvc/MediaParser]。
MP4在FFmpeg中的Demuxer
ffmpeg解封装MP4常用参数:
MP4在FFmpeg中的Muxer
ffmpeg封装MP4常用参数:
- faststart参数
正常情况下ffmpeg生产moov是在mdat写完成之后再写入,可以通过参数将moov容器移动至mdat的前面:ffmpeg -i input.flv -c copy -f mp4 output.mp4 ffmpeg -i input.flv -c copy -f mp4 -movflags faststart output.mp4
书中有讲过,如果是在互联网视频点播中,希望这个MP4文件被快速打开,那么需要将moov存放在mdat的前面,否则就只有将MP4文件下载完才可以进行播放。 - dash参数使用案例
ffmpeg -i input.flv -c copy -f mp4 -movflags dash output.mp4
- isml参数使用案例
从来没听说过的东西。。。
视频文件转FLV
FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式。
FLV格式标准
FLV文件格式分为两部分,一部分为FLV文件头,另一部分为FLV文件内容。
- FLV文件头格式解析
- FLV文件内容格式解析
- FLVTAG格式解析
- VideoTag格式解析
- AudioTag格式解析
- ScriptData格式解析
FFmpeg转flv参数
参数 | 类型 | 说明 |
---|---|---|
flvflags | flag | 设置生成FLV时使用的flag |
flvflags | aac_seq_header_detect | 添加AAC音频的Sequence Header |
flvflags | no_sequence_end | 生成FLV结束时不写入sequence end |
flvflags | no_metadata | 生成FLV时不写入metadata |
flvflags | no_duration_filesize | 用于直播时不在metadata中写入duration与filesize |
flvflags | add_keyframe_index | 生成FLV时自动写入关键帧索引信息到metadata头 |
在生成FLV文件时,写入视频、音频数据均需要写入Sequence Header数据。
FFmpeg文件转FLV
FLV封装中可以支持的视频编码:
- Sorenson H.263
- Screen Video
- On2 VP6
- 带Alpha通道的On2 VP6
- Screen Video 2
- H.264(AVC)
FLV封装中支持的音频编码:
- 线性PCM,大小端取决于平台
- ADPCM音频格式
- MP3
- 线性PCM,小端
- Nellymoser 16kHz Mono
- Nellymoser 8kHz Mono
- Nellymoser
- G.711 A-law
- G.711 mu-law
- 保留(WTF?)
- AAC
- Speex
- MP3 8kHz
如果封装flv时,内部的音频或者视频标准不是FLV支持的,那么就会报错,需要先进行专门:
ffmpeg -i input_ac3.mp4 -vcodec copy -acodec aac -f flv output.flv
从上面这个例子可以看出指定输出音频编码为FLV支持的标准即可。
FFmpeg生成带关键索引的FLV
对于网络点播视频,可以用yamdi工具为关键帧建立索引。也可以使用FFmpeg实现:
ffmpeg -i input.mp4 -c copy -f flv -flvflags add_keyframe_index output.flv
FLV文件格式分析工具
- flvparse
- FlvAnalyzer
- ffprobe
ffprobe -v trace -i output.flv
视频文件转M3U8
M3U8格式标准
- EXTM3U
- EXT-X-VERSION
- EXT-X-TARGETDURATION
- EXT-X-MEDIA-SEQUENCE
- EXTINF
- EXT-X-ENDLIST
- EXT-X-STREAM-INF
FFmpeg封装HLS参数
参数 | 类型 | 说明 |
---|---|---|
start_number | 整数 | 设置M3U8列表中的第一片的序列数 |
hls_time | 浮点数 | 设置每一片时长 |
hls_list_size | 整数 | 设置M3U8中分片的个数 |
hls_ts_options | 字符串 | 设置TS切片的参数 |
hls_wrap | 整数 | 设置切片索引回滚的边界值 |
hls_allow_cache | 整数 | 设置M3U8中EXT-X-ALLOW-CACHE的标签 |
hls_base_url | 字符串 | 设置M378中每一片的前置路径 |
hls_segment_filename | 字符串 | 设置切片名模板 |
hls_key_info_file | 字符串 | 设置M3U8加密的key文件路径 |
hls_subtitle_path | 字符串 | 设置M3U8字幕路径 |
hls_flags | 标签(整数) | 设置M3U8文件列表的操作,具体如下: sing_file:生成一个媒体索引与字节范围; delete_segments:删除M3U8文件中不包含的过期的TS切片文件; round_durations:生成的M3U8切片信息的duration为整数; discont_start:生成M3U8的时候在列表前边加上discontinuity标签; omit_endlist:在M3U8末尾不追加endlist标签; |
use_localtime | 布尔 | 设置M3U8文件序号为本地时间戳 |
use_localtime_mkdir | 布尔 | 根据本地时间戳生成目录 |
hls_playlist_type | 整数 | 设置M3U8列表为事件或者点播列表 |
method | 字符串 | 设置HTTP属性 |
举例:
常规的从文件转换为HLS直播
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8
-bsf:v h264_toannexb
是说将MP4中的H.264数据转换为H.264 AnnexB标准的编码。
- 设置start_number
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -start_number 300 output.m3u8
- hls_time参数
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_time 10 output.m3u8
因为ffmpeg这个命令是会从关键帧开始切片,所以这个10秒钟并不是严格的。 - hls_list_size参数
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_list_size 3 output.m3u8
- hls_wrap参数(据说有问题,在新版本中这个参数会被废弃?)
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_wrap 3 output.m3u8
- hls_base_url参数
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_base_url http://localhost output.m3u8
- hls_segment_filename参数
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_segment_filename test_output-%d.ts output.m3u8
- hls_flags参数
- delete_segments
需要配合hls_list_size使用。ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_flags delete_segments -hls_list_size 4 output.m3u8
- round_durations
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_flags round_durations output.m3u8
让m3u8文件里的切片时长信息显示为整型。 - discont_start
在m3u8文件里第一个TS信息前面加上#EXT-X-DISCONTINUITY
表明切片不连续。ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_flags discont_start output.m3u8
- omit_endlist
在m3u8文件末尾不写上endlist标签。ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_flags omit_endlist output.m3u8
- split_by_time
配合hls_time一起使用,达到不按关键帧而是按照指定时间强行切片的效果。造成的问题就是如果你获得的第一个ts不是I帧开头的可能就会花屏或者显示慢。ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_time 2 -hls_flags split_by_time output.m3u8
- delete_segments
- use_localtime参数
ffmpeg -re -i input.mp4 -c copy -f hls -bsf:v h264_mp4toannexb -hls_segment_filename -use_localtime output.m3u8
- method参数
居然ffmpeg配合nginx的webdav模块可以直接把生成的m3u8和ts文件给直接推到服务器上去!
视频文件切片
- segment_format指定切片文件的格式
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 test_output-%d.mp4
- segment_list与segment_list_type指定切片索引列表
- ffconcat
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type ffconcat -segment_list output.lst test_output-%d.mp4
- flat格式
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type flat -segment_list filelist.txt test_output-%d.mp4
- csv格式
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type csv -segment_list filelist.csv test_output-%d.mp4
- m3u8格式
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_list_type m3u8 -segment_list output.m3u8 test_output-%d.mp4
- ffconcat
- reset_timestamps使切片时间戳归0
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -reset_timestamps 1 test_output-%d.mp4
- segment_times按照时间点剪切
ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 -segment_times 3,9,12 test_output-%d.mp4
FFmpeg使用ss与t参数进行切片
- 使用ss指定剪切开头部分
ffmpeg -ss 8 -i input.mp4 -c copy output.ts
- 使用t指定视频总长度
ffmpeg -i input.mp4 -c copy -t 10 -copyts output.ts
- 使用output_ts_offset指定输出start_time
ffmpeg -i input.mp4 -c copy -t 10 -output_ts_offset 120 output.mp4
音视频文件音视频流抽取
抽取AAC音频流
ffmpeg -i input.mp4 -vn -acodec copy output.aac
抽取H.264视频流
ffmpeg -i input.mp4 -vcodec copy -an output.h264
抽取音视频文件中的H.265数据
ffmpeg -i input.mp4 -vcodec copy -an -bsf hevc_mp4toannexb -f hevc output.hevc
第四章 FFmpeg转码
支持H.264的常见封装格式有:FLV,MP4,HLS(M3U8),MKV,TS等。FFmpeg本身不支持H.264编码,主要用x264和OpenH264编码器。使用ffmpeg -h encoder=libx264
可以看到x264支持的像素格式。
x264编码参数
参数 | 类型 | 说明 |
---|---|---|
preset | 字符串 | 编码器预设参数 |
tune | 字符串 | 调优编码参数 |
profile | 字符串 | 编码profile档级设置 |
level | 字符串 | 编码level层级设置 |
wpredp | 字符串 | P帧预测设置 |
x264opts | 字符串 | 设置x264专有参数 |
crf | 浮点数 | 选择质量恒定质量模式 |
crf_max | 浮点数 | 选择质量恒定质量模式最大值 |
qp | 整数 | 恒定量化参数控制 |
psy | 浮点数 | 只用psychovisual优化 |
rc-lookahead | 整数 | 设置预读帧设置 |
weightb | 浮点数 | B帧预测设置 |
weightp | 整数 | 设置预测分析方法:none、simple、smart三种模式 |
ssim | 布尔 | 计算打印SSIM状态 |
intra-refresh | 布尔 | 定时刷I帧以替代IDR帧 |
bluray-compat | 布尔 | 蓝光兼容参数 |
b-bias | 整数 | B帧使用频率设置 |
mixed-refs | 布尔 | 每个partition一个参考,而不是每个宏块一个参考 |
8x8dct | 布尔 | 8×8矩阵变换,用在high profile |
aud | 布尔 | 带AUD分隔标识 |
mbtree | 布尔 | 宏块树频率控制 |
deblock | 字符串 | 环路滤波参数 |
cplxblur | 浮点数 | 减少波动QP参数 |
partitions | 字符串 | 逗号分隔的partition列表,可以包含的值有p8x8,p4x4,b8x8,i8x8,i4x4,none,all |
direct-pred | 整数 | 运动向量预测模式 |
slice-max-size | 整数 | Slice的最大值 |
nal-hrd | 整数 | HRD信号信息设置:None,VBR,CBR设置 |
motion-est | 整数 | 运动估计方法 |
forced-idr | 整数 | 强行设置关键帧为IDR帧 |
coder | 整数 | 编码器类型包括default、cavlc、cabac、vlc、ac |
b_strategy | 整数 | I/P/B帧选择策略 |
chromaoffst | 整数 | QP色度和亮度之间的差异参数 |
sc_threshold | 整数 | 场景切换阈值参数 |
noise_reduction | 整数 | 降噪处理参数 |
x264-params | 字符串 | 与x264opts操作相同 |
编码举例
编码器预设参数preset
- ultrafast
- superfast
- veryfast
- faster
- fast
- medium
- slow
- slower
- veryslow
- placebo
ffmpeg -i 2020-09-05-171930.mp4 -vcodec libx264 -preset ultrafast -b:v 100k output.mp4
在命令的输出中有显示:
frame= 336 fps=0.0 q=-1.0 Lsize= 245kB time=00:00:11.16 bitrate= 179.4kbits/s speed=29.9x
表示转码所花时间是视频本身时间的29.9分之一。
H.264编码优化参数tune
- film
- animation
- grain
- stillimage
- psnr
- ssim
- fastdecode
- zerolatency
在使用FFmpeg与x264进行H.264的直播编码推流时可以使用zerolatency模式降低因编码导致的延迟。
H.264的profile与level设置
profile:
- Baseline
- Extend
- Main
- High
- High10
- High422
- High444
控制场景切换关键帧插入参数sc_threshold
设置x264内部参数x264opts
CBR恒定码率设置参数nal-hrd
硬件编解码
Nvidia GPU
Intel QSV
第五章 FFmpeg流媒体
发布与录制rtmp流
rtmp参数:
参数 | 类型 | 说明 |
---|---|---|
rtmp_app | 字符串 | RTMP流发布点,又称为APP |
rtmp_buffer | 整数 | 客户端buffer大小(单位:毫秒),默认为3秒 |
rtmp_conn | 字符串 | 在RTMP的Connect命令中增加自定义AMF数据 |
rtmp_flashver | 字符串 | 设置模拟的flashplugin的版本号 |
rtmp_live | 整数 | 指定RTMP流媒体播放类型,可以为any、live、recorded |
rtmp_pageurl | 字符串 | RTMP在Connect命令中设置的PageURL字段,其为播放时所在的Web页面URL |
rtmp_playpath | 字符串 | RTMP流播放的Stream地址,或者成为密钥,或者称为发布流 |
rtmp_subscribe | 字符串 | 直播流名称,默认设置为rtmp_playpath的值 |
rtmp_swfhash | 二进制数据 | 解压swf文件后的SHA256的hash值 |
rtmp_swfsize | 整数 | swf文件解压后的大小,用于swf认证 |
rtmp_swfurl | 字符串 | RTMP的Connect命令中设置的swfURL播放器的URL |
rtmp_swfverify | 字符串 | 设置swf认证时swf文件的URL地址 |
rtmp_tcurl | 字符串 | RTMP的Connect命令中设置的tcURL目标发布点地址,一般形如rtmp://xxx.xxx.xxx/app |
rtmp_listen | 整数 | 开启RTMP服务时所监听的端口 |
listen | 整数 | 与rtmp_listen相同 |
timeout | 整数 | 监听rtmpu端口时设置的超时时间,以秒为单位 |
推流:
ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app live -rtmp_playpath class rtmp://publish.chinaffmpeg.com
#可以省略掉rtmp_app参数与rtmp_playpath参数
ffmpeg -i input.mp4 -c copy -f flv rtmp://publish.chinaffmpeg.com/live/class
拉流:
ffmpeg -rtmp_app live -rtmp_playpath class -i rtmp://publish.chinaffmpeg.com -c copy -f flv output.flv
#同样的,命令可以简写
ffmpeg -i rtmp://publish.chinaffmpeg.com/live/class -c copy -f flv output.flv
录制rtsp流
通过ffmpeg -h demuxer=rtsp
查看rtsp协议相关参数:
参数 | 类型 | 说明 |
---|---|---|
initial_pause | 布尔 | 建立廉洁后暂停播放 |
rtsp_transport | 标记 | 设置rtsp的传输协议,可以为udp、tcp、udp_multicast、http |
rtsp_flags | 标记 | 可以为filter_src(只接收指定IP的流)、listen(设置为被动接受模式)、prefer_tcp(TCP可用情况下传输协议首选TCP) |
allowed_media_types | 标记 | 设置允许接受的数据模式(默认全部开启):video,audio,data,subtitle |
min_port | 整数 | 设置最小本地UDP端口,默认为5000 |
max_port | 整数 | 设置最大本地UDP端口,默认为65000 |
timeout | 整数 | 设置监听端口超时时间 |
reorder_queue_size | 整数 | 设置录制数据Buffer的大小 |
buffer_size | 整数 | 设置底层传输包Buffer的大小 |
user-agent | 字符串 | 用户客户端标识 |
rtsp录制直播流:
ffmpeg -rtsp_transport tcp -i rtsp://47.90.47.25/test.ts -c copy -f mp4 output.mp4
添加User-Agent:
ffmpeg -user-agent "ChinaFFmpeg-Player" -i rtsp://input:554/live/1/stream.sdp -c copy -f mp4 -y output.mp4
录制http流
这节讲的所谓http直播,其实就是将视频文件用http方式提供出来,然后ffmpeg既可以作为http服务器,也可以作为http客户端。
ffmpeg支持的参数:
参数 | 类型 | 说明 |
---|---|---|
seekable | 布尔 | 设置HTTP链接为可以seek操作 |
chunked_post | 布尔 | 使用Chunked模式post数据 |
http_proxy | 字符串 | 设置HTTP代理传输数据 |
headers | 字符串 | 自定义HTTP Header数据 |
content_type | 字符串 | 设置POST的内容类型 |
user_agent | 字符串 | 设置HTTP请求客户端信息 |
multiple_requests | 布尔 | HTTP长连接开启 |
post_data | 二进制数据 | 设置将要POST的数据 |
cookies | 字符串 | 设置HTTP请求时携带的Cookies |
icy | 布尔 | 设置ICY元数据,默认打开 |
anth_type | 整数 | HTTP验证类型设置 |
offset | 整数 | 初始化HTTP请求时的偏移位置 |
method | 字符串 | 发起HTTP请求时使用的HTTP的方法 |
reconnect | 布尔 | 在EOF之前断开发起重连 |
reconnect_at_eof | 布尔 | 在得到EOF时发起重连 |
reply_code | 整数 | 作为HTTP服务时向客户端反馈状态码 |
举例:
seek操作:
ffmpeg -ss 30 -seekable 1 -i http://bbs.chinaffmpeg.com/test.ts -c copy -y output.mp4
headers参数设置:
ffmpeg -headers "referer: http://bbs.chinaffmpeg.com/index.html" -i http://play.chinaffmpeg.com/live/class.flv -c copy -f flv -y output.flv
user_agent参数设置:
ffmpeg -user_agent "LiuQi's Player" -i http://bbs.chinaffmpeg.com/1.flv
拉流录制:
ffmpeg -i http://bbs.chinaffmpeg.com/live.flv -c copy -f flv output.flv
ffmpeg -i http://bbs.chinaffmpeg.com/live.ts -c copy -f flv output.flv
ffmpeg -i http://bbs.chinaffmpeg.com/live.m3u8 -c copy -f flv output.flv
录制和发布UDP/TCP流
所谓录制和发布UDP/TCP流是ffmpeg通过自己的私有协议传输音视频流。
TCP参数:
参数 | 类型 | 说明 |
---|---|---|
listen | 整数 | 作为Server时监听TCP的端口 |
timeout | 整数 | 获得数据超时时间(微妙) |
listen_timeout | 整数 | 作为Server时监听TCP端口的超时时间(毫秒) |
send_buffer_size | 整数 | 通过socket发送的buffer大小 |
recv_buffer_size | 整数 | 通过socket读取的buffer大小 |
UDP参数列表:
参数 | 类型 | 说明 |
---|---|---|
buffer_size | 整数 | 系统数据buffer大小 |
bitrate | 整数 | 每秒钟发送的码率 |
localport | 整数 | 本地端口 |
localaddr | 整数 | 本地地址 |
pkt_size | 整数 | 最大UDP数据包大小 |
reuse | 布尔 | UDP socket复用 |
broadcast | 布尔 | 广播模式开启与关闭 |
ttl | 整数 | 多播时配合使用的存活时间 |
fifo_size | 整数 | 管道大小 |
timeout | 整数 | 设置数据传输的超时时间 |
使用举例:
# 作为服务器
ffmpeg -listen 1 -f flv -i tcp://127.0.0.1:1234/live/stream -c copy -f flv output.flv
# 作为客户端
ffmpeg -re -i input.mp4 -c copy -f flv tcp://127.0.0.1:1234/live/stream
# 作为客户端
ffmpeg -re -i input.mp4 -c copy -localport 23456 -f flv udp://192.168.100.179:1234/live/stream
几个listen_timeout、timeout、send_buffer_size、recv_buffer_size的例子懒得列了,看一眼参数说明就会用。
推多路流
这节讲的就是如何把一路流同时推到多个地方去。
- 用管道
ffmpeg -i input.mp4 -vodec libx264 -acodec aac -f flv - | ffmpeg f flv -i - -c copy -f flv rtmp://publish.chinaffmpeg.com/live/stream1 -c copy -f flv rtmp://publish.chinaffmpeg.com/live/stream2
- 用tee封装格式
ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -map 0 -f tee "[f=flv]rtmp://publish.chinaffmpeg.com/live/stream1 | [f=flv]rtmp://publish.chinaffmpeg.com/live/stream2"
- 用tee协议
ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -f flv "tee:rtmp://publish.chinaffmpeg.com/live/stream1|rtmp://publish.chinaffmpeg.com/live/stream2"
HDS流
window_size
参数控制文件列表大小ffmpeg -i input -c copy -f hds -window_size 4 output
extra_window_size
参数控制文件个数ffmpeg -re -i input.mp4 -c copy -f hds -window_size 4 -extra_window_size 1 output
DASH流
window_size
与extra_window_size
参数ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 index.mpd
single_file
参数ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 -single_file 1 index.mpd
第六章 FFmpeg滤镜使用
FFmpeg的滤镜处理(filter)就是对视频和音频做一些缩放、合并、翻转之类的常规操作,这些操作自己实现也不见得有多困难,但是自己实现的可能没人家高效,定义的接口没有人家设计的好。
FFmpeg的滤镜官方文档。
filter的语法
读官方文档,会先让你体会一个使用滤镜的例子:
ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
上面的命令描述了如下所示的一个处理流程图:
[main]
input --> split ---------------------> overlay --> output
| ^
|[tmp] [flip]|
+-----> crop --> vflip -------+
可以看出滤镜大概就是用给定的输入源作为起始节点,对这些起始节点不断应用滤镜可以得到新的节点,最后选取某些节点作为我们想要的输出就可以了。
关于滤镜语法的几点总结:
-vf
和filter_complex
不能同时使用。
使用filter_complex
,可用通过""
描述一个足够完整和复杂的处理流图。- 多个滤镜之间用
;
相隔;
位于同一条chain的滤镜可以用,
相隔; - 滤镜的参数用
<filter>=arg1=a:arg2=b
这样的key、val对方式提供,不同的key、val对之间用:
相隔;
滤镜的参数也可以不把key写出来,只把val用冒号分开就可以,只是参数的顺序必须要和filter接受的参数保持一致;
写key和不写key的两种描述参数的方式可以混用,只是只能前面的多个按顺序描述的key、val对可以省略掉参数名,后面的参数必须都把参数名写出来; - 每个滤镜都有输入和输出,用
[input/output]
表示,输入和输出可以有多个,输入写在滤镜名字的前面,输出写在滤镜名字的后面; - 滤镜的输入和输出可以不写,上一个无名输出会作为下一个无名输入;
- 滤镜是基于解码后的画面进行操作的;
可以在指定完要进行的filter操作之后再指定编码器;
适用于filter的内置变量:
变量 | 说明 |
---|---|
t | 时间戳以秒表示,如果输入的时间戳是未知的,则是NAN |
n | 输入帧的顺序编号,从0开始 |
pos | 输入帧的位置,如果未知则是NAN |
w | 输入视频帧的宽度 |
h | 输入视频帧的高度 |
为视频添加水印
- 文字水印
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test]; [in][test]overlay[out]" -vcodec libx264 output.flv
`ffmpeg -re -i input.mp4 -vf “movie=sub.mp4,scale=480×320[test]; [in][test]overlay=x=main_w-480:y=main_h-320[out]” -vcodec libx264 output.flv” - 图片水印
ffmpeg -i input.mp4 -vf "movie=logo.png[wm]; [in][wm]overlay=30:10[out]" output.mp4
ffmpeg -i input.mp4 -vf "movie=logo.png,colorkey=black:1.0:1.0[wm];[in][wm]overlay=30:10[out]" output.mp4
画中画
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay[out]" -vcodec libx264 output.flv
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay=x=main_w-480:y=main_h-320[out]" -vcodec libx264 output.flv
ffmpeg -re -i input.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay=x='if(gte(t,2), -w+(t-2)*20,NAN)':y=0[out]" -vcodec libx264 output.flv
这个例子通过内置变量实现了跑马灯式的画中画效果。
多宫格
多宫格和画中画其实没有本质上的区别,都是用overlay这个滤镜,这里列一个官方文档的例子:
ffmpeg -i left.avi -i right.avi -filter_complex "
nullsrc=size=200x100 [background];
[0:v] setpts=PTS-STARTPTS, scale=100x100 [left];
[1:v] setpts=PTS-STARTPTS, scale=100x100 [right];
[background][left] overlay=shortest=1 [background+left];
[background+left][right] overlay=shortest=1:x=100 [left+right]
"
音频流滤镜操作
- 双声道合并单声道
ffmpeg -i input.aac -ac 1 output.aac
- 双声道提取
ffmpeg -i input.aac -filter_complex "[0:0]pan=1c|c0=c0[left];[0:0]pan=1c|c0[right]" -map "[left]" left.aac -map "[right]" right.aac
pan滤镜的介绍
pan滤镜的参数:l|outdef|outdef|...
。 - 双声道转双音频流
ffmpeg -i input.aac -filter_complex channelsplit=channel_layout=stereo output.mka
把双声道音频转为了两个单声道的音频流。 - 单声道转双声道
ffmpeg -i left.aac -ac 2 output.m4a
- 两个音频源合并双声道
两个单声道音频流合并为一个stereo双声道音频流:ffmpeg -i left.aac -i right.aac -filter_complex "[0:a][1:a] amerge=inputs=2[aout]" -map "[aout]" output.mka
- 多音频合并为多声道
ffmpeg -i front_left.wav -i front_right.wav -i front_center.wav -i lfe.wav -i back_left.wav -i back_right.wav -filter_complex "[0:a][1:a][2:a][3:a][4:a][5:a] amerge=inputs=6[aout]" -map "[aout]" output.wav
音频音量探测
- 音频音量
ffmpeg -i output.wav -filter_complex volumedetect -c:v copy -f null /dev/null
- 绘制音频波形
ffmpeg -i output.wav -filter_complex "showwavespic=s=640x120:split_channels=1" -frames:v 1 output.png
ffmpeg -i output.wav -filter_complex "showwavespic=s=640x120" -frames:v 1 output.png
为视频加字幕
- 通过滤镜添加ASS字幕
ffmpeg -i input.mp4 -vf ass=t1.ass -f mp4 output.mp4
- 将ass字幕写入封装容器中
ffmpeg -i input.mp4 -i t1.ass -acodec copy -vcodec copy -scodec copy output.mkv
ffmpeg -i input.mp4 -i t1.ass -map 0:0 -map 0:1 -map 1:0 -acodec copy -vcodec copy -scodec copy output.mkv
扣图合并
使用chromakey滤镜可以进行扣图处理,然后通过overlay滤镜就可以把一个纯色背景下的人物融合到另外一个画面中去了。
chromakey参数:
参数 | 类型 | 说明 |
---|---|---|
color | 颜色 | 设置chromakey颜色值,默认为黑色 |
similarity | 浮点 | 设置chromakey相似值 |
blend | 浮点 | 设置chromakey融合值 |
yuv | 布尔 | yuv代替rgb,默认为false |
颜色代号可以通过ffmpeg -colors
命令查询。
ffmpeg -i input.mp4 -i input_green.mp4 -filter_complex "[1:v]chromakey=Green:0.1:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" output.mp4
除了chromakey滤镜还可以使用colorkey滤镜,chromakey用于处理YUV数据,colorkey处理纯色数据都可以。
3D视频处理
定时视频截图
- 获取指定时刻的截图
ffmpeg -i input.flv -ss 00:00:7.435 -vframes 1 out.png
- 用fps滤镜获取图片
ffmpeg -i input.flv -vf fps=1 out%d.png
1秒钟截图一次ffmpeg -i input.flv -vf fps=1/60 img%03d.jpg
1分钟截图一次ffmpeg -i input.flv -vf fps=1/600 thumb%04d.bmp
10分钟截图一次ffmpeg -i input.flv -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr thumb%04d.png
按照I帧截图
生成测试元数据
- 生成音频测试流
可以通过lavfi虚拟音频源的abuffer、aevalsrc、anullsrc、flite、anoisesrc、sine滤镜生成音频流:ffmpeg -re -f lavfi -i abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo -acodec aac -y output.aac
ffmpeg -re -f lavfi "aevalsrc=sin(420*2*PI*t)|cos(430*2*PIT*t):c=FC|BC" -acodec aac output.aac
- 生成视频测试流
可以通过lavfi虚拟视频源的allrgb、allyuv、color、haldclutsrc、nullsrc、rgbtestsrc、smptebars、smptehdbars、testsrc、testsrc2、yuvtestsr等滤镜生成视频流:ffmpeg -re -f lavfi -i testsrc=duration=5.3:size=qcif:rate=25 -vcodec libx264 -r:v 25 output.mp4
ffmpeg -re -f lavfi -i testsrc2=duration=5.3:size=qcif:rate=25 -vcodec libx264 -r:v 25 output.mp4
ffmpeg -re -f lavfi -i color=c=red@0.2:s=qcif:r=25 -vcodec libx264 -r:v 25 output.mp4
ffmpeg -re -f lavfi -i "nullsrc=s=256x256, geq=random(1)*255:128:128" -vcodec libx264 -r:v 25 output.mp4
倍速处理
- 音频倍速处理
atempo滤镜可以用来处理音频的倍速,其只有一个参数tempo,取值0.5到2.0之间,分别表示速度为原来的一半和2倍。ffmpeg -i input.wav -filter_complex "atempo=tempo=0.5" -acodec aac output.aac
ffmpeg -i input.wav -filter_complex "atempo=tempo=2.0" -acodec aac output.aac
- 视频倍速处理
seepts滤镜用于处理视频倍速,其只有一个参数expr,用于描述视频的每一帧的时间戳。值说明FRAME_RATE根据帧率设置帧率值,只用于固定频率PTS输入的pts时间戳RTCTIME使用RTC的时间作为时间戳(即将弃用)TB输入的时间戳的时间基(timebase)ffmpeg -re -i input.mp4 -filter_complex "septs=PTS*2" output.mp4
这个命令把原来的视频调整为了半速播放。ffmpeg -re -i input.mp4 -filter_complex "septs=PTS/2" output.mp4
这个命令把原来的视频调整为了2倍速播放。
第七章 FFmpeg采集设备
Linux
- 查看设备列表
ffmpeg -devices
- 从fbdev中采集fbdev是终端里的图像
ffmpeg -framerate 30 -f fbdev -i /dev/fb0 output.mp4
- 从v4l2采集v4l2是摄像头采集到的图像
# 查询摄像头支持的格式 ffmpeg -f v4l2 -list_formats all -i /dev/video0 # 从摄像头录像 ffmpeg -s 1920x1080 -i /dev/video0 output.avi
- 从x11grab采集
这个是采集的桌面上显示的图像。x11grab支持的参数:参数类型说明draw_mouse整数支持绘制鼠标光标follow_mouse整数跟踪鼠标轨迹数据framerate字符串输入采集的视频帧率show_region整数获得输入桌面的指定区域region_border整数当show_region为1时,设置输入指定区域的边框的粗细程度video_size字符串输入采集视频的分辨率输入设备的命名规则:[主机名]:显示编号id.屏幕编号id[+起始x轴,起始y轴]
# 桌面录制
ffmpeg -f x11grab -framerate 25 -video_size 1366x768 -i :0.0 out.mp4
# 桌面录制指定区域
ffmpeg -f x11grab -framerate 25 -video_size 352x288 -i :0.0+300,200 out.mp4
# 桌面录制带鼠标记录的视频
ffmpeg -f x11grab -video_size 1366x768 -follow_mouse 1 -i :0.0 out.mp4
近期评论