昨天,有个朋友给我出了个难题:他手上有一个视频,1080P的,49秒,200多兆;要求在确保质量的情况下把文件压缩到10M以内。

这是什么概念呢?按照文件大小10M来计算,码率是:10 x 8 / 49 = 1.6 Mbps。也就比VCD的质量略好一点(注:VCD的标准码率是1150 Kbps)。谈何“确保质量”?mission impossible啊!

咱还是现实一点吧。在不明显损失画质的前提下,看看使用FFmpeg能够帮到多少忙。用iPhone拍了一个1920 x 1080的视频,33秒,46.3 MB,编码格式是H.264。考虑到H.264目前尚是主流的视频格式,为了播放的兼容性,我们在使用FFmpeg转码时同样选择H.264。

命令行参数-crf

在优先保证画面质量(也不太在乎转码时间)的情况下,使用-crf参数来控制转码是比较适宜的。这个参数的取值范围为0~51,其中0为无损模式,数值越大,画质越差,生成的文件却越小。从主观上讲,18~28是一个合理的范围。18被认为是视觉无损的(从技术角度上看当然还是有损的),它的输出视频质量和输入视频相当。

我们的策略是,在保证可接受视频画质的前提下,选择一个最大的crf值——如果输出视频质量很好,那就尝试一个更大的值;如果看起来很糟,那就尝试一个小一点的值。

让我们先执行下面这条命令(关于FFmpeg运行环境的配置,请参阅这篇文章):

ffmpeg -i D:\src.mov -c:v libx264 -preset veryslow -crf 18 -c:a copy D:\dest1.mp4

意思是:将D盘的源文件src.mov,以“非常慢”的速度重新编码成H.264格式,保存为D:\dest1.mp4。其中,-preset指定的编码速度越慢,获得的压缩效率就越高。而-c:a copy又是什么意思呢?因为音频的码率一般都比较小,我们就不折腾它了,况且解码后重新编码也会损害音质,于是,就将音频数据从源文件中以原有编码格式直接拷入目标文件吧。

小提示:想知道-c:v 后面的参数值怎么填吗?或者说FFmpeg到底支持哪些音视频编码格式?执行ffmpeg –encoders看一下吧。另外,执行ffmpeg -i D:\src.mov -c:v libx264 -preset -tune D:\dummy.mp4可以看到-preset参数的取值范围,如下:

有个小疑问:既然不在乎等待时间,为什么不给-preset指定一个最慢的placebo呢?那是因为:与 veryslow相比,placebo以极高的编码时间为代价,只换取了大概1%的视频质量提升。这是一种收益递减准则:slow 与 medium相比提升了5%~10%;slower 与 slow相比提升了5%;veryslow 与 slower相比提升了3%。

另外,针对特定类型的源内容(比如电影、动画等),还可以使用-tune参数进行特别的优化。但如果你不确定该用哪个选项,还是忽略这个参数吧。

对比效果

执行完一条转码命令之后,调整-crf参数值,分别设为19、20、28、51,重新转码输出为不同的MP4文件。记录数据,对比如下:

 

crf = 18

crf = 19

crf = 20

crf = 28

crf = 51

文件大小(MB)

46.3

36.7

31.2

26.5

7.95

1.25

缩减比率

21%

33%

43%

83%

97%

尝试播放这些文件。发现crf取值为18~28的情况下生成的文件,其画质没有明显的差异,而以-crf 51生成的视频画质已经惨不忍睹了!在实际应用中,多试几个crf值,在画质和压缩比之间找到一个你能接受的平衡点即可。

参考文章:ffmpeg与x264编码指南

