FFmpeg H.264编码器指南[译]

ffmpeg,编码器,指南 · 浏览次数 : 18

小编点评

#生成内容排版 **1.定义参数** - preset slow:速度慢 - preset veryslow:速度快速 - crf 18:18压缩率 - crf 23:23压缩率 - crf 51:51压缩率 - crf 0:无损 **2.设置参数** - input:输入视频 - vcodec:视频编码器 - preset:预设参数 - c:a:音频编码器 **3.生成视频** - preset slow: ffmpeg -i input.mp4 -vcodec libx264 -preset slow -crf 18 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - preset veryslow: ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 23 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - preset ultrafast: ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 51 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - crf 18: ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 18 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - crf 23: ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 23 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - crf 51: ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 51 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv - crf 0: ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 0 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv **4.保存视频** - name:视频名称 - output:视频路径 **5.重复生成视频** - repeat:次数 - name:视频名称 - output:视频路径

正文

H264 视频编码器指南

本指引着眼于x264编码器,这里假设你的FFmpeg 编译了--enable-libx264支持。如果你需要编译支持的帮助请看这篇文档:https://trac.ffmpeg.org/wiki/CompilationGuide,看 HWAccelIntro关于支持H264编码器在逻辑上的支持;

有两种适用于大部分场景的码率控制模式

Constant Rate Factor (CRF) : 恒定码率因子模式

Two-Pass ABR: 两遍式控制模式

码率控制是指每帧需要处理多少bits的数据。码率控制会决定视频文件的大小和质量的优劣。需要更多关于码率控制模式的区别,请看这篇文章

CRF-- 恒定码率因子模式

推荐在你需要保证视频的质量最佳,而完全不关心视频文件的大小的时候使用这种模式;

这种模式运行编码器当在不关心输出文件的大小时,得到一个一定质量的视频;这种方式可以让一次处理达到一个最大的压缩效果。也可以通过调整每帧所谓的量化因子,可以得到所需的比特率去保证要求的视频质量等级;不过缺点就是你不能指定输出文件的大小或者限制视频不能超过某个大小阈值,也就是说这种方式不推荐用到流式的视频编码。

1、设置CRF的值

CRF的取值范围是0-51,0是画面质量最高的无损(只是针对8bit,10bit的话要用 -qp 0),默认值是23,51的话是画质最差的。值越低,质量越高(可以理解为画面质量的损失值),主管的认为合理的值范围是17-28。

17或者18是肉眼区别不出来的无损或者几乎区分不出来的无损;这时看起来跟输入一样或者非常接近,但技术来说并不是无损的。

CRF的取值范围对画质的影响是指数级别的,所以,参数值+6的结果差不多只有原数值比特率/文件大小的一半。同样,参数值-6会导致大概比特率/文件大小是原来的两倍。

在视频质量可以接受的范围选择一个CRF最大的值。 如果输出画质依旧非常好,再选大一点,如果画质不行,再调小;

注意:0-51 的CRF取值范围仅适用于8-bit 的x264. 如果你编译了10bit的x264,CRF的取值范围是 0-63,(在x264的源码上,它是-12到51,只不过是 FFmpeg的 libx264给包装了一层,做了偏移处理。所以0依旧是无损的,但只在受支持的配置文件中,High 10 不支持无损)。
你可以通过FFmpeg编码处理的控制台输出判断你究竟在用哪种(yuv420p就是8-bit的,yuv420p10le就是10-bit的)。8-bit更常用;

2、选择一个预设值和Tune;

preset--预设值

译者:--preset的参数主要调节编码速度和质量的平衡

预设值是一系列保证确定的编码速度和压缩率的选项值的集合。慢的预设值能提供更好的压缩效率(也就是文件能压缩得更小)。例如,如果你设定了确定的文件大小或者固定的比特率,你能用更慢的预设值得到更好的质量。同样的,对于固定的质量编码,你能通过选择较慢的预设值到简单保存比特率;

