翻译:
一、GOALS
你应该学习:
- 基本概念
- 安装ffmpeg和工具
- 编码视频
- 应用过滤器
- 分析视频
二、要求
这些幻灯片
ffmpeg,ffprobe和ffplay的安装
一些示例视频,例如:Big Buck Bunny(http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_normal.mp4)
三、资源
如果您需要样本视频进行测试,请参阅VQEG的概述
(视频质量专家组):https://www.its.bldrdoc.gov/vqeg/video-datasets-and-organizations.aspx
四、介绍FFMPEG
1、关于该项目
免费的开源软件,用于多媒体编辑,转换,...
2000年开始
持续发展至今
类似或相关的(和有用的)框架:
- ImageMagick的
- MLT框架
2、TOOLS
FFmpeg包含:
命令行工具:ffmpeg,ffprobe,ffserver,ffplay
库:libavformat,libavcodec,libavfilter,...
许多项目都使用图书馆(VLC,MLT框架,...)
3、关于图书馆(LIBAV *)
libavformat:读写容器格式(AVI,MKV,MP4,...)
libavcodec:读写编解码器(H.264,H.265,VP9,...)
libavfilter:视频和音频的各种过滤器
... 还有很多
有关如何以编程方式使用库的示例:http://leixiaohua1020.github.io/#ffmpeg-development-examples
4、建筑
简化的整体架构:
5、安装/编译
文档:https://ffmpeg.org/ffmpeg-all.html
维基:http://trac.ffmpeg.org/wiki
IRC:#ffmpeg
邮件列表:https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-user/
堆栈溢出:https://stackoverflow.com/和使用#ffmpeg
超级用户:http://superuser.com/并使用#ffmpeg
...或问我
通用视频编码概念
6、通用视频编码概念
(1)集装箱格式
容器包含媒体数据。 典型例子:
- MP4:用于H.264,H.264,AAC音频的MPEG-4第14部分容器...
- MKV:任何媒体格式的多功能容器
- AVI:遗留容器
查看支持的容器:
$ ffmpeg -formats
File formats:
D. = Demuxing supported
.E = Muxing supported
--
D 3dostr 3DO STR
E 3g2 3GP2 (3GPP2 file format)
E 3gp 3GP (3GPP file format)
D 4xm 4X Technologies
E a64 a64 - video for Commodore 64
D aa Audible AA format files
(2)编解码器
- CODEC =编码器/解码器
- 有关如何对视频,音频进行编码和解码的规范
- 通常不是关于如何编码/压缩数据的规范
查看支持的编解码器:
$ ffmpeg -codecs
Codecs:
D..... = Decoding supported
.E.... = Encoding supported
..V... = Video codec
..A... = Audio codec
..S... = Subtitle codec
...I.. = Intra frame-only codec
....L. = Lossy compression
.....S = Lossless compression
-------
D.VI.. 012v Uncompressed 4:2:2 10-bit
D.V.L. 4xm 4X Movie
D.VI.S 8bps QuickTime 8BPS video
.EVIL. a64_multi Multicolor charset for Commodore 64 (encoders: a64multi )
.EVIL. a64_multi5 Multicolor charset for Commodore 64, extended with 5th color (colram) (encoders: a64multi5 )
D.V..S aasc Autodesk RLE
D.VIL. aic Apple Intermediate Codec
...
(3)最重要的(丢失)编解码器
目前主要使用,由ITU / ISO标准化:
- H.262 / MPEG-2 H部分:广播,电视,用于向后兼容
- H.264 / MPEG-4第10部分:当今视频编码事实上的标准
- H.265 / MPEG-H:H.264的继任者,质量提高高达50%
- MP3 / MPEG-2音频层III:曾经是事实上的音频编码标准
- AAC / ISO / IEC 14496-3:2009:高级音频编码标准
无版税的竞争对手:
- VP8:Google提供的免费,开放源代码编解码器
- VP9:VP8的后继,几乎与H.265一样好
- AV1:目前正在开发作为VP9的继任者
(4)最重要的无损编解码器
无损编解码器可用于存档,编辑...
- 原始YUV,HuffYUV,FFV1,...
- 原始PCM,FLAC,ALAC,...
此外,还存在“视觉上无损”的编解码器:
- 苹果ProRes,Avid DNxHD,JPEG2000,高质量H.264 / H.265,...
- 高比特率,通常只有I帧
7、编码器
- 编码器是输出符合编解码器的比特流的实际软件
- 编码器可以在质量和性能上有所不同
例子:
- libx264:最受欢迎的免费和开源H.264编码器
- NVENC:基于NVIDIA GPU的H.264编码器
- libx265:免费和开源的HEVC编码器
- libvpx:Google的VP8和VP9编码器
- libfdk-aac:AAC编码器
- aac:原生FFmpeg AAC编码器
...
→很多竞争
8、编码器支持FFMPEG
$ ffmpeg -encoders
Encoders:
V..... = Video
A..... = Audio
S..... = Subtitle
.F.... = Frame-level multithreading
..S... = Slice-level multithreading
...X.. = Codec is experimental
....B. = Supports draw_horiz_band
.....D = Supports direct rendering method 1
------
V..... a64multi Multicolor charset for Commodore 64 (codec a64_multi)
V..... a64multi5 Multicolor charset for Commodore 64, extended with 5th color (colram) (codec a64_multi5)
V..... alias_pix Alias/Wavefront PIX image
...
9、像素格式
- 视频流中原始像素的表示
- 指定亮度/颜色分量和色度子采样的顺序
图片来源:维基百科(https://en.wikipedia.org/wiki/Chroma_subsampling)
支持的像素格式:ffmpeg -pix_fmts
10、练习1
任务:
从网上下载一个PNG图像
运行以下命令:
ffmpeg -loop 1 -i <image> -t 5 output.mp4
视频文件播放效果
问题:
- 什么编解码器和编码器是自动选择输出文件?
- 什么像素格式是由ffmpeg自动选择的?
- 你为什么认为这样做?
11、 使用FFMPEG命令行工具进行编码
(1)一般语法
ffmpeg <global-options> <input-options> -i <input> <output-options> <output>
- 日志输出,文件覆盖,全局选项...
- 用于读取文件的输入选项
- 输出选项:
- 转换(编解码器,质量...)
- 滤波
- 流映射
完整的帮助:ffmpeg -h full或man ffmpeg
12、转码和传输
(1)从一个编解码器转码到另一个:
ffmpeg -i <input> -c:v libx264 output.mp4
(2)从一个容器/格式转换到另一个 - 不用重新编码:
ffmpeg -i input.mp4 -c copy output.mkv
ffmpeg将从输入中获取一个视频,音频和字幕流,并将其映射到输出。
说明:
- -c设置编码器(参见ffmpeg编码器)
- -c复制只复制比特流
- -c:v仅设置视频编码器
- -c:仅设置音频编码器
- -an和-vn会禁用音频或视频流
13、转码背景
从http://ffmpeg.org/ffmpeg-all.html:
ffmpeg […] read[s] input files and get packets containing encoded data from them. When there are multiple input files,
ffmpeg tries to keep them synchronized […].
Encoded packets are then passed to the decoder. […] The decoder produces uncompressed frames […] which can be processed further by filtering […].
After filtering, the frames are passed to the encoder, which encodes them and outputs encoded packets. Finally those are passed to the muxer,
which writes the encoded packets to the output file.
14、寻找和切割
(1)从时间戳<开始>剪辑视频<持续时间>,或直到<结束>:
ffmpeg -ss <start> -i <input> -t <duration> -c copy <output>
ffmpeg -ss <start> -i <input> -to <end> -c copy <output>
(2)eg
ffmpeg -ss 00:01:50 -i <input> -t 10.5 -c copy <output>
ffmpeg -ss 2.5 -i <input> -to 10 -c copy <output>
(3)笔记:
- 重新编码时,寻求总是准确的
- 当复制比特流时(-c复制),ffmpeg可以复制未示出但是必要的帧
- 另见:http://trac.ffmpeg.org/wiki/Seeking
15、设置质量
- 输出质量取决于编码器的默认值
- 不要只编码没有设置任何质量水平
可能的选项(只是例子):
- -b:v或-b:a来设置比特率(例如:
-b:v 1000K
,-b:v 8M
) - -q:v或-q:a设置固定质量参数(例如:本机AAC编码器的 -q:a 2)
编码器特定选项的示例:
- -crf为libx264 / libx265设置恒定速率因子
- -vbr为FDK-AAC编码器设定恒定的质量
- 许多更多; 见例如 例如,ffmpeg -h编码器= libx264
16、转换为H.264
质量恒定(CRF)编码:
ffmpeg -i <input> -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mkv
18至28的CRF看起来“不错”,越低越好。
双向编码:
ffmpeg -y -i <input> -c:v libx264 -b:v 8M -pass 1 -c:a aac -b:a 128k -f mp4 /dev/null
ffmpeg -i <input> -c:v libx264 -b:v 8M -pass 2 -c:a aac -b:a 128k output.mp4
(Windows:使用NUL而不是/ dev / null)
请参阅https://trac.ffmpeg.org/wiki/Encode/H.264
17、速率控制
不同种类的费率控制:
- 恒定比特率(CBR)
- 可变比特率(VBR)
- 平均比特率(ABR)
- 恒定量化参数(CQP)
- 基于心理视觉属性的恒定质量 CRF在x264 / x265 / libvpx-vp9中
- 约束比特率(VBV)
在哪种情况下使用哪种费率控制?
更多信息:https://slhck.info/video/2017/03/01/rate-control.html
18、速率控制示例
- 随着时间的推移(平滑)不同的速率控制模式的帧大小
- 观察ABR开始时比特率的错误估计
19、速度VS. 质量VS. 文件大小
(有损)编码总是一个折衷之间:
例如:
- 你可以有快速,高质量的编码,但文件会很大
- 您可以拥有高质量,更小的文件大小,但编码时间会更长
- 你可以使用快速编码的小文件,但质量会很差
20、速度/质量预置在X264
使用预设选项选择libx264的编码速度:
ffmpeg -i <input> -c:v libx264 -crf 23 -preset ultrafast -an output.mkv
ffmpeg -i <input> -c:v libx264 -crf 23 -preset medium -an output.mkv
ffmpeg -i <input> -c:v libx264 -crf 23 -preset veryslow -an output.mkv
所有预设:ultrafast
, superfast
, veryfast
, faster
, fast
, medium
, slow
, slower
, veryslow
示例结果(全部具有相同的质量!):
21、改变框架
通过删除或复制帧来更改帧率的简单方法:
ffmpeg -i <input> -r 24 <output>
更复杂的方法涉及过滤,请参阅fps,mpdecimate,minterpolate过滤器。
22、流映射
每个文件及其流都有一个唯一的ID,从0开始。
例子:
0:0是第一个输入文件的第一个流
0:1是第一个输入文件的第二个流
2:a:0是第三个输入文件的第一个音频流
...
您可以将输入流映射到输出,例如 将音频添加到视频:
ffmpeg -i input.mp4 -i input.m4a -c copy -map 0:v:0 -map 1:a:0 output.mp4
请参阅:ttp://trac.ffmpeg.org/wiki/Map
23、简单的过滤
ffmpeg有很多视频,音频,字幕过滤器:
ffmpeg -i <input> -filter:v "<filter1>,<filter2>,<filter3>" <output>
一个<filter>有一个名字和几个选项,以及一些预定义的变量:
-filter:v <name>=<option1>=<value1>:<option2>=<value2>
笔记:
- 您可以使用-filter:a作为音频过滤器。
- 过滤器可以链接在一起分开,
- 使用ffmpeg -filters查看所有过滤器
- 检查http://trac.ffmpeg.org/wiki/FilteringGuide and http://ffmpeg.org/ffmpeg-filters.html
24、SCALING
(1)缩放到320×240:
ffmpeg -i <input> -vf "scale=w=320:h=240" <output>
eg:
mediainfo
(2)缩放到240的高度,并保持宽高比可以被2整除:
ffmpeg -i <input> -vf scale=w=-2:h=240 <output>
(3)如果需要,可缩放至1280×720或更小:
ffmpeg -i <input> -vf "scale=1280:720:force_original_aspect_ratio=decrease" <output>
eg:
www@TinywanAliYun:~/ffmpeg$ ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease" output-scale-1280x720.mp4
更多提示:
- http://trac.ffmpeg.org/wiki/Scaling%20(resizing)%20with%20ffmpeg
- https://superuser.com/questions/547296/
25、填充
将黑色边框添加到文件,例如 1920×800输入到1920×1080:
ffmpeg -i <input> -vf "pad=1920:1080:(ow-iw)/2:(oh-ih)/2" <output>
eg1:1920x800
ffmpeg -i input.mp4 -vf "scale=1920:800:force_original_aspect_ratio=decrease" output-scale-1920x800.mp4
eg2:1920x800 => 1920x1080
ffmpeg -i output-scale-1920x800.mp4 -vf "pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output-scale-1920x1080.mp4
26、衰退
在特定的时间内在特定的时间内简单的淡入和淡出。
ffmpeg -i <input> -filter:v \
"fade=t=in:st=0:d=5,fade=t=out:st=30:d=5" \
<output>
笔记:
- t设置淡入类型(进入或退出)
- d设定持续时间
- st设定以秒为单位的开始时间或HH:MM:SS.msec
- ffmpeg不能“从后面搜索”; 你必须自己找到总的持续时间(例如用ffprobe)
27、绘图文本
用于在视频上打印文本的复杂系统:
ffmpeg -i <input> -vf \
drawtext="text='Test Text':x=100:y=50:\
fontsize=24:fontcolor=yellow:box=1:boxcolor=red" \
<output>
eg:
ffmpeg -i input.mp4 -vf drawtext="text='Hello Tinywan':x=100:y=50:\
fontsize=24:fontcolor=yellow:box=1:boxcolor=red" output-vf-text.mp4
- 与字体系列,大小,位置,颜色相关的各种选项...
- 文本扩展(以帧号或时间码烧录)
- 更多:http://ffmpeg.org/ffmpeg-all.html#drawtext-1
28、复杂的过滤
复杂的过滤器有多个输入和/或输出:
ffmpeg -i <input1> -i <input2> -filter_complex \
"[0:v:0][1:v:0]overlay[outv]" \
-map "[outv]" <output>
步骤:
- 指定过滤链的输入(例如[0:v:0] [1:v:0])
- 在链中指定过滤器(例如覆盖)
- 指定链的输出标签(例如[outv])
- 将输出标签映射到最终输出文件
- 你可以有多个过滤链;
更多:http://ffmpeg.org/ffmpeg-all.html#Filtergraph-syntax-1
29、协调流量
解码三个视频/音频流并相互追加:
ffmpeg -i <input1> -i <input2> -i <input3> -filter_complex \
"[0:0][0:1][1:0][1:1][2:0][2:1]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" <output>
See: http://trac.ffmpeg.org/wiki/Concatenate (also for other methods)
五、练习2 - PT.1
- 采取一个原始的1920×1080视频文件
- 将其剪裁到5秒长度,并将其缩小到240像素的高度
- 保持相同的宽高比,保持原始音频流不重新编码。
- 采取缩小版本的视频,并通过连接将其附加到原始视频,并使用您选择的无损编解码器对最终文件进行编码
- 提示:您必须先重新升级
- 奖励点,如果你可以在一个命令做到这一点
练习2 - PT。2
问题:
- 你如何使ffmpeg找出输出宽度?
- 最终输出宽度是多少? 根据数学,输出宽度应该是多少?
- 为什么这些价值有时不同?
- 为什么连接时要重新升级视频?
(1)时间表编辑
仅在特定时间点启用过滤器。
例:
- 在左上角显示一个水印
- 仅在第1秒和第2秒之间
ffmpeg -i <video> -i <watermark> -filter_complex \
"[0:v][1:v]overlay=10:10:enable='between(t,1,2)'[outv]" \
-map "[outv]" <output>
更多:http://ffmpeg.org/ffmpeg-all.html#Timeline-editing
(2)计算简单的质量指标
PSNR(峰值信噪比):
$ ffmpeg -i <degraded> -i <reference> -filter_complex psnr -f null /dev/null
[Parsed_psnr_0 @ 0x7fdb187045c0] PSNR y:33.437789 u:39.814416 v:39.319141 average:34.698320 min:29.305186 max:inf
SSIM(结构相似性):
$ ffmpeg -i <degraded> -i <reference> -filter_complex ssim -f null /dev/null
[Parsed_ssim_0 @ 0x7fbf0500b660] SSIM Y:0.925477 (11.277116) U:0.948906 (12.916325) V:0.946795 (12.740513) All:0.932935 (11.735054)
笔记:
- 可以选择添加:2>&1 | grep SSIM只过滤相关的输出
- Windows用户使用NUL而不是/ dev / null
- PSNR是一个不可靠和不准确的质量指标,SSIM更好但不完美
- 尝试改用“适当的”视频质量指标,例如 VQM或VMAF
练习3 - PT。1
任务:
- 使用两遍编码将示例视频转换为H.264格式的x264
- 使用以下比特率:1M,2M,4M,6M,8M
- 使用libx264的所有现有速度预设和所有选定的比特率对视频进行编码。
提示:
- 这可能需要一些时间,取决于您的CPU速度
- 如果您可以编写简单的批处理或Bash脚本而不是键入所有命令,则可以获得奖励积分
练习3 - PT。2
问题:
- 编码平均需要多长时间才能达到给定的速度预设?
- 对于每个目标比特率,绘制一条显示所用时间(y轴)与所用预设(x轴)的曲线。 (如果将曲线叠加在一个曲线上,例如通过不同的颜色,则可以得到奖励点。)
- 你看到编码剪辑之间的质量差异?
- 计算具有不同预设的编码视频的质量度量。
- 对于每个目标比特率,绘制一条显示质量(y轴)与所用预设(x轴)的曲线。 (如果将曲线叠加在一个曲线上,例如通过不同的颜色,则可以得到奖励点。)
提示:
- 您可以使用内置的ssim过滤器作为质量的粗略衡量标准
- 在Linux上,你可以使用time命令,在Windows上这有点难(做一个网页搜索)
- 这可以用Excel来完成,但是像Python或R这样的其他工具也是有用的
(4)许多其他过滤器
例子:
- 使用选择过滤器进行场景变化检测
- 删除水印(delogo)
- 模糊,边缘检测和卷积滤波器
- 视频稳定
- 矢量显示器,直方图和其他信息
- 色度和alpha键控
- 字幕编辑
六、使用FFPROBE获取媒体信息
(1)总体概念
ffprobe <input>
[-select_streams <selection>]
[-show_streams|-show_format|-show_frames|-show_packets]
[-show_entries <entries>]
[-of <output-format>]
说明:
- 例如,select_streams仅用于指定视频或音频
- show_选择要显示的信息
- show_entries用于选择要显示的条目较少
- 设置输出格式
更多:
(2)实用FFPROBE示例PT-1
显示所有可用的流:
ffprobe <input> -show_streams
eg:
ffprobe output.mp4 -show_streams
在视频流上显示信息:
ffprobe <input> -select_streams v -show_format
eg:
ffprobe output.mp4 -select_streams v -show_format
以CSV格式显示每个帧的呈现时间戳和帧类型(p = 0禁用CSV段标题)
ffprobe <input> -select_streams v -show_frames \
-show_entries frame=pkt_pts_time,pict_type -of csv=p=0
(3)实用FFPROBE示例PT。2
【1】将输出更改为JSON格式进行解析:
ffprobe <input> -select_streams v -show_packets -of json
eg:
ffprobe output.mp4 -select_streams v -show_format -of json
{
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.40.101
Duration: 00:00:05.00, start: 0.000000, bitrate: 105 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 1464x717, 101 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 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": "5.000000",
"size": "65967",
"bit_rate": "105547",
"probe_score": 100,
"tags": {
"major_brand": "isom",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"encoder": "Lavf56.40.101"
}
}
}
【2】获取文件中的流数(nk = 1禁用键):
ffprobe <input> -show_format -show_entries format=nb_streams -of compact=nk=1:p=0
【3】以秒为单位获得持续时间或HH:MM:SS.ms:
ffprobe <input> -show_format -show_entries format=duration -of compact=nk=1:p=0
ffprobe -sexagesimal <input> -show_format -show_entries format=duration -of compact=nk=1:p=0
eg1:(5s)
ffprobe output.mp4 -show_format -show_entries format=duration -of compact=nk=1:p=0
eg2:(0:00:05.000000)
ffprobe -sexagesimal output.mp4 -show_format -show_entries format=duration -of compact=nk=1:p=0
【4】以Bit / s格式获取音频流的比特率:
ffprobe <input> -select_streams a -show_entries stream=bit_rate -of compact=nk=1:p=0
eg1
ffprobe bunny_1080p_60fps.mp4 -select_streams a -show_entries stream=bit_rate -of compact=nk=1:p=0
七、检查视频编解码器
(1)调试运动向量
使用MPEG编解码器(H.264,H.265,...)在FFmpeg中可视化运动的简单方法:
ffplay -flags2 +export_mvs input.mp4 -vf codecview=mv=pf+bf+bb
ffmpeg -flags2 +export_mvs -i input.mp4 -vf codecview=mv=pf+bf+bb <output>
- pf - 预测P图像的预测运动矢量
- bf - 预测B图像的预测运动矢量
- bb- B画面的后向预测运动矢量
(2)调试运动向量
更多信息:http://trac.ffmpeg.org/wiki/Debug/MacroblocksAndMotionVectors
调试宏块类型
使用MPEG编解码器(H.264,H.265,...)可视化FFmpeg中的宏块分割:
ffplay -debug vis_mb_type input.mp4
ffmpeg -debug vis_mb_type -i input.mp4 output.mp4
视频流分析仪
用于图形分析比特流的不同软件:
Elecard流分析仪(商业)
CodecVisa(商业)
英特尔视频专业分析仪(商业)
概要
你应该学会如何:
- 了解FFmpeg库,编解码器,容器,编码器,...
- 编码视频和音频
- 应用基本过滤器
- 读取流信息和元数据
- 如果遇到困难,请寻求帮助