

封面图(说起来军火商黄仁勋与FFmpeg本来是八竿子打不着的)
此文本来想写短一些,但是文字太少解释不清楚很多内容,一下子输出了两千字。
本文适用于硬盘里有一堆游戏录像或者网课占用着硬盘或者手机录制了很多视频不想删但是不知道该怎么处理的人。请注意命令行没那么可怕。
本文中没有涉及到的具体使用教程之类的东西可能会在以后补充,如果没有补充请自行百度或者谷歌寻找教程。大方向我认为我写清楚了,具体怎么操作有很多人科普过,我没必要再重复。
FFmpeg是一个“自由软件”(开源软件的一种,源代码对外公布,这软件是全世界的程序员在下班时间弄出来的,听起来业余,实际上很好用,至今历史有20余年了吧。)作为个人用户自己用这软件是没什么问题的,原则上讲不能拿来盈利(但是格式工厂和QQ影音之类不讲原则的人太多了)。
HEVC/H265是比现在流行的MP4普遍采用的AVC/H264更先进的视频编码标准。(现在没有普及貌似是因为软硬件专利费用大于企业可以节省下来的开支。)
相比于现在流行的MP4格式使用的AVC/H264(现在你看到的视频百分之90是用这个方式编码的),HEVC/H265可以在保证画质的前提下把视频体积缩小30%-50%,很多商业公司为了推荐自己的HEVC算法会宣称视频体积可以腰斩,这话说的不完全正确,大多数情况下如果要保证质量,编码之后的视频体积经常是原视频的55%-70% 。直接把原视频码率除以2编码,一般问题不大但是细节可能会有明显的损失的(比如色块涂抹,锐度下降之类的)。

HEVC Advance联盟制作的对比表格
NVENC是英伟达做出来的一套视频编码的硬件加速接口,曾经HEVC编码是很痛苦时间很长的事情,只有软编码可靠能用,硬件加速的效果很差画质很烂被人骂,但是现在是2020年了朋友,不要迷信过时的老帖子旧教程,你要对老黄的魔法有信心。
hevc_nvenc与h264_nvenc是FFmpeg的“编码器”,官网挂着的编译好的程序下载以后就可以直接使用,不用下载源代码自己再编译,只要正常安装N卡驱动就能用。而libx264与libx265,你可以理解为没有硬件加速的“编码器”,对于HEVC编码质量会好一点,但是要花非常非常长的时间代价。
在ffmpeg或者基于ffmpeg编写的视频编码、转码、“压制”软件里(格式工厂、QQ影音之流),限制视频大小(控制码率)主要有两种方式:直接限制视频流的码率(ABR,平均码率控制)或者设置适当的CRF(恒定码率系数),当然还有一个“CQP”,我从来没用过这个方法,没具体研究过这个方式的原理。
ABR方式直接限制了视频流的平均比特率,此方法可以使用硬件加速(NVIDA的NVENC,A卡不知道或许也是支持的),但是有些高级参数不能调整,没有libx264、libx265灵活。主要适用于网课,直播录屏,老电影,低清晰度、不重要的影视片源以及爆米花电影(这种看一遍就不会再看的电影难道不应该删掉吗?)。
CRF不支持N卡加速,只能用CPU,速度很慢。CRF这个参数值越大视频文件越小,画质越差,大于24以后可能会有肉眼可见的差别,但是我自己测试,参数设置到28照样可以接受,大多数情况下视频不会一点一点一帧一帧的看,糊一点问题不大。主要适用于优先考虑视频画面质量,其次再考虑占用磁盘空间的情况。

CRF参数范围,FFmpeg默认23,字幕组普遍在用18-24,大多数人选择28就够用了。
如果不考虑花费的时间,大致不会出问题的前提下尽可能压缩占用空间,我个人建议选择 -crf 28 ,CRF 28适用于各种各样的视频,可以保证直观观感上大致看不出来画质损失。但问题是软编码需要时间是视频时间的好几倍甚至几十倍,太慢了耗不起。
网课普遍的静止的画面内容很多,ABR与硬件加速(hevc_nvenc)是完全够用的,至于具体码率设置要自己试,我自己测试720P的视频流最低可以降到128kbps。(如果以后有详细版长图文,会注明原因)
同样一个视频,编码成HEVC/H265,N卡加速花费的时间是原视频的22分之一,没有硬件加速需要的时间是原视频的10倍。调整好了参数,两种编码生成的视频没有肉眼可见的差别。(评估两个视频编码以后的差别,FFmpeg提供了SSIM与PSNR这两个参数,人眼识别找茬说实话不靠谱太主观了还费劲)

软编码花费时间太长,5分半的视频用时2969秒,不重要的视频没必要这么折腾。
我这台式机(E3 1231 v3 (4C8T),16G RAM,GTX 1050Ti)试着比较合适的命令行参数如下:
FFmpeg + hevc_nvenc:
ffmpeg -i "input.mp4" -c:v hevc_nvenc -b:v 1250k -maxrate 8000k -bufsize 8000k -c:a copy "output.mp4"
FFmpeg + libx265:
ffmpeg -i "input.mp4" -c:v libx265 -crf 23 -x265-params ctu=32:bframes=6:rc-lookahead=70:no-open-gop=1:subme=3:merange=25:no-amp=1:no-sao=1:rd=5 -c:a copy "output.mp4"
命令行里的每个参数还是比较重要的,但是这不是本文的重点,具体是怎么回事后续可能会补充一篇文章介绍,也可能不会补充。
理论上讲Linux平台使用正常编译的FFmpeg也可以用这个同样的命令行参数编码转码视频。然而实际上我没有测试的条件,具体会不会报错不知道。
FFmpeg程序直接在其官网下载即可,真的不想在Windows用命令行的可以考虑使用格式工厂,用一用没问题,但是编码效果差一些,上述命令行很可能不能用了,安装过程小心流氓软件。
本文中没有涉及到的具体使用教程之类的东西可能会在以后补充,如果没有补充请自行百度或者谷歌寻找教程。
我会在其他可以发文稿的平台同步这篇短文,希望不会有什么人会把这个没什么水平的文章据为己有转载或者洗稿,如果真的有人这么干了我只能说这人实在是太没水平了。