FFmpeg命令行转码

本文主要了解FFmpeg进行音视频编码转换。主要学习如下几个知识点:

  • FFmpeg使用libx264进行H,264(AVC)软编码,使用libx265进行H.265(HEVC)软编码
  • 使用FFmpeg在MacOS环境下硬编码
  • 了解音频编码,MP3,AAC的参数设置编码

FFmpeg软编码H.264和H.265

支持H.264的封装格式的文件格式有很多,例如FLV,MP4,HLS,TS等。FFmpeg本身不支持H.264的编码器,通过第三方库x264或者OpenH264来支持,但是OpenH264开源较晚,所以多数使用的还是x264,可以通过命令行ffmpeg -h encoder=libx264来查看x264编码的一些基本信息和参数情况。

H.264编码实例

通过上面的-h命令查看x264支持的参数真的很多,我们在要用到优化的时候可以仔细了解其参数的含义,下面的几个实例列出了一些参数的使用,简单的了解参数的含义以及使用方法。每一个参数都可以带很多不同的配置,在使用的时候查看文档

编码器预设参数preset

这个参数主要调节编码速度和质量的平衡,有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo这10个选项,从快到慢。

使用H.264转码文件

ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -b:v 2000k output.mp4

输出关键速度信息




多了一个参数-preset ultrafast 中的ultrafast表示使用最快的编码方式,默认的编码速度是medium模式的,来查看这两种模式生成的输出信息差异。

ffmpeg -i input.mp4 -vcodec libx264 -preset medium -b:v 2000k output.mp4




上面的ultrafast速度是41.1倍,使用medium速度是6。24倍但是生成的视频的画质速度低的会好一些,

编码优化参数tune

这个参数配合视频类型和视觉优化的参数。可选项

  • film:电影真人类型
  • animation:动画
  • grain:需要保留大量的grain
  • stillimage:静态图像编码时使用
  • psnr:提高psnr做了优化的参数
  • ssim:提高ssim做了优化参数
  • fastdecode:可以快速解码的参数
  • zerolatency:零延迟,用在需要非常低的延迟的情况,比如电视电话会议编码。
ffmpeg -i input.mp4 -vcodec libx264 -tune zerolatency -b:v 2000k output.mp4

profile和level设置

profile和level的设置和H.264标准文档ISO-14496-Part10描述的profile和level信息基本相同。profile有如下选项:

  • Baseline
  • Extented
  • Main
  • High
  • High10
  • High422
  • High444
    profile设置信息不同会影响编码出来的视频的很多参数不同。例如是否支持I与P分片。level也会影响很多参数,例如最大解码速度不同。

下面使用baseline profile和high profile编码一个H.264视频,分析两个编码出来的文件的区别。有一个知识我们提取了解一下baseline profile编码出来额视频不会包含B帧,而high profile包含B帧,下面就看它们B帧的差别

ffmpeg -i input.mp4 -vcodec libx264 -profile:v baseline -level 3.1 -s 352x288 -an -y -t 10 ouput_baseline.ts
ffmpeg -i input.mp4 -vcodec libx264 -profile:v high -level 3.1 -s 352x288 -an -y -t 10 ouput_high.ts

生成了两个文件,通过ffprobe来查看包含B帧的信息

ffprobe -v quiet -show_frames -select_streams v output_baseline.ts |grep "pict_type=B"|wc -l

输出0

ffprobe -v quiet -show_frames -select_streams v output_high.ts |grep "pict_type=B"|wc -l

输出161
验证了我们的理论baseline profile包含0个B帧,而high profile包含B帧。在进行实时流媒体直播时,使用包含B帧的编码更可靠些;适当加入B帧可以有效降低码率

sc_threshold

FFmpeg可以通过参数-g设置帧数间隔为GOP的长度,但是遇到场景切换的时候,从一个画面突然变为另一个画面时,会强行插入一个关键帧,这时GOP的长度会重新开始。可以通过参数sc_threshold决定是否在场景切换的时候插入关键帧。
执行命令控制编码时GOP的大小。

ffmpeg -i input.mp4 -c:v libx264 -g 50 -t 60 output.mp4

执行完毕后生成的文件每50帧被设置为一个GOP间隔。
通过软件Elecrd StreamEye查看帧信息如下:




可以看到红色框框框起来的两个I帧间隔很短,因为插入的I帧和前面的画面完全不同

看到有些GOP的间距很短,这是因为强行插入了GOP导致的,为了使GOP的插入更加均匀,使用sc_threshold设置一下:

