前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FFmpeg 学习

FFmpeg 学习

作者头像
不会跳舞的鸟
发布2022-11-16 10:03:44
7870
发布2022-11-16 10:03:44
举报
文章被收录于专栏:不会跳舞的鸟

数据类型

AVRational

ffmpeg 为了保证数据的精度与完整性,有一个 AVRational 数据类型,就是一个有理数(分数)

代码语言:javascript
复制
typedef struct AVRational{
    int num; // Numerator
    int den; // Denominator
} AVRational;

常见 num / den 的形式

输入输出

简单

代码语言:javascript
复制
ffmpeg -i in.mp4 out.flv
  • -i 是代表输入
  • 此命令默认会按照其默认编码器参数重新编码,而不是仅仅转封装

按照轨道(流)

代码语言:javascript
复制
ffmpeg -i 1.mp4 -i 2.mp4 -map 0:v:0 -map 1:a:0 -c copy out.mp4
  • -map 0:v:0 代表选取第 0 个输入文件的视频(v 是video,a 则是 audio)的第 0 个轨道
  • ffmpeg 默认的选择:
    • 视频:选择分辨率(品质)最高的
    • 音频:选择 Channel 最多的
    • 字幕:第一个找到的

改变视频分辨率

指定分辨率

代码语言:javascript
复制
ffmpeg -i data/origin/2.mp4 -vf scale=1920:1080 -c:v libx264 -b:v 10m data/temp1080/2.mp4 -hide_banner
  • -i dirs 输入文件路径
  • -vf scale=1920\*1080 缩放到 1920*1080, scale 是一种 video filter -vf 为 video filtergraph, -vf-filter:v 的简称 -vf scale 等同于 -s
  • -hide_banner 选项用于在输出文件的详细信息时省略 ffmpeg 的版本信息和编译选项等
  • -c:v libx264 指定编码器 libx264
  • -b:v 10m 指定码率 10m

宽高比缩放

(不建议使用)

代码语言:javascript
复制
ffmpeg -i data/origin/2.mp4 -vf scale=1920:-1 data/temp1080/2.mp4 -hide_banner

作用是:宽度设为 1920,高度自适应

  • 不同之处在于宽度写了 -1,代表根据宽度及宽高比自适应,猜测自适应那一方写负数就可以做到自适应 但是此方法遇到明确的那一方无法除尽的时候会报错

裁剪视频

使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存

代码语言:javascript
复制
ffmpeg -ss 00:00:00 -i video.mp4 -vcodec copy -acodec copy -t 00:00:31 output1.mp4
  • -t 是 Duration,换成-to的话是切到指定时刻
  • -ss 如果在 -i 前,是直接 seek 到指定时刻(前的关键帧上),再进行切割;如果 -ss-i 后,则是从头开始 decode,直到遇到指定时刻开始切割,会比较慢,后者比较精准。 注意:因为 ffmpeg 的 bug,如果视频第一帧不是从 0 开始,则起始截取位置可能会乱掉,如果想从头开始,则删掉 -ss 参数即可

指定时长切片

代码语言:javascript
复制
ffmpeg -y -nostdin -hide_banner -v error -analyzeduration 400000000 -i ./ori.mp4 -max_interleave_delta 0 -flags +global_header -max_muxing_queue_size 3000 -c copy -f segment -segment_time 600 -reset_timestamps 1 -segment_list ./origin.ffconcat -metadata description="Bilibili VXCode Swarm Transcoder v0.1.29" ./S%03d.mp4
  • -segment_time 600 每段时长 600s
  • ./S%03d.mp4 分段格式化文件名,此处为 S000.mp4 S001.mp4

取帧

拆所有帧

指定总帧数
代码语言:javascript
复制
ffmpeg -i data/temp1080/2.mp4 -f image2 -vframes 1441 -filter_complex 'scale=1920:1080' data/input/2.mp4/2_%07d.bmp
  • -vframes 1441 总视频帧数为 1441
  • -filter_complex 'scale=1920:1080' 指定输出的图片尺寸(scale 是一种滤镜),如果不指定此参数则按照原始分辨率
指定帧率
代码语言:javascript
复制
ffmpeg -i data/temp1080/2.mp4 -r 5 data/input/2.mp4/2_%07d.bmp

属于截图,和原视频帧率无关,或者说一秒截几张图

  • -i dirs 输入文件路径
  • -r 5 一秒截 5 张图

