Skip to content

studying-notes/ffmpeg-notes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FFmpeg 学习笔记

FFmpeg 库及其作用

  • libavcodec:提供了一系列编码器的实现。
  • libavformat:实现了流协议、容器格式和基础的 IO 访问。
  • libavutil:包括了哈希器、解码器和各种工具函数。
  • libavfilter:提供了各种音视频过滤器。
  • libavdevice:提供了访问捕获设备和回放设备的接口。
  • libswresample:实现了混音和重采样。
  • libswscale:实现了色彩转换和缩放功能。

FFmpeg 基本概念

  • 容器/文件 Conainer/File:特定格式的多媒体文件。
  • 媒体流 Stream:一种视频数据信息的传输方式,5 种流:音频,视频,字幕,附件,数据。
  • 数据帧/数据包 Frame/Packet:帧代表一幅静止的图像,分为 I 帧,P 帧,B 帧。
  • 编解码器 Codec:以帧为单位实现压缩数据和原始数据之间的相互转换,CODEC = COde(编码)+ DECode(解码)。
  • 复用 Mux / 解复用 Demux:把不同的流按照某种容器的规则放入容器,这种行为叫做复用(Mux)。把不同的流从某种容器中解析出来,这种行为叫做解复用(Demux)。
  • 帧率:帧率也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要 15 帧。
  • 码率:比特率 / 码率 / 数据率是一个确定整体视频/音频质量的参数,秒为单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用 bps 来表达。

FFmpeg 命令分类

按使用目的可以将 FFmpeg 命令分成以下几类:

  • 基本信息查询命令
  • 录制
  • 分解与复用
  • 处理原始数据
  • 滤镜
  • 切割与合并
  • 视频图像互转
  • 直播相关

除了 FFmpeg 的基本信息查询命令外,其它命令都按下图所示的流程处理音视频。

 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|

FFmpeg 调用 libavformat 库来读取输入文件并获取包含编码数据的数据包。 当有多个输入文件时,FFmpeg 会尝试通过跟踪任何活动输入流上的最低时间戳来使其保持同步。

然后将编码的数据包传送给解码器。 解码器产生未压缩的帧,可以通过滤波进一步处理。 在过滤之后,帧被传递到编码器,编码器并输出编码的数据包。 最后,这些传递给复用器,将编码的数据包写入输出文件。

FFmpeg 命令选项​​

具体命令参数详见FFmpeg 命令参数

  • 所有的数值选项中,如果不另外指明,均表示接受数值作为输入,其后可添加一个单位字符串,比如 K,M,或 G;
  • 如果 i 被附加在单位,完整的前缀将被解释为一个单元前缀的二进制倍数,也即 1024 倍,而不是 1000 倍,追加 B 可使数值增加 8 倍,比如 KB,MiB,G 和 B 的数量后缀;
  • 选项​​不带参数是布尔选项,并设置相应的值设置为 true;可以通过在选项前添加 no 来将选项设置为 false

媒体流的选择

默认情况下,FFmpeg 只包含输入文件中每种类型的一个流,并将其添加到每个输出文件中,FFmpeg 根据以下标准挑选每一个的最佳:

  • 对于视频,是具有最高分辨率的流
  • 对于音频,是具有最多 channel 的流
  • 对于字幕,是第一个字幕流
  • 在相同类型的几个流相等的情况下,选择具有最小索引的流

可以通过使用 -vn / -an / -sn / -dn 选项来禁用某些默认设置。 要进行全面的手动控制,可以用 -map 选项,该选项禁用刚描述的默认设置。

流标识符形式

流标识符被用来精确地指定一个给定的选项作用于哪一个数据流。一个标识符一般是选项名称加冒号分隔的字符串。例如 -codec:a:1 ac3 包含流标识符 a:1,它匹配第二音频流。因此,将选择 AC3 编解码器的第二音频流。

一个标识符可以匹配多个流,这个选项将适用于所有流。比如,流标识符 -b:a 128k 标识了所有的音频流。

空标识符匹配所有的流。例如, -codec copy-codec: copy 会复制所有的数据流而不重新编码。

流标识符的可能形式:

  • stream_index 匹配与该索引对应的流。例如 -threads:1 4 将设置第二个流的线程计数为 4。
  • stream_type[:stream_index] 流类型是下列字母之一:v 为视频,a 为声音,s 为字幕,d 为数据,t 为附件。如果 stream_index 给出,则它匹配该类型的索引为 stream_index 的流。否则,它匹配所有这种类型的流。
  • p:program_id[:stream_index] 如果给定 stream_index,那其将与在与ID为 program_idprogramstream_index 的流相匹配。否则,它将匹配在 program_id 中的所有流。
  • stream_id / i:stream_id 按流索引逐一匹配流。
  • m:key[:value] 匹配流的元数据标签中具有指定 key 的流。如果 value 没有给出,将匹配包含给定标签的所有流。在 ffmpeg 中,按元数据匹配仅能用于输入文件。

功能模块

封装转换

ffmpeg 的封装转换功能包含在 AVFormat 模块中,通过 libavformat 库进行 MuxDemux 操作;多媒体文件的格式有很多种,这些格式中的很多参数在 MuxDemux 的操作参数中是公用的。

转码

ffmpeg 编解码部分的功能主要是通过模块 AVCodec 来完成的,通过 libavcodec 库进行 EncodeDecode 操作。