黄聪:FFmpeg视频转码技巧之-crf参数(H.264篇)的更多相关文章

  1. C#实现 ffmpeg视频转码、播放

    近来公司项目要求实现全景相机的视频截取,但是截取的视频需求转码上传.经过研究采用ffmpeg转码,奉上一个详细介绍的博文: 最简单的基于FFMPEG的转码程序 主要是转码的操作过程,能够实现了从相机获 ...

  2. 【视频编解码·学习笔记】6. H.264码流分析工程创建

    一.准备工作: 新建一个VS工程SimpleH264Analyzer, 修改工程属性参数-> 输出目录:$(SolutionDir)bin\$(Configuration)\,工作目录:$(So ...

  3. 【视频编解码·学习笔记】4. H.264的码流封装格式

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  4. 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  5. 新手学习FFmpeg - 调用API完成录屏并进行H.264编码

    Screen Record H.264 目前在网络传输视频/音频流都一般会采用H.264进行编码,所以尝试调用FFMPEG API完成Mac录屏功能,同时编码为H.264格式. 在上一篇文章中,通过调 ...

  6. 【视频编解码·学习笔记】3. H.264视频编解码工程JM的下载与编解码

    一.下载JM工程: JM是H.264标准制定团队所认可的官方参考软件.网址如下 http://iphome.hhi.de/suehring/tml/ 从页面中可找到相应的工程源码,本次选择JM 8.6 ...

  7. 【视频编解码·学习笔记】2. H.264简介

    一.H.264视频编码标准 H.264视频编码标准是ITU-T与MPEG合作产生的又一巨大成果,自颁布之日起就在业界产生了巨大影响.严格地讲,H.264标准是属于MPEG-4家族的一部分,即MPEG- ...

  8. java运用FFMPEG视频转码技术

    基于windows系统安装FFMPEG转码技术 http://wenku.baidu.com/link?url=z4Tv3CUXxxzLpa5QPI-FmfFtrIQeiCYNq6Uhe6QCHkU- ...

  9. java ffmpeg视频转码(自测通过)

    import java.io.*; public class VideoTransfer { //ffmepg文件 安装目录 private static String ffmpeg = " ...

随机推荐

  1. webgl opengl教程样例

    webgl2样例: http://webglsamples.org opengl教程: https://learnopengl.com/ http://www.opengl-tutorial.org/ ...

  2. 安卓 dex 通用脱壳技术研究(四)

    /*     当第一个类执行到此函数时,我们在dvmDefineClass执行之前,也就是第一个类加载之前     注入我们的dump代码:即DumpClass()函数 */ static void  ...

  3. php字符编码转换之gb2312转为utf8(转)

    在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...

  4. 九度OJ-1042-最长公共子序列(LCS)

    题目1042:Coincidence 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4045 解决:2208 题目描述: Find a longest common subsequence ...

  5. WINDOWS系统的正确安装-硬盘格式如何选择

    有一种这样的说法,WIN7改装WIN10必须要重新分区,将硬盘格式化为GPT格式(GUID分区表 ), WIN10改装WIN7必须要重新分区,将硬盘格式化为MBR格式. 这种说法一直困扰着我,于是经过 ...

  6. Centos7禁止或者允许开机启动服务

    [root@bogon rsyslog.d]# systemctl is-enabled httpd disabled [root@bogon rsyslog.d]# systemctl status ...

  7. centos7升级自带的php5.4版本到php5.6

    history命令历史 8 yum provides php #自带的只有5.4版本 9 rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-relea ...

  8. php7 php-fpm 重启

    PHP7中php.ini.php-fpm和www.conf的配置 http://www.tuicool.com/articles/NjmQNj6 php-fpm 关闭:  kill -SIGINT ` ...

  9. 对某个区间操作(sort,stable_sort,parital_sort,parital_sort_copy,nth_element,is_sorted)

    sort //版本一 template <class RandomAccessIterator> void sort(RandomAccessIterator first,RandomAc ...

  10. mysql 的 docker 镜像使用

    mysql 的 docker 镜像使用: 下载镜像: docker pull mysql:8.0.14 运行容器: docker run -it -e MYSQL_ROOT_PASSWORD=mypw ...