美文网首页
视频与FFMPEG那些事

视频与FFMPEG那些事

作者: 一数一道 | 来源:发表于2022-06-16 16:54 被阅读0次

    1. 基本概念

    1.1 容器(Container)

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

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

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

    3. 元数据(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非常强大,但是我们使用它做得最多的操作是:

    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
    

    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
    

    字幕分软挂载和硬挂载:

    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
    

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

    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
    

    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种流类型:

    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
    

    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
    

    过滤器

    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

    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
    

    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]]]]

    参数:

    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-pad示意图
    # 给视频添加一个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个视频是覆盖视频。参数:

    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
    

    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
    

    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
    

    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]]

    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
    

    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
    

    其他

    # 不影响边缘
    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标准

    ffmpeg下载

    相关文章

      网友评论

          本文标题:视频与FFMPEG那些事

          本文链接:https://www.haomeiwen.com/subject/fhyqvrtx.html