取指定时刻开始 n 帧

代码语言:javascript
复制
ffmpeg -i LOL2_LR.mp4 -ss 1.0 -vframes 1 -vf scale=1920:1080 cover.jpg
  • -ss 1.0 从第 1 秒开始
  • -vframes 1 取 1 帧

图片集合成视频

代码语言:javascript
复制
ffmpeg -threads 6 -pattern_type glob -f image2 -r 30 -i 'LOL2/*.bmp' -c:v libx264 -b:v 30m -pix_fmt yuv420p out.mp4
  • -threads 6 线程数 6
  • -c:v libx264 -c:v libx264 等同于 -vcodec libx264 等同于 -codec:v libx264 reference: http://ffmpeg.org/pipermail/ffmpeg-user/2017-February/035335.html
  • -r 30 帧率 30,需要放在 -i 之前
  • -b:v 30m 30m 视频码率(比特率)
  • -crf 5 网上这样说:取值范围为0~51,其中0为无损模式,数值越大,画质越差,生成的文件却越小。从主观上讲,18~28是一个合理的范围。18被认为是视觉无损的(从技术角度上看当然还是有损的),它的输出视频质量和输入视频相当。 (本条命令没用到,用 -b:v 代替了)
  • -pix_fmt yuv420p

音视频分离与合成

抽取音频

代码语言:javascript
复制
ffmpeg -i full.mp4 -vn -y -acodec copy audio.aac

抽取视频

代码语言:javascript
复制
ffmpeg -i full.mp4 -vcodec copy –an video.mp4

音视频合成

代码语言:javascript
复制
ffmpeg -i only_video.mp4 -i only_audio.aac -vcodec copy -acodec copy full.mp4

视频拼接

参考: wikiConcatenate

参数形式

代码语言:javascript
复制
ffmpeg -i "concat:input1.mp4|input2.mp4" -c copy out.mp4

外部 txt 形式

代码语言:javascript
复制
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

txt 的文件的格式:

代码语言:javascript
复制
# this is a comment
file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'

循环播放

代码语言:javascript
复制
ffmpeg -stream_loop 10 -i clip1.mp4 -c copy out.mp4
  • -stream_loop 10 代表循环 10 次,如果写 0 是不循环,如果写 -1 则是无限循环(多用在直播推流)

画中画

这里画中画的实现方式是 overlay

代码语言:javascript
复制
ffmpeg -i src1.mp4 -i src2.mp4 -lavfi "[0:v]crop=x=960:y=540:w=960:h=540[a];[a]scale=1920:1080[b];[1:v][b]overlay=x=960:y=540[c]" -map [c] -c:v libx264 dst.mp4 -y
  • -filter_complex-lavfi
    1. ; 分隔每一次操作
    2. [0:v]crop=x=960:y=540:w=960:h=540[a][0:v] 代表选中 -i 输入中第 1(下标 0)个视频流,经过裁剪(crop)出从横坐标 x=960 纵坐标 y=540 开始,宽度 w=960 高度 h=540 的画幅,结果视频流命名为 [a]
    3. [a] 流的尺度设置(此处实际情况是拉伸)为 1920:1080 的分辨率(源流是第一步裁剪出的 960:540),结果视频流命名为 [b]
    4. [1:v][b]overlay[c][0:v] 第 2(下标 1)个视频流当作背景画面,将 [b] 视频流覆盖到其上面,定位到 (960, 540) 的位置(不指定默认在左上角),结果视频流命名为 [c]
  • -map [c] 输出 c 视频流
  • -y 不提示直接覆盖已存在文件

直播推流

代码语言:javascript
复制
ffmpeg -i in.mp4 "rtmp://xxx"
  • 仅需要将输出文件写成推流地址即可

视频质量控制

码率控制

指定码率

-b:v 2M 是在编码的时候控制视频固定码率为2M,音频则为-b:a 128K

恒定质量

-crf 18 -qp 18

  • -crf 恒定速率(constant rate factor)因子模式,是恒定质量的编码方式,与恒定码率(CBR)是相反的,crf 的范围在 0 - 51,0 是绝对无损,18 被认为是视觉无损
  • -qp 恒定量化(constant quantizer)器模式,定义了从一个像素宏块中丢掉多少信息

