ffmpeg 参数_使用FFMPEG进行视频转码
Note: 此文章首发于我的个人博客zhi-hua.wang
,开放转载但需附上出处。
使用FFMPEG进行视频转码 - 日落孤城www.zhi-hua.wang
FFMPEG 是一款开源的视频处理软件,再利用FFMPEG转码的过程中踩了很多坑,在这里列举一些常用的 FFMPEG 命令防止忘记。
以下所有的命令的输入都是《The.Mandalorian.S01E01.INTERNAL.HDR.2160p.WEB.H265-DEFLATE.mkv》这部影片,这部影片有很多特殊的地方,所以给我带来了不少困扰。它也驱使我学习了关于视频的很多知识,以下是它的一些基本参数:
视频
格式 : HEVC
格式配置 (Profile) : Main 10@L5@High
时长 : 38 分 46 秒
码率 : 15.9 Mb/s
宽度 : 3 840 像素
高度 : 1 608 像素
原始高度 : 2 160 像素
帧率模式 : 恒定帧率 (CFR)
帧率 : 23.976 (24000/1001) FPS
色彩空间 : YUV
色度抽样 : 4:2:0
位深 : 10 位
数据密度 [码率/(像素*帧率)] : 0.108
流大小 : 4.32 GiB (94%)
色彩范围 : Limited
色彩原色 : BT.2020
传输特性 : PQ
矩阵系数 : BT.2020 non-constant
这部影片是 4K HDR10 影片,编码方式为 HEVC,像素格式为 yuv420p10le,容器分辨率为 3840X2160,实际分辨率为3840X1608,色彩范围( color range )为TV( Limited ),色彩原色( color primaries )为 bt2020,传输特性为smpte2084( PQ ),矩阵系数(color matrix )为 bt2020nc 。为了节省篇幅,以下均以input.mkv代表这个视频源文件。而且由于配备了gtx1070显卡以及安装了最新的驱动,所有的操作都是尽量利用GPU进行硬件加速。
1. 转为720p(失败)
为了达到最好的性能,我准备使用hevc_cuvid进行解码,scale_npp进行视频缩放,hevc_nvenc进行编码。-hwaccel cuvid
告诉ffmpeg使用cuvid加速,并且把视频的数据保留在显存而不是内存上。由于版权问题ffmpeg不自带scale_npp滤镜,需要自己编译。为了方便我选择manjaro系统,直接安装AUR上的ffmpeg-full
包。这个过程也很心酸,可以专门写一篇文章了,这里就不展开了。关于ffmpeg转码的文章在互联网上有很多,尤其是英伟达官网的《ffmpeg transcoding guide》建议好好读一读。
ffmpeg -hwaccel cuvid -c:v hevc_cuvid -i input.mkv -c:a copy -vf scale_npp=1280:720 -c:v hevc_nvenc -b:v 5M output.mkv
运行以上命令却报错了。原来scale_npp滤镜很娇气,无法处理10bit的视频,因此尝试失败。
2. 转为720p (format, scale_npp:48fps)
既然无法处理10bit,那我把它转成8bit呗。上format滤镜,将yuv420p10le转为yuv420p。由于format是软件滤镜,因此取消-hwaccel cuvid
。这样解码的视频会自动转存到内存。format处理好的内容使用hwupload_cuda上传到GPU,然后通过scale_npp缩放,之后通过hevc_nvenc编码。
ffmpeg -c:v hevc_cuvid -i input.mkv -c:a copy -vf "format=yuv420p,hwupload_cuda,scale_npp=1280:720" -c:v hevc_nvenc -b:v 5M output.mkv
输入以上命令,发现咋只有48fps呢?那岂不是要十几分钟?太慢了!
3. 转为720p (scale_cuda:227fps)
突然发现了scale_cuda这个宝藏,它能接受10bit输入。而且scale_cuda在ffmpeg的编译版中自带!这就好办了,赶紧敲下以下命令:
ffmpeg -hwaccel cuvid -c:v hevc_cuvid -i input.mkv -c:a copy -vf scale_cuda=1280:720 -c:v hevc_nvenc -b:v 5M output.mkv
所有任务都转到GPU上运行了,性能得到巨大提升。通过观察发现此时的瓶颈变为了GPU解码。GPU解码器的占用率高局100%,而编码器只占用了不到20%。
4. 转为720p 8bit (pix_fmt:失败)
ffmpeg -hwaccel cuvid -c:v hevc_cuvid -i input.mkv -c:a copy -vf scale_cuda=1280:720 -c:v hevc_nvenc -pix_fmt yuv420p -b:v 5M output.mkv
然而它报错:
Impossible to convert between the formats supported by the filter 'Parsed_scale_cuda_0' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0
5.转为720p 8bit (pix_fmt:223fps)
经过长时间的试错,发现之前的错误通过在scale_cuda滤镜后添加hwdownload,format=p010le
就可以解决了,至于为啥我也不知道 。-hwaccel_output_format cuda
目前可以不加,只不过会警告你以后不加就会报错了。
ffmpeg -hwaccel cuvid -hwaccel_output_format cuda -c:v hevc_cuvid -i input.mkv -c:a copy -vf "scale_cuda=1280:720,hwdownload,format=p010le" -c:v hevc_nvenc -pix_fmt yuv420p -b:v 5M output.mkv
6.用resize缩放而不是scale_cuda或scale_npp (resize:225fps)
这一条与上一条没多大的区别,只是把scale_cuda改为了resize。resize这个参数是我从英伟达官网上的一篇pdf上了解到的,它说用resize性能好一些。至于好不好我不知道,我只知道resize更易读与打出来。
ffmpeg -hwaccel cuvid -hwaccel_output_format cuda -c:v hevc_cuvid -resize 1280x720 -i input.mkv -c:a copy -vf "hwdownload,format=p010le" -c:v hevc_nvenc -pix_fmt yuv420p -b:v 5M output.mkv
7.固定质量模式
之前的转码都是恒定码率模式,很不科学。hevc_nvenc没有crf参数,这可咋办呢?好在找到了替代方案。通过将-rc:v
设置为vbr
或者vbr_hq
,从而启用VBR模式,然后设置-cq:v
、-qmin
、-qmax
。这里最好把它们设置成一个数值,否则没有多大意义。这个数值接类似于crf参数。
ffmpeg -hwaccel cuvid -c:v hevc_cuvid -resize 1280x720 -i input.mkv -c:a copy -vf "hwdownload,format=p010le" -c:v hevc_nvenc -pix_fmt yuv420p -rc:v vbr -cq:v 20 -qmin 20 -qmax 20 output.mkv
8.颜色偏差--HDR转SDR(tonemap_opencl)
经过前面这么多的折腾,视频已经压制好了。可是越看越不对劲。为啥我压的视频看起来灰蒙蒙的呢?经过深入调查发现是由于HDR导致的。这个视频本身是HDR的,而转换过程中ffmpeg并没有保留HDR有关的元数据(这应该是个BUG),又没进行颜色的转换。所以播放器把这个HDR视频当作SDR来处理,就会导致画面发灰。解决办法有两种,一是将其转为SDR,这需要tonemap滤镜(似乎scale滤镜也可以)。另一种是保留元数据,让播放器能够正常处理。这里选择第一种。由于tonemap是运行在cpu上的,效率低,所以我改用它的硬件加速版:tonemap_opencl
http://ffmpeg.org/ffmpeg-filters.html#tonemap_005fopenclffmpeg.org
注意下面的命令我只在linux上测试成功过,win10会报错,我也不知道为什么。
ffmpeg -hwaccel cuvid -init_hw_device opencl=ocl -filter_hw_device ocl -extra_hw_frames 3 -c:v hevc_cuvid -resize 1280x720 -i input.mkv -c:a copy -vf "hwupload,tonemap_opencl=tonemap=mobius:param=0.01:desat=0:r=tv:p=bt709:t=bt709:m=bt709:format=nv12,hwdownload,format=nv12" -c:v hevc_nvenc -rc:v vbr -cq:v 20 -qmin 20 -qmax 20 output.mkv
tonemap_opencl的这些参数中,tonemap指定了使用的算法,可选值为none
、clip
、linear
、gamma
、reinhard
、hable
、mobius
。param是用来微调这些算法的。具体的内容看ffmpeg的文档。这里最重要的是将p、t以及m都设置为了bt709。所以这个滤镜会完成以下转换:色彩原色: bt2020->bt709、传输特性:smpte2084->bt709、矩阵系数:bt2020nc->bt709 (HDR有多种不同标准,smpte2084对应的是HDR10。 经过HDR->SDR的转换,颜色终于变得正常了,不过仔细看肯定和原片有差距。可以根据画面的特色选用不同的算法和参数来进行调整,以保证画面的准确度。
9. 颜色偏差--添加HDR元数据(失败)
上一节我们将HDR转为了SDR,画面的准确度有些许丢失。那该怎么办呢?之前说到还有一种方法,那就是保留元数据。我尝试过用MKVToolNix将色彩原色、传输特性以及矩阵系数分别设置为9、16和9。然后这个视频在linux上播放正常了,但是在windows上还是灰的。我真的是很无语!!!
YouTubeHDR/hdr_metadatagithub.com
我在github上还找到了另外一个项目,叫做nv_hevc_hdr_patcher。但是这个项目看起来挺不好用的,我懒得折腾,所以HDR元数据添加宣告失败(怎么可能这么轻易放弃,下一节会用其它工具搞定这个问题(如果我还会继续写的话(会吗?)))
SK-Hardwired/nv_hevc_hdr_patchergithub.com
总结
使用FFMPEG,在尽量利用硬件加速的情况下完成了视频的压制。直接转码时会丧失HDR元数据,导致发灰(见下图中间一栏)。通过tonemap可以将HDR转为SDR视频,画面的颜色得到较为准确的还原,但还是有轻微的差别。最终也没能够完成HDR元数据的添加。
ffmpeg 参数_使用FFMPEG进行视频转码相关推荐
- ffmpeg学习(13)音视频转码(2)使用filter
ffmpeg学习(10)音视频文件muxer(1)封装格式转换 中介绍了媒体文件的封装格式转换,ffmpeg学习(11)音视频文件muxer(2)多输入混流 中介绍了音视频的混流,本文介绍基于ffmp ...
- ffmpeg命令_使用ffmpeg命令为多个短视频修改视频备注说明
今天主要给大家讲一下使用视频剪辑高手中的ffmpeg命令为多个短视频修改备注说明的详细步骤,有需要和感兴趣的宝贝们可以跟随小编一起来试试. 收集视频 将需要剪辑的短视频保存到同一文件夹上 进入软件 双 ...
- python调用ffmpeg合并_用ffmpeg命令处理mp4剪切与合并
1. 剪切: ./ffmpeg -ss 00:00:06 -t 00:00:12 -i input.mp4 -vcodec copy -acodec copy output.mp4 意思是从截取从6秒 ...
- SpringBoot 实现大文件视频转码(转码基于FFMPEG实现)
最近项目需要将用户上传的视频如果不是MP4格式,需要全部转码为MP4格式的,这里我通过FFMPeg进行大文件视频转码的实现. 一.安装FFMPeg 首先我们需要在机器上安装FFMPeg用于我们的视频转 ...
- ffmpeg webm 提取_ffmpeg简单使用教程 转码、压制、提取、截取、合并、录屏等
1.查看帮助文档 ffmpeg是一个开源的音视频转码工具 本文是自己学习ffmpeg使用方式的一个笔记 将ffmpeg命令行工具加入环境变量之后,输入ffmpeg -h打印帮助文档 PS C:\Use ...
- 七彩cms云转码_七彩CMS视频转码 2019云转码彻底开源系统版本号
源代码详细介绍 自然环境规定:nginx 1.16.2,php7.2,mariadb10.3 视頻情况一直是"已经等候转换格式",这个是因为ffmpeg沒有管理权限.视频转码要采用 ...
- 抖音短视频源码中视频排序模块热门列表解决方案
我们都知道,在短视频APP中会有推荐列表,不同短视频APP的推荐机制是不同的,有聚集流量的"中心化"推荐方式,也有对新手友好的"去中心化"推荐机制. 中心化推荐 ...
- ffmpeg 硬件解码rtsp流_树莓派使用硬件加速视频转码
现在随着智能设备普及以及宽带的升级,越来越的的视频素材在不断的产生.无论是我们自己拍摄的视频,还是从网上收集来的电影.电视剧,并不是全部都值得我们保存最高清的版本.打个比方,比如你下载了一个 1080 ...
- ffmpeg rtmp 花屏_使用FFMPEG进行视频转码
Note: 此文章首发于我的个人博客zhi-hua.wang ,开放转载但需附上出处. 使用FFMPEG进行视频转码 - 日落孤城www.zhi-hua.wang FFMPEG 是一款开源的视频处理 ...
最新文章
- Kaggle HousePrice : LB 0.11666(排名前15%), 用搭积木的方式(一,原理)
- [转]关于安卓与ios的推送系统,我说说自己的看法。
- 重置mysql密码的命令
- 【Qt】2D绘图之涂鸦板
- 买铅笔(洛谷-P1909)
- 【bzoj2929】[Poi1999]洞穴攀行 网络流最大流
- groovy 使用java类_深入学习java中的Groovy 和 Scala 类
- css3 rem的用法
- python实现通讯录的增删改查_python实现数据库增删改查
- 7月5日服务器临时维护更新公告,封印战记7月5日更新什么? 7月5日临时更新维护公告...
- 目前M院M师的教学乱象
- delphi mysql类_Delphi MySQL数据库操作类
- rhino编程语言c井,Rhino插件开发:RhinoScript脚本教程(4):VBScript基础
- CAPL基础知识学习
- 教你同时分析DPD多个单号的物流信息
- Ionic之自定义icon大小
- 计算机学院刘岗,中科院金属所刘岗研究员访问城市环境研究所
- Python 爬虫下载图片两种方法
- 普通工程师和高级工程师的差别在哪里?如何快速突破?
- 植物大战僵尸(6):查找植物叠加种植CALL
热门文章
- 重力传感器 测重力代码_“重力瀑布”如何帮助您教授孩子的密码学基础知识...
- Python实现定时任务,定时采集数据,定时执行脚本程序都可以
- 用python偷偷给班级群女同学的颜值进行排名,排最后的大姐说开学要打爆我
- LAB Color Space
- Pytorch《DCGAN模型》
- [机器学习-实践]支持向量机(SVM)从例子代码中学习
- 计算 期望与方差(mean and Variance)在 Tensorflow 与 Numpy 对比
- 0 full gc时cpu idle_Go语言中如何观察GC
- iris数据集_sklearn日志(二)训练集和测试集划分
- 混合模型简介与高斯混合模型