当前位置:   article > 正文

视频与FFMPEG那些事_h264 sar

h264 sar

1. 基本概念

1.1 容器(Container)

容器也就是封装格式,例如MP4。容器中主要包含以下内容:

  1. 视频流(Video Stream):视频数据

  2. 音频流(Audio Stream):音频数据

  3. 元数据(Meta Data):码率、帧率、分辨率等等

有些容器还可以外挂字幕文件,例如MKV。

把视频、音频、元数据、字幕这些数据打包成一个容器数据,有个好听的词叫:封装。

容器用来装东西,不介意装什么,相同的编码也可以使用不同的容器。就好比,牛奶用碗装还是用奶瓶装,并不影响牛奶本身。
ffmpeg容器转换

把MP4视频使用H264编码,音频使用ACC编码,转换为MKV之后,视频还是使用H264编码,音频还是使用ACC编码。

常见容器

容器公司或组织说明
AVI微软有损压缩,基本被淘汰技术
MOV苹果老使用少
RMReal Networks体积小,画质不错
RMVBReal NetworksRM进化版,VB,Variable Bit Rate比特率可变
ASF微软WMA、WMV
MKV开源能容纳多种不同类型编码的视频、音频及字幕流
MPG/MPEGMPEG受支持比较广泛
FLVAdobe视频网站常用
HLS苹果自适应码率的格式,视频网站、直播常用,如果看到.m3u8后缀的请求,多半使用的是这种格式
MPEG-DASHMPEG开源自适应码率的格式,国际标准

1.2 编码解码器(codec)

主要Codec不是特指编码,而是编码和解码的复合体,由Coder和Decoder组成。

常见视频编码格式

编码说明
MPEG-1VCD使用这种编码,常见后缀.mpg、.mlv、.mpe、.mpeg、.dat
MPEG-2DVD使用这种编码,常见后缀.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
VP9VP9 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非常强大,但是我们使用它做得最多的操作是:

  1. 格式转换
  2. 获取视频声音
  3. 添加字幕

简单的操作:截图、合并截取视频片段、生成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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

字幕分软挂载和硬挂载:

  1. 软挂载是把字幕文件添加在容器中,基本只有一个拷贝操作,所以速度非常快
  2. 硬挂载是把字幕渲染到视频中,要把字幕文件的内容读取出来,然后一帧一帧添加到视频中,所以比较慢

软挂载虽然快,但是它需要容器支持,例如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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

关于帧率的预定义值可以参考后面的帧率预定义表。

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个喇叭。

常见音频码率:

  1. MP3: 128kbps
  2. LC-AAC: 112kbps
  3. HE-AAC(SBR): 96kbps
  4. HE-AAC(v2): 48kbps

视频码率计算

我们已经知道,视频就是连续的图片,所以计算视频码率,我们先计算图片大小。

视频和图片都有一个分辨率,例如4k的分辨率4096*2160,这个表示width上有4096个像素,height上有2304个像素,总共8847360像素。

一张4096*2160分辨率的图片,图片数据有多大呢?还涉及另一个参数:像素深度,也就是有多少位表示1个像素。

  1. 1位:用1bit表示颜色,单色显示,最常见的就是红色黑底的LED屏
  2. 8位:用8bit表示颜色,可以显示2^8=256种颜色,黑白屏
  3. 16位:用16bit表示颜色,可以显示2^16=65536种颜色。RGB565(5位表示R红色、6位表示G绿色、5位表示B蓝色)
  4. 24位:用24bit表示颜色,可以显示2^24=16777216种颜色。RGB888(8位R红色、8位G绿色、8位B蓝色)
  5. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

关于分辨率的预定义值可以参考后面的分辨率预定义表。

3. FFMPEG详解

3.1 基本组件

组件说明
libavutil公共工具函数
libavcodec编码解码,针对视频音频,执行encode与decode操作
libavformat封装转换,针对容器,mux和demux操作
libavdevice设备数据读取和写入
libavfilter过滤器,处理音视频倍速、水平翻转、裁剪、加方框……
libswscale视频场景比例缩放、色彩映射转换
libswresample音频重采样、样本格式转换
libpostproc后期效果