选在你耐心范围内最慢的预设值。所有的预设值由慢到快的速度排序如下:

  • ultrafast (很快,但文件很大 几乎没怎么压缩)
  • superfast
  • veryfast
  • faster
  • fast
  • medium – 默认预设值
  • slow
  • slower
  • veryslow (很慢,但压缩率很高 文件很小)
  • placebo – 忽略这个,这个没啥用 (参考 FAQ)

你可以通过参数:-preset help看到当前的所有预设值。如你安装了x264的库,你也可以用x264 --fullhelp 查看完整的预设设置;

Tune

译者:--tune的参数主要配合视频类型和视觉优化的参数。

你可以用-tune参数去改变你指定的输入的设置,当前的turn有如下值:

  • film – 适用于高质量的电影,降低去块效应。use for high quality movie content; lowers deblocking
  • animation – 适用于动画,使用更高级的去块处理和更多的参考帧。 good for cartoons; uses higher deblocking and more reference frames
  • grain – 保留旧的、颗粒状的影片材料中的颗粒结构。 preserves the grain structure in old, grainy film material
  • stillimage – 适用于幻灯片式的内容。good for slideshow-like content
  • fastdecode – 通过关掉某些路径,实现更快的编码。allows faster decoding by disabling certain filters
  • zerolatency – 适用于快的编码和低延迟的流。 good for fast encoding and low-latency streaming
  • psnr – 忽略此项,编码器开发用的。ignore this as it is only used for codec development
  • ssim – 忽略此项,编码器开发用的。ignore this as it is only used for codec development

例如,如果你的输入是一个动画你可以用animation,或者你你保留颗粒状在影片里你可以用grain选项。如果你不确定你要用那个选项或者不知道你的输入适用何选项你可以忽略 -tune 选项。你可以用 -tune help查看所用的tune选项列表,或者用 x264 --fullhelp看这些选项设置的含义。

Profile(配置文件)

译者:限制输出文件的profile。这个参数将覆盖其它所有值,此选项能保证输出profile兼容的视频流。如果使用了这个选项,将不能进行无损压缩(qp 0 or crf 0)。

一般不建议设置;

-profile:v 参数将输出限定为特定的H264配置。一般来说你不想理用这个选项,建议忽略这个设置h264会自动选择合适的配置文件;

某些设备(一般是老掉牙的)只支持更多限制的Constrained BaselineMain profiles。你可以设置这些选项值为 -profile:v baseline or -profile:v main. 新设备一般都支持更高级的 High配置文件。

另外要用这个参数的原因是,要去匹配其他用 concat demuxer连接的视频文件。

注意:-profile:v参数不兼容无损的编码,setting -profile:v high444 也是无效的。

x264支持的配置文件如下:

  • baseline
  • main
  • high
  • high10 (first 10 bit compatible profile)
  • high422 (支持yuv420p, yuv422p, yuv420p10le and yuv422p10le)
  • high444 (supports as above as well as yuv444p and yuv444p10le)

列出预算和tunes

用以下命令列出当前的预算和tunes:

ffmpeg -hide_banner -f lavfi -i nullsrc -c:v libx264 -preset help -f mp4 -

注意: windows环境要改为:

ffmpeg -hide_banner -f lavfi -i nullsrc -c:v libx264 -preset help -f mp4 NUL

CRF 示例

下面命令用更慢的预设值与更好的压缩,将视频重新编码为质量好的视频。

ffmpeg -i input -c:v libx264 -preset slow -crf 22 -c:a copy output.mkv

注意,这条示例直接用简单拷贝的方式将输入的音频流拷贝到输出而没有重新编码;

如果你要处理一批相似的视频,用统一的设置,能保证这样这批视频的输出质量都接近;

译者:这里的-preset控制的是压缩率和编码速度的,-crf控制输出质量的。

Two-Pass--两遍式

