1. 基本概念
1.1 容器(Container)
容器也就是封装格式,例如MP4。容器中主要包含以下内容:
-
视频流(Video Stream):视频数据
-
音频流(Audio Stream):音频数据
-
元数据(Meta Data):码率、帧率、分辨率等等
有些容器还可以外挂字幕文件,例如MKV。
把视频、音频、元数据、字幕这些数据打包成一个容器数据,有个好听的词叫:封装。
容器用来装东西,不介意装什么,相同的编码也可以使用不同的容器。就好比,牛奶用碗装还是用奶瓶装,并不影响牛奶本身。
ffmpeg格式转换把MP4视频使用H264编码,音频使用ACC编码,转换为MKV之后,视频还是使用H264编码,音频还是使用ACC编码。
常见容器
容器 | 公司或组织 | 说明 |
---|---|---|
AVI | 微软 | 有损压缩,基本被淘汰技术 |
MOV | 苹果 | 老使用少 |
RM | Real Networks | 体积小,画质不错 |
RMVB | Real Networks | RM进化版,VB,Variable Bit Rate比特率可变 |
ASF | 微软 | WMA、WMV |
MKV | 开源 | 能容纳多种不同类型编码的视频、音频及字幕流 |
MPG/MPEG | MPEG | 受支持比较广泛 |
FLV | Adobe | 视频网站常用 |
HLS | 苹果 | 自适应码率的格式,视频网站、直播常用,如果看到.m3u8后缀的请求,多半使用的是这种格式 |
MPEG-DASH | MPEG | 开源自适应码率的格式,国际标准 |
1.2 编码解码器(codec)
主要Codec不是特指编码,而是编码和解码的复合体,由Coder和Decoder组成。
常见视频编码格式
编码 | 说明 |
---|---|
MPEG-1 | VCD使用这种编码,常见后缀.mpg、.mlv、.mpe、.mpeg、.dat |
MPEG-2 | DVD使用这种编码,常见后缀.mpg、.mpe、.mpeg、.m2v、.vob |
MPEG-4 | 为了播放流式媒体的高质量视频而专门设计,.mp4、.asf、.mov |
H26X | 国际电传视讯联盟(ITU)主导,最常见的是H264 |
wmedia系列 | Mpeg-4 v1/v2/v3,Windows Media Video 7/8/9/10 |
VP9 | VP9 Google开放格式、无需授权费的Codec,压缩率不错,资源需求高 |
AV1 | 开放媒体联盟开发,免授权 |
H264也叫Advanced Video Coding(AVC)是现在最常见的codec,它的压缩比是MPEG-4的1.5-2倍,但是它需要授权费。
H265也叫High Efficiency Video Coding(HEVC),是h264的升级版本,压缩率可以达到h264的2倍,但是它需要的计算资源也多,并且也需要授权费。
压缩率很重要,越高的压缩率,意味着同样质量的视频占用的存储空间越小,这对那些视频公司非常重要,因为能极大的节省存储和带宽费用。
所以,对与做视频的大公司授权费不可怕,可怕是有钱,买不到技术。例如,国内字节就有利用人工智能编码的技术,比现有很多公开的编码技术的压缩率高。
他们现在肯定不会因为一点授权费就把这技术给别人用,只有自己有,意味着比对手更低的成本,就有弄死对手的可能。
常见音频编码格式
编码 | 说明 |
---|---|
MP3 | 有损编码、听不出来是因为人类的听力局限性 |
ACC | 相同码率下,音频质量比MP3更高,在音频通道中有局限性 |
AC3 | 对音频通道有完整支持 |
OGG | 完全免费,支持多声道 |
FLAC | 免费,无损压缩 |
如果你对视频剪辑有所了解,就会发现很多教程教你选编码格式就是H.264 + ACC,这是因为这是现在最常见的组合,也应该算是现在各个视频网站支持最好的codec了。
1.3 采样率
单位是Hz,表示每秒采样的次数,采样率越大,精度就越高,处理出来的文件就越接近原始数据。
例如,很多会议工具录制视频的时候声音的采样率就是33000Hz,我们剪辑视频的时候,声音的采样率通常设置为44100Hz,但是通常不会超过48000Hz。
1.4 采样位数
也叫采样值或取样值,用来衡量声音波动变化的一个参数,采用位数越大,所发出声音的能力越强。
音频文件大小(byte) = (采样频率 * 采样位数 * 声道 *时间)/8
1.5 码率(比特率)
数据传输时单位时间传送的数据位数,用的单位Kbps,Mbps,码率越高,单位时间的数据越多,意味着画面质量越好。
我们通过码率和文件大小就能算出视频时长。
1.6 帧率(FPS)
以帧称为单位的位图图像连续出现在显示器上的频率。
简单来说,帧率衡量的是画面的丝滑(连贯)程度,通常情况下帧率越高,画面越丝滑。
1.7 分辨率
视频中的分辨率,可以简单的理解为画面大小,就是长有多少像素,宽有多少像素。
2. FFMPEG基本操作
FFMPEG非常强大,但是我们使用它做得最多的操作是:
- 格式转换
- 获取视频声音
- 添加字幕
简单的操作:截图、合并截取视频片段、生成gif很多播放器就能做。
复杂的操作:可能需要使用更专业的剪辑软件更方便。
下面我就先来介绍一下FFMPEG的常见操作,其他的我们在后面介绍。
2.1 截取
时间相关参数:
参数 | 说明 |
---|---|
t duration | 截取多少秒的视频 |
to time_stop | 截取到那个时间点结束 |
fs limit_size | 截取多少字节 |
ss time_off | 截取的开始时间 |
sseof time_off | 相对于视频结尾的开始时间点,截取最后几秒,使用负数 |
# -ss 5指定从输入视频第5秒开始截取,-t 10指截取10秒,-c:v copy拷贝,-c:a copy声音拷贝
ffmpeg -i input.mp4 -ss 5 -t 10 -c:v copy -c:a copy output.mp4
# 如果不指定-c:v copy -c:a copy会使用默认编码,比拷贝慢
ffmpeg -i input.mp4 -ss 5 -t 10 output.mp4
# 00:00:30开始,截取5秒
ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:05 -vcodec copy -acodec copy output.mp4
# 截取最后20s,注意-sseof的位置,不知道为什么,这个参数的位置调换会出错
ffmpeg -sseof -20 -i input.mp4 output.mp4
ffmpeg -sseof -0:20 -i input.mp4 output.mp4
2.2 分离合并
# -i参数指定输入文件,默认使用原来的codec,指改变容器
ffmpeg -i input.mp4 output.ts
# c:a copy指直接拷贝声音,c:v copy指直接拷贝视频,即codec不变,基本和上一个命令等价
ffmpeg -i input.avi c:a copy c:v copy output.mp4
# -map 0是选择所有流,-f指定格式为segment -segment_list指定列表文件
ffmpeg -i math.mp4 -c copy -map 0 -f segment -segment_list math.m3u8 -segment_time 10 math-%04d.ts
# 获取视频声音,-vn去除视频部分 -c:a copy拷贝声音
ffmpeg -i input.mp4 -vn -c:a copy audio.mp3
# 获取视频,-an去除视频声音 -c:v copy 拷贝视频
ffmpeg -i input.mp4 -an -c:v copy video.mp4
# 一步到位,分离视频和音频
ffmpeg -i input.mp4 -c:v copy -an video.mp4 -c:a -vn audio.mp3
# 合并视频和音频
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a copy output.mp4
2.3 字幕
# 将.srt文件转换成.ass文件
ffmpeg -i subtitle.srt subtitle.ass
# 将.ass文件转换成.srt文件
ffmpeg -i subtitle.ass subtitle.srt
# -c:s mov_text字幕使用mov_text操作,-c:v copy视频拷贝 -c:a copy音频拷贝
ffmpeg -i input.mp4 -i subtitles.srt -c:s mov_text -c:v copy -c:a copy output.mp4
# 还可以使用-vf
ffmpeg -i input.mkv -vf subtitles=input.srt output.mp4
# 软挂载,mkv容器支持软挂载,所以可以使用-c copy直接拷贝,优点是速度快
ffmpeg -i input.mp4 -i input.srt -c copy output.mkv
字幕分软挂载和硬挂载:
- 软挂载是把字幕文件添加在容器中,基本只有一个拷贝操作,所以速度非常快
- 硬挂载是把字幕渲染到视频中,要把字幕文件的内容读取出来,然后一帧一帧添加到视频中,所以比较慢
软挂载虽然快,但是它需要容器支持,例如mkv就支持软挂载,mp4格式就只支持硬挂载。
2.4 帧率
视频帧率是一个非常重要的参数,它决定了视频的流畅程度,如果要视频看起来连贯,而不是一张一张的图片,帧率至少需要15。
# 使用-r参数
ffmpeg -i input.mp4 -r 15 output.mp4
# 使用fps filter设置帧率
ffmpeg -i input.mp4 -vf fps=25 output.mp4
# 使用预设值,电影标准24帧每秒
ffmpeg -i input.mp4 -r film output.mp4
关于帧率的预定义值可以参考后面的帧率预定义表。
2.5 码率
视频的码率也是一个非常重要的参数。
码率 = 视频文件大小(bit) / 时长(s)
例如,时长1分钟,大小100M的视频文件的码率:
100 * 1024 * 1024 * 8 / 60 = 13981013.33 bps = 13981kbps = 13.98Mbps
视频包含音频的码率和视频的码率
码率 = 视频的码率 + 音频的码率
通过码率我们能够控制视频的大小和质量
音频码率计算
音频的码率 = 采样率 * 位深度 *通道数
44.1k * 16 * 2 = 1411.2kbps
采样率:我们前面介绍过,44.1kHz表示每秒采样数据点是44100个。
位深度:决定声音动态范围,可以看做是分贝大小,通常16位,最高可以记录96分贝(dB),20位可以记录120分贝,24位可以记录144分贝。
通道数:例如单声道、立体声道,单声道使用1个喇叭,立体声分左右声道,可以使用2个喇叭。
常见音频码率:
- MP3: 128kbps
- LC-AAC: 112kbps
- HE-AAC(SBR): 96kbps
- HE-AAC(v2): 48kbps
视频码率计算
我们已经知道,视频就是连续的图片,所以计算视频码率,我们先计算图片大小。
视频和图片都有一个分辨率,例如4k的分辨率4096*2160,这个表示width上有4096个像素,height上有2304个像素,总共8847360像素。
一张4096*2160分辨率的图片,图片数据有多大呢?还涉及另一个参数:像素深度,也就是有多少位表示1个像素。
- 1位:用1bit表示颜色,单色显示,最常见的就是红色黑底的LED屏
- 8位:用8bit表示颜色,可以显示2^8=256种颜色,黑白屏
- 16位:用16bit表示颜色,可以显示2^16=65536种颜色。RGB565(5位表示R红色、6位表示G绿色、5位表示B蓝色)
- 24位:用24bit表示颜色,可以显示2^24=16777216种颜色。RGB888(8位R红色、8位G绿色、8位B蓝色)
- 32位:32位在24位基础上加上了透明度,ARGB
16位深度会失真,我们一般的照片图片也不会使用透明度,所以,我们通常看到的图片位深度基本都是24位(bit)。
一个像素24位,8847360像素总共212336640bit=26542080Byte=25920KB=25.3125MB
上面只是理论计算,通常我们在相机原图才会看到图片这么大,会因为图片格式不同压缩比不同,实际使用的图片可能会小很多。
视频中,如果我们使用电影的帧率24,即每秒24帧,那么1秒的数据就是24 * 25.3125 = 607.5MB,只是1秒的数据。
一部电影90分钟,607.5M * 5400 = 3280500MB = 3203.61G
这样算下来,一部电影的原片几十上百G,是不是也没什么大不了。
前面我们已经计算到每秒数据:607.5M = 607.5 * 1024 = 622080KB = 637009920Byte = 5096079360bit
所以码率:5096079360bit/s ≈ 5096079kbps ≈ 5096Mbps ≈ 5Gbps
注意:在很多bps相关单位,如带宽、码率等中通常K是指1千(103)、M是指百万(106)、G是指10亿(10^9)
光看每秒607.5MB数据(大约5Gbps)可能没啥概念,要和机械硬盘的读写速度100MB/s左右,SATA协议的固态硬盘速度500MB/s左右一对比就有感觉了。
现在是不是对视频剪视度慢、卡顿有更直观的认识了?
实际上现阶段,码率基本达不到5Gbps,数字电影倡导联盟(DCI)规定了数字电影包(DCP)码率上限为250Mbps,常见的流媒体文件码率还要低一些。
我们常用的视频、例如视频会议录制的视频码率其实还是比较低的,我随便找了一个2160*1080视频总码率才287kbps。
# 将视频的码率设置为2kbps
ffmpeg -i input.mp4 -b:v 2000k output.mp4
# 设置bufsize,可以让码率波动率小一点
ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k output.mp4
# 可以通过minrate、maxrate设置码率阈值,可变码率(VBR Variable Bit Rate)
ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k -maxrate 2500k output.mp4
2.6 分辨率
# 可以通过-s参数设置分辨率
ffmpeg -i input.mp4 -s 320x240 output.mp4
# 等价于-video_size
ffmpeg -i input.mp4 -video_size 320x240 output.mp4
# 可以使用预定义值
ffmpeg -i input.mp4 -s vga output.mp4
# 上一条命令就等价于下面命令
ffmpeg -i input.mp4 -s 640x480 output.mp4
关于分辨率的预定义值可以参考后面的分辨率预定义表。
3. FFMPEG详解
3.1 基本组件
组件 | 说明 |
---|---|
libavutil | 公共工具函数 |
libavcodec | 编码解码,针对视频音频,执行encode与decode操作 |
libavformat | 封装转换,针对容器,mux和demux操作 |
libavdevice | 设备数据读取和写入 |
libavfilter | 过滤器,处理音视频倍速、水平翻转、裁剪、加方框…… |
libswscale | 视频场景比例缩放、色彩映射转换 |
libswresample | 音频重采样、样本格式转换 |
libpostproc | 后期效果 |
FFMPEG处理数据流程:
ffmpeg-处理流程FFmpeg可以识别5种流类型:
-
视频video(v)
-
音频audio(a)
-
附件attachment(t)
-
数据data(d)
-
字幕subtitle(s)
所以在命令中看到v基本就是指操作视频,看到a基本就是指操作音频。例如map操作:
-
-map 0 选择所有的流类型和其中所有的流
-
-map i:v 选择文件i中的所有视频流
-
-map i:a 选择所有的音频流
-
-map i:s 选择所有的字幕流
3.2 帮助查看命令
# 查看基本帮助信息
ffmpeg -h
# 查看高级参数
ffmpeg -h long
# 查看所有参数
ffmpeg -h full
# 帮助文档比较多,可用重定向到文件查看
ffmpeg -h full >> help.txt
ffmpeg -h demuxer=hls
ffmpeg -h muxer=hls
# 查看flv的解码器
ffmpeg -h decoder=flv
# 查看libx264编码器
ffmpeg -h encoder=libx264
# 查看可用的码流过滤器
ffmpeg -bsfs
# 查看所有可用的codec
ffmpeg -codecs
# 查看所有可用的解码器
ffmpeg -decoders
# 查看所有可用的编码器
ffmpeg -encoders
# 查看所有可用的过滤器
ffmpeg -filters
# 查看所有的封装格式(容器)
ffmpeg -formats
# 查看所有声道布局
ffmpeg -layouts
# 查看所有像素格式
ffmpeg -pix_fmts
# 查看所有支持的协议
ffmpeg -protocols
# 查看版本
ffmpeg -version
3.3 全局参数
参数 | 说明 |
---|---|
-loglevel loglevel | 设置日志输出基本,等价-v loglevel |
-report | 生成报告 |
-max_alloc bytes | 内存分配最大块 |
-y | 默认覆盖已经存在的同名文件 |
-n | 不覆盖已经存在的文件 |
-ignore_unknown | 忽略位置流类型 |
-filter_threads | 非复杂过滤器线程数 |
-filter_complex_threads | 复杂过滤器线程数 |
-stats | 编码的时候打印处理过程报告 |
-vol volume | 修改音量 |
-preset | 主要调节编码速度和质量的平衡 |
preset可选值:
- ultrafast
- superfast
- veryfast
- faster
- fast
- medium
- slow
- slower
- veryslow
- placebo
从上到下,编码速度变小,质量增高
3.4 文件主要参数
参数 | 说明 |
---|---|
-f fmt | 强制格式转换 |
-c codec | 指定编解码器 |
-codec codec | 指定编解码器 |
-t duration | 时间期间,单位秒 |
-to time_stop | 结束时间 |
-fs limit_size | 文件大小,单位bytes |
-ss time_off | 开始时间位置,相对文件开头 |
-sseof time_off | 开始时间位置,相对文件结束 |
-seek_timestamp | -ss使用时间戳格式 |
-timestamp time | 记录开始时间戳,now表示当前期间 |
-metadata string=string | 添加元数据 |
-target type | 目标文件类型 |
-apad | 声音填充 |
-frames number | 设置帧 |
-filter filter_graph | 设置流 |
-filter_script filename | 设置流 |
3.5 视频参数
参数 | 说明 |
---|---|
-vframes number | 设置视频帧数 |
-r rate | 设置帧率 |
-s size | 设置分辨率 |
-aspect aspect | 设置分辨率比例,4:3、16:9、1.3333、1.7777 |
-vn | 禁用(移除)视频,video no |
-vcodec codec | 使用指定codec |
-vf filter_graph | 设置视频过滤器 |
-ab bitrate | 设置音频比特率,-b:a |
-b bitrate | 设置视频比特率,-b:v |
-dn | 禁用数据,data no |
3.6 音频参数
参数 | 说明 |
---|---|
-aframes number | 声音输出的帧大小 |
-aq quality | 设置声音质量 |
-ar rate | 设置声音采样率 |
-ac channels | 设置声道数 |
-an | 禁用(移除)声音,audio no |
-acodec codec | 使用指定codec |
-vol volume | 设置声音 |
-af filter_graph | 设置声音过滤器 |
3.7 字幕参数
参数 | 说明 |
---|---|
-s size | 设置帧大小 |
-sn | 禁用字幕 |
-scodec codec | 强制使用指定的codec |
-canvas_size size | 设置画布大小 |
4. FFMPEG过滤器
下面,我们看一些常见的过滤器,及其示例
- split:通常是用来建立拷贝,往往源流需要执行多个系列操作的时候使用
- pad:填充,默认使用黑色
- crop:裁剪
- scale;放缩
- hflip、vflip:翻转
- overlay:覆盖
- rotate、transpose:旋转
- fade:淡入淡出
4.1 filter_complex
- 过滤器(filter):可以简单一个操作
- 过滤器链(filter chain):一个过滤器链链包含多个过滤器
- 过滤器图(filter graph):一个过滤器图包含多个过滤器链,图是有向无环图的图
filter_complex参数就是一个过滤器图,包含多个过滤器链,不同链使用分号(;)分割,每个过滤器链中包含多个过滤器使用逗号(,)分割。
vf命令也可以是过滤器图。示例:
ffmpeg -i input.mp4 -vf split[pd][hp];[pd]pad=2*iw[o1];[hp]hflip[o2];[o1][o2]overlay=w
如上所示,vf参数包含3个逗号,总共有4个过滤器链,每个过滤器链中只有一个过滤器
- 第1个: split过滤器创建两个输入文件的拷贝并标记为[pd],[hp]
- 第2个: [pd]作为pad过滤器的输入,pad过滤器2倍宽度标记为[o1]
- 第3个: [hp]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[o2]
- 第4个: 用overlay过滤器把[o2]覆盖到[o1]的旁边
# 横向拼接,参数过滤器图包含2个过滤器链
# [0:v]pad=iw*2:ih[a],[0:v]表示选择第一个输入a.mp4的视频,pad过滤器宽度加倍,高度不变标记为a
# [a][1:v]overlay=w,[a]是第一个过滤器链的结果,[1:v]表示选择第2个输入b.mp4的视频,overlay过滤器,x坐标为b.mp4的宽度
ffmpeg -i a.mp4 -i b.mp4 -filter_complex "[0:v]pad=iw*2:ih[a];[a][1:v]overlay=w" o.mp4
# 同理,纵向拼接
ffmpeg -i a.mp4 -i b.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" o.mp4
ffmpeg -i a.mp4 -i b.mp4 -i c.mp4 -filter_complex "[0:v]pad=iw*3:ih*[a];[a][1:v]overlay=w[b];[b][2:v]overlay=2.0*w" o.mp4
ffmpeg -i a.mp4 -i b.mp4 -i c.mp4 -filter_complex "[0:v]pad=iw:ih*3[a];[a][1:v]overlay=0:h[b];[b][2:v]overlay=0:2*h" o.mp4
# 这个过滤器图有4个过滤器链
# 1. [0:v]pad=iw*2:ih*2[a],第1个视频a.mp4长宽加倍,标记为a
# 2. [a][1:v]overlay=W-w[b],用第2个视频b.mp4去覆盖a,x坐标是b.mp4的宽度,相当于放在右上角,标记为b
# 3. [b][2:v]overlay=0:H-h[c],用第3个视频c.mp4去覆盖b,x坐标是0,y坐标是c.mp4的高度,相当于放在左下角,标记为c
# 4. [c][3:v]overlay=W-w:H-h,用第4个视频d.mp4去覆盖c,x坐标是d.mp4的宽度,y坐标是d.mp4的高度,相当于放在右下角
ffmpeg -i a.mp4 -i b.mp4 -i c.mp4 -i d.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=W-w[b];[b][2:v]overlay=0:H-h[c];[c][3:v]overlay=W-w:H-h" o.mp4
4.2 旋转与翻转
# 顺时针翻转90度
ffmpeg -i input.mp4 -vf transpose=1 output.mp4
# 水平翻转、左右翻转
ffmpeg -i input.mp4 -vf hflip output.mp4
# 垂直翻转、上下翻转
ffmpeg -i input.mp4 -vf vflip output.mp4
# 顺时针旋转90度并水平翻转
ffmpeg -i input.mp4 -vf transpose=1,hflip output.mp4
# rotate参数单位是弧度,1°=π/180,360°=2π
# 旋转90度
ffmpeg -i input.mp4 -vf rotate=PI/2 output.mp4
transpose:
- 0: 逆时针旋转90°,然后垂直翻转
- 1: 顺时针旋转90°
- 2: 逆时针旋转90°
- 3: 顺时针旋转90°,然后水平翻转
4.3 裁剪
裁剪使用crop
- iw表示输入视频的宽度
- ih表示输入视频的高度
- ow表示输出视频的宽度
- oh表示输出视频的高度
- x表示水平位置,默认数值为(ih - oh) / 2
- y表示竖直位置,默认数值为(ih - oh) / 2
# vf表示视频过滤器(video filter),w表示宽度,h表示高度,x表示起点横坐标,y表示起点纵坐标
ffmpeg -i input.mp4 -vf crop=w=500:h=500:x=120:y=340 output.mp4
# 截取视频左边1/3
# iw/3表示原视频的1/3,ih表示原视频一样高,0:0横纵坐标都是0,表示左上角开始
ffmpeg -i input.mp4 -vf crop=iw/3:ih:0:0 output.mp4
# 截取视频中间1/3
# 和上一个对比,横坐标变了,从宽度1/3开始(iw/3)
ffmpeg -i input.mp4 -vf crop=iw/3:ih:iw/3:0 output.mp4
# 截取视频右边1/3
# 和上2个比,横坐标变了,从宽度2/3开始(iw/3 * 2)
ffmpeg -i input.mp4 -vf crop=iw/3:ih:iw/3*2:0 output.mp4
# x、y横纵坐标默认是0:0
ffmpeg -i input.mp4 -vf crop=iw/2:ih/2 output.mp4
4.4 缩放scale
# 放缩到960x540,不一定等比,可能变形
ffmpeg -i input.mp4 -vf scale=960:540 output.mp4
# 将宽度放缩到960,高度按宽度放缩比例放缩,等比放缩,不变形
ffmpeg -i input.mp4 -vf scale=960:-1 output.mp4
# 将视频放缩到宽200高100
ffmpeg -i input.mp4 -vf scale=w=200:h=100 output.mp4
# 放缩时,指定宽度的最小值
ffmpeg -i input.mp4 -vf scale=w='min(5000,iw*1.5)':h=1280 output.mp4
# 放缩时,指定宽度的最大值,高度按宽度等比放缩
ffmpeg -i input.mp4 -vf scale=w='max(1920,iw*1)':h=-1 output.mp4
# 如果只想设置宽度,同时保持原来的宽高比
4.5 pad
pad填充视频:
pad=width[:height:[:x[:y:[:color]]]]
参数:
- width:填充之后的宽度
- height:填充之后的高度
- x:填充之后视频的左上角为0点,原视频左上角的横坐标
- y:填充之后视频的左上角为0点,原视频左上角的纵坐标
- color:接受十六进制RGB值(0xRRGGBB),默认黑色
变量:
- in_w或iw:输入的宽度,input width
- in_h或ih:输入的高度,input height
- out_w或ow:输出宽度,output width
- out_h或oh:输出高度,output height
# 给视频添加一个50像素粉色边框,因为有左右、上下,所以各+100像素
ffmpeg -i input.mp4 -y -vf pad=iw+100:ih+100:50:50:pink output.mp4
# 4:3(16:12 12:9)到16:9填充
# 4:3等比放缩为12:9,12<16,宽度不够,所以高度不够,宽度被填充为ih*16/9
# 宽度变了,为了居中,所以x坐标需要为填充宽度的1/2
ffmpeg -i input.mp4 -vf pad=ih*16/9:ih:(ow-iw)/2:0 output.mp4
# 16:9到4:3(16:12 12:9)填充
# 相反,高度不够,宽度不变,填充高度到iw*3/4
# 高度变了,为了居中,所以y坐标需要为填充高度的1/2
ffmpeg -i input.mp4 -vf pad=iw:iw*3/4:0:(oh-ih)/2 output.mp4
4.6 overlay
overlay将覆盖视频(前景)叠加在主视频(背景)上。它需要2个输入,第1个是主视频,第2个视频是覆盖视频。参数:
- x,覆盖视频横坐标,默认0
- y,覆盖视频纵坐标,默认0
- rgb,默认0表示输入颜色空间不改变,1表示将输入的颜色空间设置为RGB
属性值:
- main_w或者W,表示主视频宽度
- main_h或者H,表示主视频高度
- overlay_w或者w,表示覆盖视频的宽度
- overlay_h或者h,表示覆盖视频的高度
# 默认0:0,也就是左上角
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
4.7 drawtext
drawtext主要用于添加水印
常用参数:
- text:内容
- fontsize:字体大小
- fontcolor:字体颜色
- fontfile:字体文件
- x:左上角为0点的横坐标
- y:左上角为0点的纵坐标
- enable:可以用于指定显示的时间区间
text中可用属性:
- text='%{pts}',每一帧的pts时间戳信息
- text='%{localtime}'、text='%{gmtime}'时间
- text='%{frame_num}' 、text='%{n}'帧的序号
- text='%{metadata:width}'视频信息
属性:
- line_h、lh,文字的行高
- main_h、h、H,输入视频高度
- main_w、w、W,输入视频宽度
- text_h、th,文本的高度
- text_w、tw,文本的宽度
- sar:输入样本宽高比
- dar:输入显示宽高比,与(w/h)*sar等价
- PAR(Pixel Aspect Ratio):单个像素的宽高比,通常像素宽高比为1:1
- DAR(Display Aspect Ratio):显示宽高比,视频画面的宽与高之比。比如常见的16:9和4:3等
- SAR(Sample Aspect Ratio):采样纵横比,横向像素点数和纵向像素点数的比值,即为我们通常提到的分辨率宽高比
- DAR = PAR x SAR
# 查看帮助
ffmpeg -h filter=drawtext
# 默认x\y=0,颜色是黑色、默认字体Sans、默认大小16
ffmpeg -i input.mp4 -vf drawtext="text=HELLO" -y output.mp4
# 默认的字体文件不支持中文,会乱码,可以指定字体文件
# 可以去C:\Windows\Fonts目录找拷贝到ffmpeg bin目录(直接使用字体目录可能不生效)
# simkai.ttf是楷体
ffmpeg -i input.mp4 -vf drawtext=text=你好啊:fontfile=simkai.ttf:fontsize=40 -y output.mp4
# 指定背景颜色
ffmpeg -i input.mp4 -vf drawtext="text=HELLO:x=100:y=100:fontsize=50:fontcolor=white:box=1:boxcolor=blue" -y output.mp4
# 在视频中间使用粉色显示视频时间戳
ffmpeg -i input.mp4 -vf drawtext="fontsize=100:fontcolor=pink:text='%{pts}':x=(w-tw)/2:y=(h-th)/2" -y output.mp4
# 内容可以通过文件的时候指定,当添加说明性文字(文字较多)的时候非常实用
ffmpeg -i input.mp4 -vf drawtext=fontcolor=white:fontsize=40:fontfile=simkai.ttf:textfile='content.txt':x=0:y=20 -y output.mp4
# 在3-8秒使用黄色显示帧序号
ffmpeg -i input.mp4 -vf drawtext="text=%{n}:x=100:y=100:fontsize=50:fontcolor=yellow:enable='between(t\,3\,8)'" -y output.mp4
4.8 水印
delogo=x:y:w:h[:t[:show]]
- x,以左上角为0点的横坐标
- y,以左上角为0点的纵坐标
- w,logo的宽度
- h,logo的高度
- t,矩形边缘厚度,默认4
- show,默认0
ffmpeg -i input.mp4 -vf delogo=x=0:y=0:w=100:h=100 output.mp4
ffmpeg -i input.mp4 -vf delogo=0:0:220:90:100:1 output.mp4
4.8 音频
# wav转PCM -f指定采用格式 -ar指定采样率
ffmpeg -i input.wav -f f32le -ar 44100 -acodec pcm_f32le output.raw
# PCM转wav -ac指定声道数
ffmpeg -f f32le -ar 44100 -ac 2 -acodec pcm_f32le -i input.raw output.wav
# 0.5倍速
ffmpeg -i input.mp3 -af atempo=0.5 output.mp3
# 2倍速
ffmpeg -i input.mp3 -af atempo=2 output.mp3
4.9 模糊与锐化
boxblur
boxblur均值滤波
boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]
- luma:亮度
- chroma:色度
- alpha:透明度
- r:radius,表示模糊操作时的邻域半径大小,
- p:power 表示模糊运算的运算次数
ffmpeg -i input.mp4 -vf boxblur=1.5:1 output.mp4
# luma_r和alpha_r半径取值范围是0~min(w,h)/2
# chroma_r半径的取值范围是0~min(cw/ch)/2
ffmpeg -i input.mp4 -vf boxblur=1:10:4:10 output.mp4
unsharp
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
ffmpeg -i input.mp4 -vf unsharp output.mp4
ffmpeg -i input.mp4 -vf unsharp=13:13:-2 output.mp4
其他
# 不影响边缘
ffmpeg -i input.mp4 -vf smartblur=5:0.8:0 output.mp4
ffmpeg -i input.mp4 -vf mp=denoise3d output.mp4
ffmpeg -i input.mp4 -vf hqdn3d output.mp4
# nr降噪, 0~100000
ffmpeg -i input.mp4 -nr 500 output.mp4
4.10 淡入淡出(fade)
参数:
- type, t,类型,in淡入,out淡出,默认为in
- start_frame, s,效果的开始时间,默认为0
- nb_frames, n,效果的最后一帧序数。对于淡入,在此帧后将以本身的视频输出,对于淡出此帧后将以设定的颜色输出,默认25
- start_time, st,开始时间,单位秒,默认为0
- duration, d,效果持续时间,单位秒
- alpha,如果设置为1,则只在透明通道实施效果,默认为0
如果start_frame和start_time都被设置,时间大的参数生效
如果duration和nb_frames同时被设置,将使用duration值
# 前面10帧黑色,30帧结束
ffmpeg -i input.mp4 -vf fade=in:10:30 -y output.mp4
# 30帧结束,下面2个等价
ffmpeg -i input.mp4 -vf fade=in:0:30 -y output.mp4
ffmpeg -i input.mp4 -vf fade=t=in:s=0:n=30 -y output.mp4
# 0-30秒区间显示淡入效果
ffmpeg -i input.mp4 -vf fade=t=in:st=0:d=30 -y output.mp4
# 前40帧黑屏,帧率15大概3秒的样子,60帧结束
# 本来想通过drawtext看帧的位置,加了drawtext之后,基本就看不出fade效果了
ffmpeg -i input.mp4 -vf fade=in:45:60 -vf drawtext="fontsize=100:fontcolor=yellow:text='%{n}':x=(w-tw)/2:y=(h-th)/2" -y output.mp4
# 仅在透明通道的第10帧开始淡入
ffmpeg -i input.mp4 -vf fade=in:0:10:alpha=1 -y output.mp4
# 前面2s黑屏,3s淡入
ffmpeg -i input.mp4 -vf fade=t=in:st=2:d=3 -y output.mp4
# 170帧开始淡出,200帧结束,后面黑了
ffmpeg -i input.mp4 -vf fade=out:170:200 -y output.mp4
ffmpeg -i input.mp4 -vf fade=type=out:start_frame=170:nb_frames=200 -y output.mp4
ffmpeg -i input.mp4 -vf fade=type=out:s=200:d=5 -y output.mp4
# 25帧淡入,100帧淡出
ffmpeg -i input.mp4 -vf fade=in:0:25,fade=out:100:125 -y output.mp4
4.11 其他
# -ss 01:23:45 截取开始时间,-vframes 1截取1帧 -q:v 2设置输出质量[1,31],越小质量越高,推荐2-5
ffmpeg -i input.mp4 -ss 01:23:45 -vframes 1 -q:v 2 output.jpg
ffmpeg -i input.jpg -s 100*100 output.jpg
# 把001.jpg、002.jpg、003.jpg等图片合成视频output.mp4
# %03d.jpg表示从1开始用0补全的3位整数为文件名的jpg文件
ffmpeg -i %04d.jpg output.mp4
# input.mp4拆出001.jpg、002.jpg、003.jpg等图片
ffmpeg -i input.mp4 %03d.jpg
# 合并还可以通过制定文件的方式,file.txt中每一行放一个要合并的文件路径
ffmpeg -f concat -i file.txt output.mp3
# 放大为之前的两倍
ffmpeg -i input.jpg -vf scale=iw*2:ih output.png
# 缩小为之前的二分之一
ffmpeg -i input.jpg -vf "scale=iw.5:ih.5" output.png
ffmpeg -i input.jpg -vf "scale=iw/2:ih/2" output.png
# 图像转换成黑白
ffmpeg -i input.png -vf hue=s=0 output.png
# 快速抠图,colorkey 将指定的色值变成透明色,当目标和背景色差比较大的时候非常方便
ffmpeg -i input.png -vf colorkey=0x093bbb:0.2 output.png
# 将视频推送到直播流
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://localhost:8044/live/test
# 容器转换
ffmpeg -i input.mp4 -c copy output.mkv
5. ffplay与ffprobe
# ffplay播放yuv视频数据
# ffplay -f <文件格式> -pix_fmt <像素格式> -video_size <视频尺寸> <文件名>
ffplay -f rawvideo -pix_fmt yuv420p -video_size 848x480 video.mp4
# ffplay播放PCM音频数据
# ffplay -f <格式名> -ac <声道数> -ar <采样率> <文件名>
ffplay -f f32le -ac 1 -ar 48000 audio.mp4
# ffprobe查看媒体文件的信息
ffprobe input.mp4 -show_format -show_streams -print_format json -loglevel fatal
# 查看视频信息
ffprobe input.mp4 -show_streams -select_streams v -print_format json
ffprobe output.mkv -show_streams -print_format json
6. 其他
6.1 帧率预定义值
预定义值 | 帧率 | 说明 |
---|---|---|
ntsc | 30000/1001 | 美国国家电视标准 |
pal | 25/1 | 欧洲电视标准 |
qntsc | 30000/1001 | |
qpal | 25/1 | |
sntsc | 30000/1001 | |
spal | 25/1 | |
film | 24/1 | 电影标准 |
ntsc-film | 24000/1001 |
6.2 分辨率预定义值
预定义值 | 分辨率 |
---|---|
ntsc | 720x480 |
pal | 720x576 |
qntsc | 352x240 |
qpal | 352x288 |
sntsc | 640x480 |
spal | 768x576 |
film | 352x240 |
ntsc-film | 352x240 |
sqcif | 128x96 |
qcif | 176x144 |
cif | 352x288 |
4cif | 704x576 |
16cif | 1408x1152 |
qqvga | 160x120 |
qvga | 320x240 |
vga | 640x480 |
svga | 800x600 |
xga | 1024x768 |
uxga | 1600x1200 |
qxga | 2048x1536 |
sxga | 1280x1024 |
qsxga | 2560x2048 |
hsxga | 5120x4096 |
wvga | 852x480 |
wxga | 1366x768 |
wsxga | 1600x1024 |
wuxga | 1920x1200 |
woxga | 2560x1600 |
wqsxga | 3200x2048 |
wquxga | 3840x2400 |
whsxga | 6400x4096 |
whuxga | 7680x4800 |
cga | 320x200 |
ega | 640x350 |
hd480 | 852x480 |
hd720 | 1280x720 |
hd1080 | 1920x1080 |
2k | 2048x1080 |
2kflat | 1998x1080 |
2kscope | 2048x858 |
4k | 4096x2160 |
4kflat | 3996x2160 |
4kscope | 4096x1716 |
nhd | 640x360 |
hqvga | 240x160 |
wqvga | 400x240 |
fwqvga | 432x240 |
hvga | 480x320 |
qhd | 960x540 |
2kdci | 2048x1080 |
4kdci | 4096x2160 |
uhd2160 | 3840x2160 |
uhd4320 | 7680x4320 |
6.3 常见分辨率
分辨率 | 缩写 | 说明 |
---|---|---|
640 x 480 | 480p | 标清 Standard Definition |
1024 x 720 | 720p | 高清 High Definition |
1920 x 1080 | 1080p | 全高清 Full High Definition |
3840 x 2160 | 4K UHD | 超高清 Ultra High-Definition 4K |
7680 x 4320 | 8K UHD | 超高清 Ultra High-Definition 8K |
4093 x 2160 | 4K DCI | 数字电影倡导联盟(DCI)4K标准 |
8192 x 4320 | 8K DCI | DCI 8K标准 |
网友评论