-->
获得免费通行证,加入我们的流媒体连接-2月19日至22日; Register Now!

如何编码与FFmpeg 5.0

文章特色图片

2022年1月17日,FFmpeg发布了FFmpeg 5.0, called Lorentz. 庆祝并帮助新用户了解FFmpeg的强大功能和易用性, 我创建了这个入门级教程,用于使用FFmpeg进行单通道和双通道编码.

For the record, 对FFmpeg的许多主要更改都发生在应用程序编程接口级别, 因此,如果您从命令行驱动程序, 你看不出有什么区别. 值得庆幸的是,Lorenz没有“破坏”我从我的FFmpeg书中测试的任何命令字符串, 学习用FFmpeg制作视频:在30分钟或更少, or courses,所以希望它不会破坏其他用户的现有命令字符串. 大多数新增功能属于高级类别,不会影响本教程中显示的内容.

让我们先简单了解一下FFmpeg. Note that you can 下载本文中显示的脚本.

About FFmpeg

根据FFmpeg的About页面, “FFmpeg是领先的多媒体框架, able to decode, encode, transcode, mux, demux, stream, 过滤和播放人类和机器创造的几乎所有东西.“FFmpeg运行在Windows上, Mac OS X, Linux, 以及各种各样的其他构建环境,并且对于广泛的活动非常有用.

例如,我学习FFmpeg是为了支持我书中的实验, 视频编码的数字:消除猜测从您的流媒体视频,其中涉及数千个编码,以确定H的最佳编码参数.264, HEVC, and VP9. 尝试执行此测试, 以及相关的质量测量, 使用一个或多个应用程序会非常麻烦.

Beyond encoding, FFmpeg还提供了一系列有用的功能, 比如在不重新编码的情况下改变容器格式, 在不重新编码的情况下提取文件部分, 缩放文件到不同的分辨率, 所有这些都构成了我的文章, "发现你不能没有的六个FFmpeg命令,是流媒体上最受欢迎的文章之一. 而不是专注于随机的任务, 本教程将带您了解使用FFmpeg进行编码的基础知识, 基本上是在回顾我的学习历程 数字编码.

有很多教程可用于在您选择的平台上安装FFmpeg. 这里是安装的链接 Windows, Mac, and Linux.

所有这些教程都是为以前版本的FFmpeg编写的, 但如果你下载了ffmpeg5,它们应该仍然可以工作.0. 因此,在您选择的操作系统上安装FFmpeg,让我们开始吧.

关于命令行处理

当您第一次开始使用FFmpeg时,您可能会通过命令行工作. 您将构建一个命令行“参数”或“脚本”,其中包含告诉FFmpeg如何编码的不同配置选项或“开关”. 您可以在命令或终端窗口中直接或通过批处理文件将这些参数提供给FFmpeg, 它们是基于文本的文件,包含一个或多个可以从命令窗口或Windows百家乐软件管理器运行的命令行参数.

当您尝试配置选项时, 您通常会将命令直接输入到命令窗口中. 设置好配置后,您可能会创建一个批处理文件来对多个文件进行编码.

In most, but not all, instances, FFmpeg命令行参数适用于所有操作系统. 一个值得注意的例外是两步编码的命令语法, Windows和Mac/Linux有什么不同. 稍后我会讲到.

However, Windows和Mac/Linux批处理文件之间有许多细微的差异,你需要了解这些差异. 我将在本文中介绍命令字符串, 但不包括如何为任何操作系统创建批处理文件.

Figure 1. 最基本的FFmpeg编码脚本(点击查看大图)

开始使用FFmpeg

Figure 1 显示了最基本的FFmpeg编码脚本, 在哪里指定输入文件, 命名输出文件, 并选择视频编解码器.

在部署此脚本时, FFmpeg对编码应用许多默认设置, 部分显示在 Figure 2. 我说“部分”是因为应用的默认值比显示的要多得多, 尽管图2包含了我们将在本教程中考虑的配置选项.

