作为一个 FFmpeg 初学者,给你分享我遇到的问题和发现的有趣。闲话不多说,直接看正文!走起!
FFmpeg的全称是“Fast Forward Moving Picture Expert Group”,组件由命令行应用程序和函数库两部分组成。在官网 FFmpeg 有它十分详尽的介绍说明,这里就不赘述了。通俗概括来说,FFmpeg 是一个免费的开源程序库,一个多媒体音视频处理分析工具软件,且提供命令行方式调用,专门用来编辑处理各种音视频或图像。它的源码是由 C 语言编写的,基于 Linux 系统中开发,不过在其它操作系统中都可以运行,跨平台性良好。
A complete, cross-platform solution to record, convert and stream audio and video !
由于博主电脑是基于 Windows 10 操作系统,FFmpeg 在其命令提示符 cmd 中或者 PowerShell(一种更强大的命令行工具,与 cmd 类似,但提供了更多的功能)中运行 FFmpeg 命令。如下所示:
用命令提示符 cmd 和 PowerShell 分别实现视频转格式功能
后文将以命令提示符 cmd 为载体进行操作,执行和展示 FFmpeg 命令行功能。
首先我们先去官网下载FFmpeg(官网链接 FFmpeg )
点击 Download 进入下一页面
点击微软图标然后点击下面第一个链接即可
进到这个下载页面后我们往下翻,会发现有 release builds 和 git master builds 两种下载版本。
(1)Git Master Builds 是使用最新的 FFmpeg 源代码构建的版本,可能包含最新的特性、改进和实验性质的功能,这个版本更新频率比较高,可以让用户及时体验到最新的功能和变化,但并没有经过完整的稳定性测试,因此可能存在较大的风险,包括程序崩溃、不稳定性等问题。适合开发人员、测试人员或技术爱好者用于尝试最新功能和提供反馈。
(2)Release Builds 是经过官方稳定发布的版本,经过了全面测试和验证,具有较高的稳定性,这个版本更新频率较低,不像 git master builds 那样频繁,但通常包含已经发布的功能和修复的 bug,适合用于正式的生产环境和一般用户使用。
我们作为音视频初学者那自然是使用 release builds 版本去下载,然后认准最新发布的当前version版本号即可。从下图可以发现有两种不同的构建版本:essentials_build 是一个精简版的构建,仅包含了 FFmpeg 的核心功能和基本组件,full_build 是有 FFmpeg 全部功能和可选组件,除了基本音视频处理功能外,还包括更多编解码器等工具。对于我们初学者学习 FFmpeg 的命令行使用来说,使用 essentials_build 足矣。
目前最新版本号即6.1.1,选上面两个链接任意一个下载解压即可
下载解压完毕后打开文件包,在bin文件夹中可以看到下面这些文件:
也就对应官网写明的FFmpeg的三个主要工具
这三个工具都是FFmpeg的一部分,可以在命令行下使用
(1)ffmpeg.exe :功能强大的处理音视频文件的软件,可以实现音视频的录制、转码、剪辑、合成等功能。
(2)ffplay.exe:FFmpeg自带的播放器工具,基于 SDL 与 ffmpeg 库实现,提供了音视频显示和播放相关的图像信息和音频波形信息等,可以播放本地文件或者网络流媒体。
(3)ffprobe.exe:FFmpeg自带的多媒体信息检测工具,可以获取多媒体文件的音频视频容器参数的详细信息,如分辨率、编码格式、时长等。
键盘快捷键“Windows + R”输入“cmd”点击“确定”或按回车enter键,即可打开命令提示符 cmd.exe
输入“ffmpeg -version”看看能否打印出版本号和下面一长串内容(后续会解释)
如图是已经打印成功的显示界面
如果显示“‘ffmpeg’不是内部或外部命令,也不是可运行的程序或批处理文件”说明是打印失败,需要设置环境变量,按照如下操作,十分简单清晰:
(1)右键点击“此电脑”,点击“属性”来到下面控制面板系统设置页面
这里还能查看自己电脑基本信息哦
(2)点击“高级系统设置”打开系统属性,再点击“环境变量”,选中系统变量中的“Path”点击“编辑”
一步步按说明来,不用急~
(3)在环境变量编辑页面点击“新建”,将自己存放 ffmpeg.exe 的 bin 文件夹目录复制黏贴上去
最后再点击”确定“即完成环境变量的设置啦
现在我们再测试 cmd 里能否显示这一串内容,如下图即成功,接着我们便可以开始命令行的学习认识啦~
FFmpeg 功能丰富多样且庞大,本文后半内容仅对基础命令行使用来做部分介绍。命令行方式可以实现大部分简单的音视频处理分析要求,但并不适合实际开发工作,一旦发生错误的话,通过捕捉报错 log 很难定位问题。
要系统深入学习 FFmpeg 开发一个稳定可靠的音视频处理软件或项目方案的话,还是需要使用库函数编写和调用,可以参考本人收集的这些资料推荐分享:
(1)书籍:《FFmpeg: The Complete Guide》(开发者编写,深入讲解)、《FFMPEG - From Zero to Hero》(图文并茂内容丰富)、《FFmpeg从入门到精通》(中文参考书籍)。
(2)网站:
FFmpeg官网(FFmpeg): 官方网站是学习FFmpeg的最佳资源之一,它提供了最完整详细的文档、示例、工具 以及最新的版本下载,重点关注官方文档,它提供了详细的技术参考,包括命令行选项、API文档和示例等。
FFmpeg Wiki(FFmpeg):一个社区驱动的网站,包含了丰富的文档和教程,涵盖了各种主题,从基本概念到高级技术。
FFmpeg Code Examples(GitHub - FFmpeg/FFmpeg: Mirror of https://git.ffmpeg.org/ffmpeg.git):FFmpeg代码示例存储库提供了许多实用的示例代码,涵盖了不同方面的使用。
FFmpeg 通过以下步骤实现输出转码转封装:
(1)解封装(Demuxing):在解封装阶段,FFmpeg 会读取输入文件的容器格式(例如 MP4、AVI、FLV 等),解析其中的音视频流数据和元数据信息。它会提取出音频流和视频流,并将它们拆分成独立的音频和视频数据。
(2)解码(Decoding):解码阶段是将音频和视频数据从原始的压缩格式(如 H.264、AAC 等)解码为未压缩的原始数据。FFmpeg使用适当的解码器来解析压缩的音频和视频数据,并将其还原为原始的音频样本和视频帧。
(3)编码(Encoding):在编码阶段,FFmpeg 使用选定的编码器将已解码的音频和视频数据重新编码为新的压缩格式。编码器将原始数据压缩并应用所选的编码算法,以减小文件大小并保持一定的图像质量和音频保真度。
(4)封装(Muxing):在封装阶段,FFmpeg 将重新编码的音频和视频数据合并到指定的输出容器格式中,生成最终的转码文件。输出容器格式可以是各种常见格式,如 MP4、AVI、MKV 等。封装过程还会添加必要的元数据(例如文件标签、时间戳等)以及其他附加信息。
这四个过程通常是连续进行的,每个阶段的输出将作为下一个阶段的输入。这其中需要经过6个步骤:读取输入内容、音视频解封装、解码每一帧音视频数据、编码每一帧音视频数据、音视频重新封装、输出到目标。
FFmpeg 提供了一系列命令行选项和库函数来实现这些过程,并允许用户根据需求自定义设置参数,以满足不同的转码需求。一般我们用 FFmpeg 是以“输入→处理→输出”的流程来理解并书写命令行的。如下所示:
ffmpeg -i C:\input.mp4 -c copy C:\output.flv 这条命令可以实现将输入文件mp4封装格式转换为flv格式。
(1)使用FFmpeg进行命令行操作需要先写“ffmpeg”。接着的“-i”简单理解就是“input”输入的意思,输入内容可以是视频、音频、图像乃至字幕等。“C:\”表示输入文件的目录位置,“input”是输入文件名,然后跟着后缀格式名。
(2)“-c”是“codec”编解码器的意思,就是告诉 FFmpeg 接下来要用什么编码器、解码器,如“-c:v h264”就是使用 H.264 视频编码器来编码输入视频流,“-c:a aac”则是用 AAC 音频编码器来编码输入音频流。简单来说,对于音视频图像,编码就是它们要以什么规则呈现,以便我们存储传送等操作,平时说的渲染、导出视频通常就是指这一过程;解码就是它们要按什么规则来解读,以便我们最终播放。“-c copy”就是复制照做原本编解码器所做的事情,所以 FFmpeg 就不用自己再来做编解码之类的工作,因此这样操作转码很快。接着后面跟输出内容,由用户自定义文件目录位置、文件名和格式名。如下所示:
输入操作也可以直接左键单击拖拽文件到命令提示符中,会自动写入目录、文件名和格式名
尽管内容看着很多还没展示完全,但这样操作能瞬间转码出视频
代码完整部分可以自行操作尝试看看,这里简单分析生成的代码各段含义:
(1)ffmpeg -i D:\桌面\SZUEA宣传视频.mp4 -c copy D:\桌面\SZUEA宣传.flv,这段命令行的意思就是使用FFmpeg工具将位于桌面的MP4视频文件SZUEA宣传视频转换为FLV格式并改名为SZUEA宣传的命令。
(2)接着展示了 FFmpeg 的版本信息和构建配置,然后列出了输入视频文件的详细信息,包括视频流和音频流的编码格式、分辨率、采样率等。
(3)接下来是输出到 FLV 格式的设置和参数以及流映射信息,在最后的输出部分显示了转换过程的进度和速度等信息。
注意:如果文件名有空格,一定要给整个文件名带上英文模式下的双引号!
好的!最基本的转码转封装格式操作我们已经了解认识了,那么接下来可以学习更多丰富有趣的命令行了!(多尝试一些会发现尊嘟很好玩很有意思的!拿 FFmpeg 做简单的剪辑创作也是完全足够的!)
但在此之前,我们还是先补充了解下关于音视频字幕以及轨道流等概念,再更好展开命令行的认识。
Tips:本文后续为统一直观,书写命令行时默认目录表示为C:\而输入内容名表示为 in,输出内容名为 out。
(1)平常我们下资源或者找字幕的时候,看到诸如“外挂中字”“内挂”“内封”“内嵌中英”等字眼,还有一些像“硬嵌”“硬压”“软压”“硬字幕”“软字幕”的说法,这都和压制字幕有关。压制字幕,简单理解就是用什么方法把字幕放进视频里,便于播放的时候一起看,常分为以下几种形式:
字幕外挂,指的是字幕作为一个独立的文件随着视频文件一起配套传输。一般只要字幕文件和视频的命名相同,下载之后放一个文件夹里,播放时就会自动加载字幕。
字幕内挂/内封,是字幕文件“打包”进视频容器格式里,传输时只要一个视频文件。这时所看到的字幕,也是播放器在同时播放字幕文件,不过它被视频容器格式“装”着,而不是独立在外。
字幕内嵌,就像镶嵌一样把字幕文件“印”在视频上,有了字幕的视频不包含也不再需要字幕文件,这种情况下看到的字幕就彻彻底底是视频画面的一部分了。
(2)字幕文件格式常见有以下几种:
SRT(SubRip Subtitle)格式:SRT 格式是一种比较简单的字幕文件格式,通过时间戳来控制字幕的出现和消失时间,通常以 .srt 为扩展名。
SSA/ASS(SubStation Alpha)格式:SSA/ASS 格式是一种比较复杂的字幕文件格式,支持更多的字幕特效和布局,以 .ssa 或 .ass 为扩展名。
SUB(MicroDVD Subtitle)格式:SUB 格式是 MicroDVD 字幕格式的一种变体,与 SRT 格式类似,也是通过时间戳来控制字幕的出现和消失时间,以 .sub 为扩展名。
SUP(Blu-ray Subtitle)格式:SUP 格式是 Blu-ray Disc 字幕格式,可以支持高清视频和透明度调节等高级特性,以 .sup 为扩展名。
(1)轨道流指的是容器中的一个单独的媒体流,可以是视频、音频或字幕。视频的画面就属于“视频流”,包含了视频帧的编码数据;视频的声音或者我们听的音乐声音本身就属于“音频流”,包含了音频样本的编码数据;像下载到的字幕文件,一些mkv视频里的内挂字幕属于“字幕流”(但注意内嵌字幕属于视频流!)。
一个视频容器格式可以装载多个视频、音频、字幕文件,对于所封装的每个文件,我们称之为轨道 Track,例如第几个视频轨、音频轨、字幕轨。
(2)一个视频文件可以有多个轨道,每个轨道可以包含一个或多个流,取决于文件的内容和格式。
FFmpeg 中可识别的流类型有五种:视频 video、音频 audio、字幕 subtitle、附加数据 attachment、普通数据 data。文件中流的数量和流类型种数的极限值由文件封装格式决定。选择哪一路输入文件的哪一路流输出到哪一路输出,这个选择过程既可以由 FFmpeg 自动完成,也可以通过 “-map” 选项手动指定。
(3)常用提取轨道流的参数有以下几种:
-vn:禁止视频流输出。
-an:禁止音频流输出。
-sn:禁止字幕流输出。
因此我们可以利用这个命令参数实现静音视频、纯音频以及字幕的提取(各自只有一轨的情况下)。
提取轨道流命令行书写示例如下:
ffmpeg -i C:\in.mp4 -vn -f mp3 C:\out.mp3 :提取纯mp3音频。
ffmpeg -i C:\in.mp4 -an -c:v copy C:\out.mp4 :输出静音视频。
ffmpeg -i C:\in.mkv -vn -an -c:s copy C:\out.srt :提取纯srt字幕。
注意:-c copy操作只是对音视频流的复制处理,并不包括字幕流,对于字幕流记得加上 -c:s copy 。
(4)选定轨道流的参数 -map
在 FFmpeg 中,使用 -map 参数可以选择要从输入文件中复制的轨道流,设置所输入的流需要指向哪个新的相对应的流。参数用法为:-map [input_file_id:][stream_specifier]
input_file_id:可选参数,表示输入文件的编号,用于指定多个输入文件时的选择。默认情况下,输入文件的编号从 0 开始递增。如“-map 0”表示选择第一个输入文件的所有流(包括视频、音频和字幕)。
stream_specifier:表示要选择的轨道流的标识符,可以是流的索引号、流的类型(如 v 表示视频流,a 表示音频流,s 表示字幕流),或者其他一些标识符。下面是一些示例:
-map 0:1 表示选择第一个输入文件的第二个流作为输出流,但不确定是音频还是视频哪个轨道流。
-map 1:a 表示选择第二个输入文件的音频流作为输出流。
-map 0:v:0 表示选择第一个输入文件的第一个视频流作为输出流。
-map i:a 表示选择第 i+1 个输入文件的第一个音频流作为输出流。
选择提取、替换以及合并轨道流的命令行书写示例如下:
ffmpeg -i C:\in.mkv -map 0:s:0 -c:s copy C:\out.ass :从 mkv 格式的第一个输入文件中提取第一个字幕流,并将其复制到输出文件中,输出文件的格式为 ASS 格式。
ffmpeg -i C:\in1.mp4 -i C:\in2.mp3 -map 0:v -map 1:a -c:v copy -f mp4 C:\out.mp4 :将 in1 文件的 mp4 视频流和 in2 文件的 mp3 音频流合并,并保存到 mp4 格式的输出文件 out 中。
ffmpeg -i C:\in1.mkv -i C:\in2.mkv -map 0:s:0 -map 1 -c copy -c:s copy C:\out.mkv :将 in1 文件的字幕流,与 in2 文件的所有视频流、音频流和字幕流合并,并保存到 mkv 格式的输出文件 out 中。
注意:在使用FFmpeg进行混流时,如果视频流和音频流的时间长度不一致,FFmpeg会以时长较短的流为准进行处理。这意味着在混流过程中,会自动将较长的流按照较短的流的时长进行裁剪,以保证最终混流的结果是同步的。如果需要以其他方式处理时间长度不一致的视频和音频流,可以通过FFmpeg提供的各种选项和滤镜进行手动处理。
(5)流选择的自动选择模式下,每种类型的流只选择一路,规则如下:
音频流:选择具有最多通道的流,若多个音频流通道数相同且通道数最多,则选第一个。
视频流:选择具有最高分辨率的流,若多个视频流分辨率相同且是最高分辨率,则选第一个。
字幕流:选择第一个字幕流。注意:字幕流有文本字幕流和图形字幕流,输出格式默认的字幕编码器仅处理其支持的字幕类型。
(1)在FFmpeg中,数据包(Packet)是存储压缩编码数据的基本单位。数据包可以包含一个或多个编码帧的数据(也存在多个数据包包含一个编码帧的不同片段的情况)。
在音频编码中,通常一个数据包只包含一帧数据;但在视频编码中,由于 B 帧和 P 帧的存在,可能会出现一个数据包包含多帧数据的情况。
(2)PTS 与 DTS
显示时间戳 PTS(Presentation Time Stamp):表示将压缩帧解码后得到的原始帧的显示时间。也就是说,当媒体播放器读取一个带有PTS的数据包时,它会等待直到PTS指定的时间,然后再显示这一帧。
解码时间戳 DTS(Decoding Time Stamp):表示压缩帧的解码时间。由于 B-frames 可能依赖于后续的帧,所以需要先解码后续的帧,因此 DTS 可能较原来稍大(要等待其参考帧解码后,它才能解码)。
音频中 DTS 和 PTS 是相同的。视频中由于 B 帧需要双向预测,B 帧依赖于其前和其后的帧,因此含 B 帧的视频解码顺序与显示顺序不同,即 DTS 与 PTS 不同。当然,不含 B 帧的视频,其 DTS 和 PTS 是相同的。
(3)对于 B-frames,其 PTS 通常大于前一帧的 PTS,但 DTS 可能小于前一帧的 DTS。这是因为 B-frames 需要依赖其后面的帧来解码,因此需要先解码后面的帧。
无 B-frames 的情况:
图像类型: I P P P P P P ... I P P
DTS: 0 1 2 3 4 5 6... 100 101 102
PTS: 0 1 2 3 4 5 6... 100 101 102
有双向预测帧的情况:
图像类型: I P B B P B B ... I P B
DTS: 0 1 2 3 4 5 6 ... 100 101 102
PTS: 0 3 1 2 6 4 5 ... 100 104 102
(4)时间基(Timebase)与时间戳(Timestamp)
在 FFmpeg 中,时间基通常用分数来表示,表示一个单位时间内的时钟周期数,用于将媒体流中的时间表示为数字值,例如 1/1000 表示每毫秒的时钟周期数;时间戳通常以时间基为单位来表示,是指在视频流或者音频流中每一个数据包的时间标记,为 int64_t 类型。时间戳乘以时间基得到实际的时刻值(以秒等为单位)。
如果一个视频帧的 dts 是 40,pts 是 160,其 time_base 是 1/1000 秒,那么可以计算出此视频帧的解码时刻是第 40ms,显示时刻是第 160ms。
在 FFmpeg 中,av_q2d 是用于将时间基从 AVRational 分数形式转换为 double 双精度形式表示的函数,转换结果单位为秒,av_q2d(time_base)=每个刻度是多少秒,不难理解 pts*av_q2d(time_base) 才是帧的显示时间戳。实现形式如下所示:
static inline double av_q2d(AVRational a) {
return a.num / (double) a.den;
}
(5)三种时间基 tbr、tbn 和 tbc
不同的封装格式具有不同的时间基。在 FFmpeg 处理音视频过程中的不同阶段,也会采用下列这三种时间基:
tbn:容器时间基,值是 AVStream.time_base 的倒数,一般用于确定音视频流的时间戳 PTS。
tbc:编解码器时间基。值是 AVCodecContext.time_base 的倒数,用于解码器和编码器之间的时间基准。
tbr:从视频流中推算可知是帧率或场率(帧率的 2 倍)。
除以上三种时间基外,FFmpeg 还有一个内部时间基 AV_TIME_BASE(以及分数形式的 AV_TIME_BASE_Q),用于 FFmpeg 内部函数处理,使用此时间基计算得到时间值表示的是微秒。
(1)在 FFmpeg 中,日志系统可以帮助你调试和了解转码过程中发生的事情。
(2)命令行书写时可以使用 -loglevel 选项来设置下列日志级别
quiet:完全禁止输出。
panic:只输出紧急情况的信息。
fatal:只输出致命错误信息。
error:只输出错误信息。
warning:输出警告和错误信息(默认级别)。
info:输出一般信息和警告。
verbose:输出更详细的信息。
debug:输出调试信息。
如:ffmpeg -i input.mp4 -c:v copy -c:a copy -loglevel debug output.mp4
(3)命令行级别的日志输出
FFmpeg 可以将日志输出到标准错误(stderr)、文本文件或者其他位置。默认情况下日志输出到标准错误。
将日志输出到文件:ffmpeg -i input.mp4 -c:v copy -c:a copy -loglevel debug -report output.mp4
使用命令行重定向:ffmpeg -i input.mp4 -c:v copy -c:a copy -loglevel debug 2> ffmpeg.log
如果日志输出到文件,你可以使用文本编辑器或者命令行工具查看它;如果日志输出到标准错误,你可以在终端中直接查看。
(1)FFmpeg API 是指 FFmpeg 多媒体处理工具提供的应用程序接口,它提供了一系列的库和头文件,允许我们在开发过程中使用这些库和头文件来调用 FFmpeg 的功能,来编写自己的多媒体处理应用程序,包括音频和视频的解码、编码、转换、处理等操作,实现自定义的多媒体处理需求,如创建自定义的视频编辑工具、流媒体处理工具、音视频转码器等。
(2)FFmpeg API 包含了多个库以及各种函数,以下是一些主要的 FFmpeg API 软件开发库和功能:
libavformat:用于封装格式的读取和写入,包括解析容器格式(如MP4、AVI)并提供音视频流的信息。
libavcodec:编解码库,提供了音视频编解码器的功能,支持多种编解码格式(如H.264、AAC)。
libavfilter:用于音视频过滤器的处理,包括滤镜、裁剪、调整大小等操作,可以实现各种音视频滤镜效果。
libswscale:用于图像格式转换和缩放。
libavresample/libswresample:提供音频的重采样工具库,用于音频重采样和格式转换。
libavutil:包含了一些常用的工具函数,如数据结构、字节操作等。
libavdevice:用于音视频设备的捕获与播放。
libpostproc:音视频后处理库。
我们使用这些库和头文件来调用 FFmpeg 的功能,来编写实现更复杂稳定的音视频处理程序项目,这里先认识一下,这些我会在之后的文章中不断学习和分享~
书写命令行前需要先添加 ffmpeg 声明使用,如“ffmpeg-L”:显示许可证。
-h,-?,-help,--help [arg]:显示帮助。可以指定可选参数来打印有关特定项目的帮助。如果未指定参数arg,则仅显示基本工具选项。若指定参数,arg可能值为:
long:除了基本工具选项之外,还打印高级工具选项。
full:打印完整的选项列表,包括编码器、解码器、解复用器、复用器、过滤器等的共享和私有选项。
decoder=decoder_name:打印有关名为encoder_name的编码器的详细信息。使用-编码器获取所有编码器列表的选项。其余解码器、复用器、解复用器的格式类似。
filter=filter_name:打印有关名为filter_name的过滤器的详细信息。使用-过滤器获取所有过滤器列表的选项。
……
-version:显示查看版本(包括子模块的详细版本信息)。
-buildconf:显示构建配置,每行一个选项。
-formats:显示可用格式(包括设备)。
-filters:显示可用过滤器。
-codecs:显示支持的所有编解码器(包括视频、音频和字母编解码器)。
-protocols:显示可用的协议。
……
(更多详细命令参数见官方文档 5.2Generic options 及后续部分)
-ss:设置媒体文件的起始时间,如想要从视频的2秒开始剪切处理,我们输入“-ss 2”,如想要更精确的时间也可以,如“-ss 1:23.789”表示设置从1分23秒789毫秒开始。
-t:设置媒体文件的持续时间,用法同上面 -ss ,如“-t 0:13.234”表示持续13秒234毫秒处理文件。
-to:设置媒体文件的截止时间,用法与前两个相同,-to 和 -t 是互斥的,并且 -t 具有优先权,两者不能同时出现使用,且使用 -to 时一定要写在 -i 前面。
时间剪辑的命令行书写示例如下:
ffmpeg -ss 0:14.000 -i C:\in.mp3 -c copy C:\out.mp3 :将mp3音频文件截到从14秒整开始。
ffmpeg -ss 1:23.456 -t 15 -i C:\in.flv -c copy C:\out.mp4 :将flv视频文件从1分23秒456毫秒开始,持续15秒,顺便完成转码至mp4格式。
ffmpeg -ss 2 -to 0:16.123 -i C:\in.mp4 -c copy C:\out.mp4 :将mp4视频文件从2秒开始到16秒123毫秒结束,即保留中间14秒123毫秒部分。
通常将 -ss 、-t 和 -to 放在-i之前。这些参数用于指定输入文件的开始时间(-ss)、持续时间(-t)或结束时间(-to),因此它们需要在输入文件(-i)之前进行设置,以确保正确地应用到指定的输入文件上,以防混乱。
(1)查看每帧的信息
ffprobe -v error -show_frames C:\in.mp4:用 ffprobe 工具来分析视频文件,并显示视频中每一帧的详细信息。“-v error”设置错误输出级别为 error,只显示错误信息;“show_frames”显示视频中每一帧的信息。如下是音频帧类型,然后 key_frame=1 表示这是 IDR frame ,如果 key_frame=0 表示这是 Non-IDR frame 。
[FRAME][FRAME]之间的信息内容即为一帧详细信息
(2)截取视频中某帧
ffmpeg -ss 00:1:05 -i C:\in.mp4 -vframes 1 C:\out.jpg:从输入的mp4视频文件的1分5秒开始截取一帧图像,“-vframes 1”表示在视频流截取一帧,最后输出jpg格式图片。
(3)导出片段视频帧
ffmpeg -ss 13 -to 15 -i C:\in.mp4 C:\out%03d.png:表示导出从视频的第13秒到第15秒,这两秒内所有帧图片。“%03d”的意思是让电脑自己以3位数字从小到大依次命名输出的文件,如001.png、002.png……
视频是30帧每秒,于是截取两秒所有帧会得到如左边60张图片
视频画面码率(数据速率) + 视频声音码率(音频比特率) = 视频总码率(总比特率)
该视频大致数据速率+音频比特率 = 总比特率
如上篇文章提到,码率对视频观感影响无很决定性关系,但与视频实际质量大小有不可逆的正比关系。视频压制就是希望能按需求取舍实际质量大小,又尽可能让观感不会下降太多的操作过程。
-b:调控设置比特率,表示音视频加起来的码率大小,“-b:v”限定只设置视频画面比特率,“-b:a”限定只设置视频声音比特率,如“-b:v 2800k”表示设置视频画面比特率为2800kbps,“-b:a 200k”表示设置视频声音比特率为200kbps。
视频压制的命令行书写示例如下:
ffmpeg -i C:\in.mp4 -b:v 2000k -b:a 200k C:\out.avi :将mp4视频画面比特率定为2000kbps,声音比特率定为200kbps,并转码为avi格式。
视频压制前后的码率对比变化
FFmpeg 一般默认使用 libx264 即 H.264 来进行软编码,下面详细介绍其相关编解码参数:
-r:设置帧率,“-r 30”就是指设置视频帧率为30帧每秒。
-s:设置分辨率,“-s 1920*1080”就是指设置视频分辨率为1920*1080,可以改变分辨率来缩放视频。
-aspect:设置输出视频的宽高比(aspect ratio),“-aspect 16:9”即设置视频宽高比为16:9。当使用 -aspect 选项时,FFmpeg 会根据指定的宽高比来调整输出视频的显示比例,而不会拉伸或压缩视频内容。这对于需要确保视频在播放时以正确比例显示的情况非常有用。
-g:设置 GOP 即关键帧间隔,“-g 30”即每隔30帧设置一个关键帧。关键帧间隔较小可以提高视频编码质量但会增大文件大小,反之。
-bf:设置连续编码为B帧的个数,“-bf 3”即设置最大B帧数量为3。较大B帧数量可以提高视频压缩效率,但也可能增大解码复杂度。
-ar:设置音频采样率,“-ar 44100”即设置音频采样率为44100Hz。
-ac:设置音频声道数,“-ac 2”表示双声道,“-ac 1”表示单声道,“-ac 6”表示5.1声道。
-pix_fmt:设置视频的像素格式即颜色空间,常见像素格式有yuv420p、yuv422p、yuv444p、rgb24、bgr24和gray这些。
-crf:使用固定质量方式,范围0~51,数值越小质量越高,简单理解0是无损,51是全损,在这之间划分了52个质量等级,一般选择18~28,例如“-crf 20”。FFmpeg 中使用 CRF 参数需要借助 x264 或者 x265 编码器进行编码。具体命令行书写示例如下:
ffmpeg -i C:\in.mp4 -c:v libx264 -crf 20 -c:a copy C:\out.mp4 :-c:v libx264 表示使用 x264 编码器进行视频编码,-c:a copy 表示音频流不进行编码,直接复制到输出文件中。
-preset:预设。在FFmpeg中,预设选项是一组预定义的编码参数集合,用于指定压制方案的速度和质量,不同的预设选项在编码速度和输出质量之间取得折衷。默认情况下预设为“medium”。预设选项设置从快到慢有ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo。FFmpeg 一般看情况用 faster~slower 之间这些就足够。
-bufsize:设置视频编解码器缓冲区大小,“-bufsize 64k”即指定视频编码时的码率控制缓冲区的大小为64 kbit/s。通常情况下,视频编码器在编码过程中需要使用一个缓冲区来存储一定量的数据,以便平滑地处理不同帧之间的码率变化。通过设置 -bufsize 参数,你可以控制这个缓冲区的大小,从而影响视频编码的质量和输出结果。
ffmpeg -f gdigrab -i desktop -pix_fmt yuv420p C:\out.mp4 :这个命令使用 FFmpeg 工具来捕获 Windows 桌面并将其保存为一个 mp4 格式的视频文件。“-f gdigrab”表示使用 GDI (Graphics Device Interface) 来捕获屏幕;“-i desktop”指定要捕获的对象为desktop即桌面内容;“-pix_fmt yuv420p”指定输出视频的像素格式为 YUV 4:2:0 planar。
这样就是开始录制成功
按q键即可暂停结束录制并保存到输出目录位置,更多参数可以自定义添加完善。
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。