如果你要输出指定大小的文件,并且输出质量和每帧的质量要求没那么高的时候, 那就用这种码率控制模式。这是用示例最好的解释。你的视频时长600秒并且需要输出大小是200MB。根据:bitrate = file size / duration:

(200 MB * 8388.608 [转换MB到KBit(1024*8/1000); 注意不是8192,因为1KBit是1000bit。]) / 600 seconds = ~2796 kBit/s 总比特率

2796 - 128 kBit/s (减去音频比特率) = 2668 kBit/s 是视频的比特率

你也可以忽略什么的计算公式如果你已经知道最终的模板比特率的话。

译者:通过上面的公式,你就能得到一个最终输出文件大小确定的视频;

两遍式示例

对应两遍式,你要用差不多一样参数跑两次,参数不同点如下:

  • 在第一遍和第二遍,用 -pass 1-pass 2 选项区别;
  • 在第一遍,输出是一个空描述,没有一个显式的输出(但会生成一个日志文件ffmpeg在第二遍需要用);
  • 在第一遍,你可以用-an参数剥离音频文件;

注意:第一遍,当用-an参数可能最终得到报段内存错误或者顺坏的文件。这样的话,去掉-an参数改为-vsync cfr就行;

例如:

ffmpeg -y -i input -c:v libx264 -b:v 2600k -pass 1 -an -f null /dev/null && \
ffmpeg -i input -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k output.mp4

windows下空输出“/dev/null”要改成“NUL”,‘\’ 要改成'`';

跟CRF一样,可用可以接受的-preset-tune-profile:v参数以得到不同的目标视频;

无损的H.264