ffmpeg -i input.mp4 -c:v libx264 -g 50 -sc_threshold 0 -t 60 output.mp4

再看GOP的帧信息如下:




拖动下面的滚动条没有发现和上面一样相隔很近的两个I帧了。

x264opts

由于FFmpeg设置x264参数时增加的参数比较多,FFmpeg开放了x264opts,可以通过这个参数设置x264的内部私有参数,如设置IBP帧的顺序以及规律。下面列举在上面生成的GOP文件数据分析基础上控制生成的文件不出现B帧,只要设置x264内部参数bframes=0即可:

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=0" -g 50 -sc_threshold 0 -t 60 output.mp4

通过StreamEye查看Stream信息没有出现B帧



如果希望控制I帧P帧B帧的频率和规律,可以通过控制GOP中B帧的帧数来实现,P帧的频率可以通过x264的参数b-adapt进行设置。
例如设置GOP中,每2个P帧之间存放3个B帧:

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=3:b-adapt=0" -g 50 -sc_threshold 0 -t 60 output.mp4

看看分析:



nal-hrd

编码可以设置VBR,CBR的编码模式,VBR为可变码率,CBR为恒定码率。互联网上VBR居多,但是我们可以使用FFmpeg制作CBR码率视频。

ffmpeg -i input.mp4 -c:v libx264 -x264opts "bframes=10:b-adapt=0" -b:v 1000k -maxrate 1000k -minrate 1000k -bufsize 50k -nal-hrd cbr -g 50 -sc_threshold 0 -t 60 output.ts

命令执行参数介绍

  • 设置B帧个数,每两个P帧之间包含10个B帧
  • 设置视频码率为1000kbit/s
  • 设置最大码率为1000kbit/s
  • 设置最小码率为1000kbit/s
  • 设置编码的buffer大小为50KB
  • 设置H.264的编码HRD信号为CBR
  • 设置每50帧一个GOP
  • 设置场景切换不强行插入关键帧
  • 设置视频输出时间为60s

可以通过工具Bitrate Viewer查看码率波动,我就没试了,通过Elecard StreamEye查看流信息的bitrate type为CBR。

FFmpeg硬编解码

以前都不知道FFmpeg可以硬编解码,以为它就只能软编解码,它真的强大。FFmpeg可以在Nvidia GPU,Intel QSV,树莓派,OS X系统下硬编解码。我使用的是OS X系统,所以下面来实验一个在该系统的硬编解码。

OS X系统硬编解码

直接看一个硬转码的实例,先把一个视频通过h264_vda硬解码,然后通过h264_videotoolbox硬编码视频文件。

ffmpeg -vcodec h264_vda -i input.mp4 -vcodec h264_videotoolbox -b:v 2000k output.mp4

结果出现错误如下:




这个错误可清楚的知道是没有安装h264_vda工具库,在前面的文章我们知道如何重新给本机的FFmpeg带参数安装一些我们要使用的库了。但是我找了可以带的–with参数,不知道解码器h264_vda属于哪个库里面的。//todo

FFmpeg输出MP3

编码MP3使用编码器libmp3lame这个库,通过命令ffmpeg -h encoder=libmp3lame可以查看它的一些参数信息。
先来看最简单的一条命令使用libmp3lame来进行音频文件编码为MP3文件。

ffmpeg -i input -acodec libmp3lame output.mp3

输出的码率类型参数设置

  • VBR:编码码率不断变化,通过参数-q:a设置
  • CBR:码率几乎不变,通过参数-b设置
  • ABR:平均码率是上面两个的结合体,使用它的参数编码速度比VBR高,质量比VBR差一点,比CBR质量好点,通过参数-abr来设置

控制码率的参数为-q:a后面带数字

FFmpeg输出AAC

AAC是一种比MP3的编码效率更高,编码音质更好的音频编码格式,常见的使用AAC编码后的文件存储格式为m4a。FFmpeg可以使用如下三种编码器

  • aac:FFmpeg自带的AAC编码
  • libfaac:第三方AAC编码器
  • libfdk_aac:第三方AAC编码器

FFmpeg使用AAC编码器

看下面最简单的例子:

ffmpeg -i input.mp4 -c:a aac -b:a 160k output.aac

同样可以使用-q:a带数值代表的码率信息进行转换

猜你喜欢

转载自blog.csdn.net/lyman_ye/article/details/80305904