FFMPEG处理数据流程:

ffmpeg数据处理流程

FFmpeg可以识别5种流类型:

  1. 视频video(v)

  2. 音频audio(a)

  3. 附件attachment(t)

  4. 数据data(d)

  5. 字幕subtitle(s)

所以在命令中看到v基本就是指操作视频,看到a基本就是指操作音频。例如map操作:

  1. -map 0 选择所有的流类型和其中所有的流

  2. -map i:v 选择文件i中的所有视频流

  3. -map i:a 选择所有的音频流

  4. -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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

3.3 全局参数

参数说明
-loglevel loglevel设置日志输出基本,等价-v loglevel
-report生成报告
-max_alloc bytes内存分配最大块
-y默认覆盖已经存在的同名文件
-n不覆盖已经存在的文件
-ignore_unknown忽略位置流类型
-filter_threads非复杂过滤器线程数
-filter_complex_threads复杂过滤器线程数
-stats编码的时候打印处理过程报告
-vol volume修改音量
-preset主要调节编码速度和质量的平衡

preset可选值:

  1. ultrafast
  2. superfast
  3. veryfast
  4. faster
  5. fast
  6. medium
  7. slow
  8. slower
  9. veryslow
  10. 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过滤器

下面,我们看一些常见的过滤器,及其示例

  1. split:通常是用来建立拷贝,往往源流需要执行多个系列操作的时候使用
  2. pad:填充,默认使用黑色
  3. crop:裁剪
  4. scale;放缩
  5. hflip、vflip:翻转
  6. overlay:覆盖
  7. rotate、transpose:旋转
  8. fade:淡入淡出

4.1 filter_complex

  1. 过滤器(filter):可以简单一个操作
  2. 过滤器链(filter chain):一个过滤器链链包含多个过滤器
  3. 过滤器图(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. 第1个: split过滤器创建两个输入文件的拷贝并标记为[pd],[hp]
  2. 第2个: [pd]作为pad过滤器的输入,pad过滤器2倍宽度标记为[o1]
  3. 第3个: [hp]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[o2]
  4. 第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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

过滤器

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

transpose:

  • 0: 逆时针旋转90°,然后垂直翻转
  • 1: 顺时针旋转90°
  • 2: 逆时针旋转90°
  • 3: 顺时针旋转90°,然后水平翻转

4.3 裁剪

裁剪使用crop

  1. iw表示输入视频的宽度
  2. ih表示输入视频的高度
  3. ow表示输出视频的宽度
  4. oh表示输出视频的高度
  5. x表示水平位置,默认数值为(ih - oh) / 2
  6. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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
# 如果只想设置宽度,同时保持原来的宽高比
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4.5 pad

pad填充视频:

pad=width[:height:[:x[:y:[:color]]]]

参数:

  1. width:填充之后的宽度
  2. height:填充之后的高度
  3. x:填充之后视频的左上角为0点,原视频左上角的横坐标
  4. y:填充之后视频的左上角为0点,原视频左上角的纵坐标
  5. color:接受十六进制RGB值(0xRRGGBB),默认黑色

变量:

  1. in_w或iw:输入的宽度,input width
  2. in_h或ih:输入的高度,input height
  3. out_w或ow:输出宽度,output width
  4. out_h或oh:输出高度,output height

ffmpeg填充示意图

# 给视频添加一个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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.6 overlay

overlay将覆盖视频(前景)叠加在主视频(背景)上。它需要2个输入,第1个是主视频,第2个视频是覆盖视频。参数:

  1. x,覆盖视频横坐标,默认0
  2. y,覆盖视频纵坐标,默认0
  3. rgb,默认0表示输入颜色空间不改变,1表示将输入的颜色空间设置为RGB

属性值:

  1. main_w或者W,表示主视频宽度
  2. main_h或者H,表示主视频高度
  3. overlay_w或者w,表示覆盖视频的宽度
  4. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4.7 drawtext

drawtext主要用于添加水印

常用参数:

  1. text:内容
  2. fontsize:字体大小
  3. fontcolor:字体颜色
  4. fontfile:字体文件
  5. x:左上角为0点的横坐标
  6. y:左上角为0点的纵坐标
  7. enable:可以用于指定显示的时间区间

text中可用属性:

  1. text=‘%{pts}’,每一帧的pts时间戳信息
  2. text=‘%{localtime}’、text='%{gmtime}'时间
  3. text=‘%{frame_num}’ 、text='%{n}'帧的序号
  4. text='%{metadata:width}'视频信息

属性:

  1. line_h、lh,文字的行高
  2. main_h、h、H,输入视频高度
  3. main_w、w、W,输入视频宽度
  4. text_h、th,文本的高度
  5. text_w、tw,文本的宽度
  6. sar:输入样本宽高比
  7. 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

drawtext

4.8 水印

delogo=x:y:w:h[:t[:show]]

  1. x,以左上角为0点的横坐标
  2. y,以左上角为0点的纵坐标
  3. w,logo的宽度
  4. h,logo的高度
  5. t,矩形边缘厚度,默认4
  6. 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
  • 1
  • 2
  • 3

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.9 模糊与锐化

boxblur

boxblur均值滤波

boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]

  1. luma:亮度
  2. chroma:色度
  3. alpha:透明度
  4. r:radius,表示模糊操作时的邻域半径大小,
  5. 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
  • 1
  • 2
  • 3
  • 4
  • 5

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

  1. l_msize_x:水平亮度矩阵,取值范围3-13,默认值为5
  2. l_msize_y:垂直亮度矩阵,取值范围3-13,默认值为5
  3. l_amount:亮度强度,取值范围-2.0-5.0,负数为模糊效果,默认值1.0
  4. c_msize_x:水平色彩矩阵,取值范围3-13,默认值5
  5. c_msize_y:垂直色彩矩阵,取值范围3-13,默认值5
  6. 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
  • 1
  • 2