如果设置了-profile:v high444参数你可以用 -crf 0 生成无损的视频,否则用 -pb 0(High 10 profile 配置不支持无损视频, 详看 https://code.videolan.org/videolan/x264/-/blob/master/x264.c#L579)。 ultrafastveryslow 这两个预设值是非常常用的,因为更快的编码速度和更好的压缩一般来说都是挺重要的考虑因素。

更快的编码示例:

ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 output.mkv

更好的压缩效果示例:

ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 output.mkv

提示:无损的视频文件一般来说都非常大,不是基于ffmpeg的播放器可能不能解码播放。所以,如果兼容性和文件大小问题不可忽略,就别用无损了。

提示:如果你要的视频是“视觉上无损”而不是技术上的无损的话,用-crf 17或者18就行(你自己试哪个数值可以接受)。这样不会像真正的无损模式一样搞出一个非常大和兼容性有问题的视频文件;

覆盖默认预设设置

虽然 -preset 已经预设好了可能是最优默认设置给你,但你还是可以用 x264-params 参数去覆盖默认设置,也可以用libx264 的私有参数(ffmpeg -h encoder=libx264)。当然这些参数不推荐初学者使用。预设值是ffmpeg开发人人给出的最优解你去调这些参数一般都是浪费时间。

示例:

ffmpeg -i input -c:v libx264 -preset slow -crf 22 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv

注意: 不要用‘x264opts’这个参数, 这个参数后续版本会被删的。用’x264-params‘就行;

【原文】

https://trac.ffmpeg.org/wiki/Encode/H.264

测试示例命令

crf输出示例

#修改编码速度与压缩率
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast  ultrafast.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow  veryslow.mp4

#加入crf,速度快
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 18  ultrafast_18.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 23  ultrafast_23.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 51  ultrafast_51.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 39  ultrafast_39.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 45  ultrafast_45.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 0  ultrafast_0.mp4

#加入crf,压缩率高
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 18  veryslow_18.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 23  veryslow_23.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 51  veryslow_51.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 0  veryslow_0.mp4

两遍式示例

ffmpeg -y -i input.mp4 -c:v libx264 -b:v 2097k -pass 1 -an -f null NUL  && ffmpeg -i input.mp4 -c:v libx264 -b:v 2097k -pass 2 -c:a aac -b:a 128k tow_pass_3MB_2097k.mp4

[参考]

https://ffmpeg.0voice.com/forum.php?mod=viewthread&tid=282

与FFmpeg H.264编码器指南[译]相似的内容:

FFmpeg H.264编码器指南[译]

H264 视频编码器指南 本指引着眼于x264编码器,这里假设你的FFmpeg 编译了--enable-libx264支持。如果你需要编译支持的帮助请看这篇文档:https://trac.ffmpeg.org/wiki/CompilationGuide,看 HWAccelIntro关于支持H264编

FFmpeg开发笔记(三十)解析H.264码流中的SPS帧和PPS帧

​《FFmpeg开发实战:从零基础到短视频上线》一书的“2.1.1 音视频编码的发展历程”介绍了H.26x系列的视频编码标准,其中H.264至今仍在广泛使用,无论视频文件还是网络直播,H.264标准都占据着可观的市场份额。 之所以H.264取得了巨大的成功,是因为它提出了一个新概念,把标准框架划分为

FFmpeg开发笔记(二十八)Linux环境给FFmpeg集成libxvid

​XviD是个开源的视频编解码器,它与DivX一同被纳入MPEG-4规范第二部分的视频标准,但DivX并未开源。早期的MP4视频大多采用XviD或者DivX编码,当时的视频格式被称作MPEG-4。现在常见的H.264后来才增补到MPEG-4规范的第十部分,当然如今使用XviD压缩的视频已经不多了。

FFmpeg开发笔记(三十一)使用RTMP Streamer开启APP直播推流

​RTMP Streamer是一个安卓手机端的开源RTMP直播推流框架,可用于RTMP直播和RTSP直播,其升级版还支持SRT直播(腾讯视频云就采用SRT协议)。RTMP Streamer支持的视频编码包括H264、H265、AV1等等,支持的音频编码包括AAC、G711、OPUS等等,可谓功能强大

FFmpeg开发笔记(三十三)分析ZLMediaKit对H.264流的插帧操作

​《FFmpeg开发实战:从零基础到短视频上线》一书的“3.4.3 把原始的H264文件封装为MP4格式”介绍了如何把H.264裸流封装为MP4文件。那么在网络上传输的H.264裸流是怎样被接收端获取视频格式的呢?前文指出H.264流必定以“SPS帧→PPS帧→IDR帧”开头,接下来就来验证是否确实

FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器

​AV1是一种新兴的免费视频编码标准,它由开放媒体联盟(Alliance for Open Media,简称AOM)于2018年制定,融合了Google VP10、Mozilla Daala以及Cisco Thor三款开源项目的成果。据说在实际测试中,AV1标准比H.265(HEVC)的压缩率提升了

C#进程调用FFmpeg操作音视频

开发背景 因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作。本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并

FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg

​《FFmpeg开发实战:从零基础到短视频上线》一书的“第11章 FFmpeg的桌面开发”介绍了如何在Windows环境对Qt结合FFmpeg实现桌面程序,那么Windows系统通过Visual Studio开发桌面程序也是很常见的,下面就介绍如何在Visual Studio的C++工程中集成FFm

FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址

​《FFmpeg开发实战:从零基础到短视频上线》一书在第10章介绍了轻量级流媒体服务器MediaMTX,通过该工具可以测试RTSP/RTMP等流媒体协议的推拉流。不过MediaMTX的功能实在是太简单了,无法应用于真实直播的生产环境,真正能用于生产环境的流媒体服务器还要看SRS或者ZLMediaKi

FFmpeg开发笔记(三十七)分析SRS对HLS协议里TS包的插帧操作

​《FFmpeg开发实战:从零基础到短视频上线》一书的“2.1.2 音视频文件的封装格式”介绍了视频流的PS格式和TS格式。由于TS包的长度固定,从TS流的任一片段开始都能独立解码,因此可以把TS当成音视频文件的封装格式。 鉴于TS包的独立解码特性,HLS协议引入了TS格式作为传输单元。HLS协议的