Figure 2. 输出(点击查看大图)

当您没有指定数据速率时, 就像我在图1中没有做的那样, FFmpeg采用恒定速率因子(CRF)编码技术,其值为23, 哪个应该以最小的比特率提供非常好的质量. 在没有其他方向的情况下, FFmpeg将关键帧间隔设置为250, 这个24帧/秒的文件大约需要10秒, 并保持分辨率和帧率与源相同. 除非在命令字符串中另行指定,否则FFmpeg将使用H.264's High H.264配置文件和Medium预设.

顺便说一下背景, 预设控制了许多编码参数,使制作人能够选择编码速度和编码质量的理想平衡. In Figure 2, 你可以看到Medium预设使用了三个b帧和三个参考帧, 但是还有更多的参数没有显示出来,这些参数是由预设控制的. Check out go2sm.com/x264 查看使用x264预设控制的所有配置选项.

如果您更改预设,您可能会更改其中的一些选项. Or, 您可以通过在命令字符串中为该配置选项指定不同的值来覆盖预设控制的值. So, if you added refs=1 到您的命令字符串, FFmpeg将使用带有一个参考帧而不是三个参考帧的Medium预设. 我并不是说你需要调整这些设置. 然而,通常在我的编码中,我接受大多数(如果不是全部的话)预设值.

继续讲音频, 当您选择x264编解码器, FFmpeg使用AAC音频压缩, 哪个是x264视频编码的默认值. FFmpeg保持与源文件相同的音频通道和采样,并应用128Kbps的比特率.

要记住的关键是这些默认值简化了编码. So, 如果要以源分辨率和帧速率进行编码, 你可以使用High profile和Medium预设, 您不需要在命令行中包含任何这些配置选项的开关. 如果默认的音频参数是OK的, 您不必在命令行中包含任何音频开关, 我的大多数命令行参数都没有.

In most instances, 只有在不需要使用默认开关时,才会在命令字符串中插入开关. 当您为自适应比特率(ABR)流进行编码时,就会出现这种情况,因为250的关键帧(或i帧)间隔是行不通的. 要更改此设置并实现所需的设置, 您需要在为ABR交付生成的文件创建的每个命令字符串中插入开关.

设置FFmpeg的i帧间隔

x264编解码器在编码过程中使用三种不同的帧类型:i帧、b帧和p帧. I-frames are self-contained frames that must appear at the start of a file or file segment; otherwise, 他们可能玩得不正确. 在ABR播放期间,播放器检索多个文件段并按顺序播放它们. So, 编码过程中的一个关键要求是确保每个片段中的第一帧是i帧.

To accomplish this, 你必须有正规的i型框架, i帧间隔必须均匀地分成段大小. So, 如果你的片段是6秒长, 你的i帧间隔必须是1, 2, 3, or 6, 2是最常用的.

要以2秒的间隔插入i帧,请使用如下所示的开关 Figure 3. The first switch, -g,将i帧间隔设置为48帧,或者对于这个24 fps的源文件设置为2秒.

Figure 3. 选择i帧间隔(点击查看大图)

However, by default, FFmpeg将在场景变化时插入i帧, 这可能会中断每48帧i帧的放置. 为了防止这种情况,我设置了 -keyint_min to 48 and the -sc_threshold (场景变化阈值)为0.

Figure 4 显示我刚刚在Telestream的Switch中编码的文件的GOP视图, 白色的i型框架, P-frames in purple, 和蓝色的b框. 你可以看到i帧间隔是48,没有中间的i帧, 所以我们完成了我们的目标.

Figure 4. 以下是在Telestream的Switch中显示的i帧间隔为48的编码文件(点击查看大图)

请注意,FFmpeg几乎总是提供完成任何任务或目标的多种方法. For example, 有一些命令序列可以在场景变化时插入i帧,并在所需的间隔内保持i帧. 我只是觉得,在大多数情况下,这种质量上的差异是不值得麻烦的, simple is better.