其他

# 不影响边缘
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

6. 其他

6.1 帧率预定义值

预定义值帧率说明
ntsc30000/1001美国国家电视标准
pal25/1欧洲电视标准
qntsc30000/1001
qpal25/1
sntsc30000/1001
spal25/1
film24/1电影标准
ntsc-film24000/1001

6.2 分辨率预定义值

预定义值分辨率
ntsc720x480
pal720x576
qntsc352x240
qpal352x288
sntsc640x480
spal768x576
film352x240
ntsc-film352x240
sqcif128x96
qcif176x144
cif352x288
4cif704x576
16cif1408x1152
qqvga160x120
qvga320x240
vga640x480
svga800x600
xga1024x768
uxga1600x1200
qxga2048x1536
sxga1280x1024
qsxga2560x2048
hsxga5120x4096
wvga852x480
wxga1366x768
wsxga1600x1024
wuxga1920x1200
woxga2560x1600
wqsxga3200x2048
wquxga3840x2400
whsxga6400x4096
whuxga7680x4800
cga320x200
ega640x350
hd480852x480
hd7201280x720
hd10801920x1080
2k2048x1080
2kflat1998x1080
2kscope2048x858
4k4096x2160
4kflat3996x2160
4kscope4096x1716
nhd640x360
hqvga240x160
wqvga400x240
fwqvga432x240
hvga480x320
qhd960x540
2kdci2048x1080
4kdci4096x2160
uhd21603840x2160
uhd43207680x4320

6.3 常见分辨率

分辨率缩写说明
640 x 480480p标清 Standard Definition
1024 x 720720p高清 High Definition
1920 x 10801080p全高清 Full High Definition
3840 x 21604K UHD超高清 Ultra High-Definition 4K
7680 x 43208K UHD超高清 Ultra High-Definition 8K
4093 x 21604K DCI数字电影倡导联盟(DCI)4K标准
8192 x 43208K DCIDCI 8K标准

ffmpeg下载

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/174772
推荐阅读
  

闽ICP备14008679号