CRF会用将每一帧的压缩不同的大小,为了让主观的质量感受差不多,会用不同的QP。他是通过把运动也考虑进来做到这一点的。在编码中,如果Qp=18,则每一帧都是QP=18,当然根据帧的类型不同会有一些微小的波动,忽略之。设置CRF=18的时候,对于运动比较大的场景,会把QP设得更高一些,对于运动比较比较不剧烈的帧,会降低QP。这会导致比特率的分配随时间变化不同5

2Pass(Multi-Pass)

通过转码两次,在恒定码率的模式下,可以使编码更高效

代码语言:javascript
复制
ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 2M -pass 1 -an -f null /dev/null && \
ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 2M -pass 2 -c:a libopus output.mkv
  • -pass 1 第一次转码,输出到空文件描述符 /dev/null
  • -an 第一次转码可以排除音频

视频质量评估

在超分辨率(或其他图像重建)工作中通常把 PSNRSSIM 两个指标结合看,因为常常图像非常模糊但是 PSNR 得分很高,这时候 SSIM 可能不高,因为 SSIM 比 PSNR 更符合人眼主观感受

PSNR

峰值信噪比

代码语言:javascript
复制
ffmpeg -i src.mp4 -i dst.mp4 -lavfi psnr -f null -

此命令会打印出每一对对比帧的Y、U、V分量的 MSE 和 PSNR 及各自平均值

  • -lavfi 选项等同于 -filter_complex 所以以上命令等同于 -filter_complex psnr="stats_file=psnr.log"
  • -lavfi psnr 可以写为 -lavfi psnr="stats_file=psnr.log" 将输出打印到 stats_file 所指定的文件如 psnr.log
  • src 及 dst 文件可各添加一个 -s WeightxHeight 来指定分辨率
  • -ffmt (input / output) 强制输入输出文件格式
SSIM

结构相似性

代码语言:javascript
复制
ffmpeg -i src.mp4 -i dst.mp4 -lavfi ssim="stats_file=ssim.log" -f null -
VMAF

VMAF 是 Netflix 开发的感知视频质量评估算法4,ffmpeg 的 libvmaf 中已经集成

分析文件信息 (Probe)

帧率

代码语言:javascript
复制
ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate src.mp4

时长

代码语言:javascript
复制
ffprobe -show_entries format=duration -of default=nk=1:nw=1 test.mp4
  • -of default=nk=1:nw=1
    • -of-print_format 的简写
    • 设置输出格式为 defaultdefault=nk=1:只输出值和换行;default=nw=1:去掉[]和[/]两行字符3

总帧数

代码语言:javascript
复制
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 src.mp4

计算 GOP 大小

代码语言:javascript
复制
ffprobe -show_frames input.mp4 | grep pict_type

然后计算两个 I 帧 (pict_type=I) 之间的距离

查看编码器名称

代码语言:javascript
复制
ffprobe -select_streams v:0 -show_entries stream=codec_name -of default=nk=1:nw=1 input.mp4
  • -select_streams v:0 代表选择此文件中的第一条视频流,v:1 则是第二条视频流,a:0 则是第一条音频流
  • -of default=nk=1:nw=1 同 ### 时长 小结中的介绍

色彩空间

-pix_fmts

Log 控制

-loglevel 参数控制 log 输出级别,包含以下值:

  • quiet
  • panic
  • fatal
  • error
  • warning
  • info
  • verbose
  • debug
  • trace

References

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据类型
    • AVRational
    • 输入输出
      • 简单
        • 按照轨道(流)
        • 改变视频分辨率
          • 指定分辨率
            • 宽高比缩放
            • 裁剪视频
              • 指定时长切片
              • 取帧
                • 拆所有帧
                  • 指定总帧数
                  • 指定帧率
                • 取指定时刻开始 n 帧
                • 图片集合成视频
                • 音视频分离与合成
                  • 抽取音频
                    • 抽取视频
                      • 音视频合成
                      • 视频拼接
                        • 参数形式
                          • 外部 txt 形式
                          • 循环播放
                          • 画中画
                          • 直播推流
                          • 视频质量控制
                            • 码率控制
                              • 指定码率
                              • 恒定质量
                              • 2Pass(Multi-Pass)
                              • PSNR
                              • SSIM
                              • VMAF
                          • 视频质量评估
                          • 分析文件信息 (Probe)
                            • 帧率
                              • 时长
                                • 总帧数
                                  • 计算 GOP 大小
                                    • 查看编码器名称
                                    • 色彩空间
                                    • Log 控制
                                    • References
                                    相关产品与服务
                                    云直播
                                    云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档