让我们一次处理几个开关,就像处理编码阶梯上较低的梯级一样. If, for example, 你的目标是通过3G连接的老式iphone, 您可能希望将分辨率降低到270,帧率降低到12 fps(24秒速率的一半),并使用Baseline配置文件来实现播放兼容性. 要完成所有这些,您需要添加如图所示的开关 Figure 5 到底部显示的命令字符串.

Figure 5. 在编码阶梯上创建较低的梯级(点击查看大图)

你可以在右边的媒体信息中看到我们已经实现了目标参数, 虽然数据速率有点高. 现在是解决比特率控制和双通道编码的时候了.

FFmpeg比特率控制

到目前为止,每个文件的比特率都是默认设置的 CRF=23 当命令行中没有数据速率配置时使用的开关. Let's fix that. Figure 6 显示影响视频比特率的三个开关.

Figure 6. 设置视频比特率(点击查看大图)

You can see that -b:v 设置视频比特率. 如果您不关心数据在文件中的分布方式, you can just use this switch; you don't need the other two.

顾名思义, -maxrate 设置文件的最大视频比特率. 如图6所示, 如果您试图生成恒定比特率(CBR)编码的文件, 将最大值设置为与目标速率相同的速率. 对于200%受限可变比特率(VBR)编码,可以将最大值设置为目标的两倍.

The -bufsize 开关设置视频缓冲验证器(VBV)的大小,您可以在 go2sm.com/vbv. As a general rule, 较大的VBV尺寸提供稍高的质量, 还有更大的比特率可变性. 如果你想控制比特率, 就像对CBR编码一样, 你应该保持VBV缓冲区较小, 1秒是一个很好的经验法则. 如果比特率可变性不是一个问题, 而对于200%受限VBR来说通常不是这样, 你可以把这个数字翻倍.

在FFmpeg双通道编码

当您使用两个通道时,VBR编码效果最好:一个用于扫描和测量文件不同部分的编码复杂性,另一个用于执行实际编码. Figure 7 显示了实现此功能的命令序列以及Windows和Mac/Linux之间第一次传递的差异.

Figure 7. 在Windows中实现两步编码(点击查看大图)

您可以在幻灯片中看到对新开关的解释. 在第一行,你加了a -y 告诉FFmpeg覆盖任何现有的日志文件. Otherwise, 如果您之前在该文件夹中执行了两次编码,并且存在日志文件, 或者以批处理模式对多个文件进行编码, FFmpeg将暂停并询问是否要覆盖现有的日志文件. 如果你离开办公室时觉得自己安排了一个高效的编码之夜, 明天早上你会非常失望的.

Then you add -pass 1 告诉FFmpeg这是第一次 -f mp4 为了确定您将在第二步中生成的输出格式,以及 NUL &&\ 告诉FFmpeg创建包含第一次传递信息的Null文件. 两个&和斜杠告诉FFmpeg,如果第一次传递成功,就运行第二次传递.

第二个传递包含 -pass 2 告诉FFmpeg查找NUL文件并使用该信息和输出文件名.

眼尖的读者会注意到,第一次传递的命令字符串只包含 -b:v control, 而第二次传递包括所有三个与数据速率相关的命令, 这样就回避了这个问题, 每次传递需要执行哪些命令? 这是一个复杂的问题,超出了本教程的范围. For now, 假设可以安全地部署数据速率参数,如下所示, 但是对于其他配置选项, 最安全的做法是将它们包含在两个通道中.

FFmpeg音频参数

如果您需要在文件中指定音频参数, 比如将立体声改为单声道,或者将数据速率设置为128Kbps以下, 您可以使用中显示的控件 Figure 8. 使用这些来选择编解码器、比特率、通道和采样率.

Figure 8. 音频控制(点击查看大图)

继续使用FFmpeg

以下是关于FFmpeg的几点. First, 前面显示的配置选项适用于大多数编解码器, 但是每个编解码器都有不同的命令. Also, FFmpeg具有很强的弹性, 如果配置选项不正确, 它通常会完成这个过程,即使这个过程没有达到你想要的效果. 但是,如果检查“命令”窗口,您可能会注意到黄色或红色的错误.

这就是你所看到的 Figure 9在那里,我把编解码器改成了VP9,它不能识别 -sc_threshold command. FFmpeg完成了第一次传递,并将完成第二次传递, 但它可能会在场景变化时插入i帧,除非你找到正确的VP9命令(没有)。. 在这种情况下,没有造成伤害,但情况可能并不总是如此. 因此,在您进行实验时,请注意命令或终端窗口.

Figure 9. 查看命令窗口中的错误,这些错误可能意味着您没有实现目标(单击查看大图)

第二点是在每次编码后检查结果. Telestream的开关, shown in Figure 4, is a fabulous tool for viewing the frame structure; Zond 265 is another.

还有一个有用的工具是MediaInfo, 它可以显示存储在ffmpeg编码文件中的与压缩相关的元数据(参见 Figure 10. 您可以在所有MediaInfo视图中看到这些数据,尽管HTML视图是最好的. 该信息允许您验证已经应用(或试图应用)的参数,并允许您查看来自其他开发人员的视频文件,以检查其编码参数.

Figure 10. 检查MediaInfo中的编码(点击查看大图)

例如,在图10中可以看到 keyint_min 设置为25,即使命令字符串请求48. 虽然这不会产生任何实际影响,因为场景更改阈值设置为0, 它表明,在将编码参数投入生产之前,始终需要验证它们.

使用FFmpeg(和所有编码器)的底线, 你不能仅仅因为编码器创建了一个文件就认为你的命令字符串是正确的. 您必须验证您的编码参数是否符合您的预期.

 [编者注:本文首次发表于2022年。 流媒体行业资料手册.]

Streaming Covers
Free
合资格订户
Subscribe Now Current Issue Past Issues
Related Articles

如何使用PowerShell和BASH为FFmpeg编写脚本

FFmpeg被设计为视频和音频录制的跨平台解决方案, conversion, 以及使用简单的静态命令行进行流式传输. 在命令字符串中使用变量和“for循环”简化了现有脚本的重用,并有助于自动化它们的操作. 虽然你不能在Windows命令窗口中使用这些脚本, 你可以在Windows上使用微软PowerShell,在Linux和Mac上使用Bash. 在本教程中,您将学习如何使用PowerShell和Bash创建和运行这样的脚本.

参加流媒体东部的5大理由

Jan Ozer将主持研讨会, presentations, 以及涵盖高级编解码器的面板, 用于远程制作的设备, WebRTC, low latency, 并于5月23日至25日在波士顿的流媒体东部上降低带宽和存储成本.

网络广播、视频会议和FFmpeg在流媒体东部的聚光灯下

Robert Reinhardt的研讨会将涵盖使用FFmpeg和管理视频会议输入和输出的最新提示和技巧, 而演示和小组讨论将着眼于将您的网络广播和事件流媒体工作提升到一个新的水平.

莫斯科国家报告:俄罗斯仍是普京的首选.264,但对HEVC和AV1有影响

好消息是:一如既往,莫斯科国立大学的编解码器研究是最全面的. 坏消息是:除非你是TikTok或腾讯,否则你无法访问一些表现最好的应用.

发现你不能没有的六个FFmpeg命令

任何进行性能或基准测试的人, 请看一下:本文中的六个命令可以帮助处理在任何工作室或编码工具中出现的基本任务.

如何自动化FFmpeg和Bento4与Bash脚本

只有一些初学者级别的脚本, 您可以使用开源工具将多个字段编码和打包为HLS和DASH输出.

开始测试的时间:FFmpeg第4轮.0和增加AV1支持

AV1提供与HEVC相同的质量,但数据速率较低. 但就目前而言,进展缓慢. 一段5秒的视频编码耗时23小时46分钟.

提及的公司及供应商