1. FFmpeg初探:从命令行到核心库

说实话,我第一次接触FFmpeg是在十年前的一个视频转码项目里。那时候客户丢过来一堆格式各异的监控录像,要求统一转成MP4。我试了各种商业软件,要么收费贵得离谱,要么转出来画质惨不忍睹。后来一个老同事说:「试试FFmpeg吧,免费的。」

这一试,就再也没换过别的工具。

1.1 FFmpeg到底是什么?

FFmpeg是一个开源的多媒体处理框架。它能做视频转码、音频转码、流媒体推拉、截图、滤镜处理……几乎你能想到的所有音视频操作,它都能干。

它的名字其实挺有意思——FF代表Fast Forward,mpeg是MPEG视频标准。合起来就是「快速处理MPEG」的意思。当然现在它支持的可远不止MPEG了。

核心定位:FFmpeg不是单一工具,而是一整套多媒体处理解决方案。它包含命令行工具、开发库、以及底层编解码器集合。

1.2 三大核心组件

FFmpeg之所以强大,是因为它的架构设计非常清晰。我习惯把它的核心组件分成三块,你理解透了,后面学封装解析就轻松多了。

libavformat — 格式的「拆装师」

这个库负责多媒体容器格式的封装和解封装。说白了,就是把视频流、音频流、字幕流「装进」一个容器文件(比如MP4、MKV、FLV),或者从容器里「拆出来」。

我在做直播项目时遇到过一个问题:推流到服务器总是花屏。查了半天,发现是libavformat在封装FLV时时间戳处理有偏差。嗯,这种坑只有亲手踩过才知道疼。

libavcodec — 编解码的「发动机」

这是FFmpeg最核心的部分。它负责实际的编码和解码工作。H.264、H.265、VP9、AAC、MP3……几乎所有主流编解码器,libavcodec都支持。

我曾经对比过libavcodec和硬件编码器的性能差异。在同等码率下,libavcodec的软件编码器画质更稳定,但CPU占用确实高。怎么选?看你的业务场景。

libavutil — 工具箱

这个库提供各种辅助功能:内存管理、数学计算、数据结构、日志系统……它不直接处理音视频,但其他所有组件都离不开它。

我的建议:初学阶段不用深究libavutil的每个函数。你只需要知道它是「基础设施」就行。等后面写代码时遇到内存分配、日志打印,自然会用到它。

除了这三个核心库,还有几个重要的辅助库:

  • libswscale — 图像缩放和色彩空间转换。比如把YUV转成RGB,或者把1080p缩到720p。
  • libswresample — 音频重采样。采样率转换、声道布局调整都靠它。
  • libavfilter — 滤镜引擎。加水印、调色、裁剪……所有滤镜操作都在这里。

下面这张图能帮你快速建立整体认知:

FFmpeg核心组件架构图 FFmpeg 核心组件架构 命令行工具 (ffmpeg, ffplay, ffprobe) 核心库 (Libraries) libavformat | libavcodec | libavutil | libswscale | libswresample | libavfilter 编解码器集合 (Codecs) + 硬件加速接口 (VAAPI, CUDA, QSV) 输入 文件 / 网络流 / 设备 输出 文件 / 网络流 / 显示 数据流方向:输入 → 解封装 → 解码 → 滤镜处理 → 编码 → 封装 → 输出 FFmpeg 软件栈

1.3 编译与安装

安装FFmpeg其实很简单,但不同平台差异挺大。我分别说说。

Linux(以Ubuntu为例)

最省事的方式是用包管理器:

sudo apt update
sudo apt install ffmpeg

但这样装的可能版本比较旧。如果你需要最新版,我建议自己编译。

macOS

brew install ffmpeg

HomeBrew会帮你处理依赖,非常方便。

Windows

去官网下载编译好的二进制文件就行。或者用Chocolatey:

choco install ffmpeg

注意:包管理器安装的FFmpeg通常只包含基础功能。如果你需要特定编解码器(比如libx264、libfdk_aac),必须自己编译。

从源码编译(推荐)

我个人习惯自己编译。原因很简单——你能控制所有编译选项,还能针对自己的CPU做优化。

基本步骤:

  1. 下载源码:git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
  2. 配置:./configure --enable-gpl --enable-libx264 --enable-libfdk-aac
  3. 编译:make -j$(nproc)
  4. 安装:sudo make install

这里有个坑——编译依赖必须提前装好。比如要支持H.264编码,你得先装libx264-dev。我曾经在编译时忘了装这个,结果折腾了半天才发现。

避坑指南:编译前先跑 ./configure --help 看看有哪些选项。我一般会开启 --enable-shared,这样编译出来的动态库方便后续开发用。

验证安装

装完之后,跑一下这个命令:

ffmpeg -version

你会看到类似这样的输出:

ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 11 (Ubuntu 11.4.0-1ubuntu1~22.04)
configuration: --enable-gpl --enable-libx264 --enable-libfdk-aac
libavutil      58. 29.100 / 58. 29.100
libavcodec     60. 31.102 / 60. 31.102
libavformat    60. 16.100 / 60. 16.100
libavdevice    60.  3.100 / 60.  3.100
libavfilter     9. 12.100 /  9. 12.100
libswscale      7.  5.100 /  7.  5.100
libswresample   4. 12.100 /  4. 12.100
libpostproc    57.  3.100 / 57.  3.100

看到这些库版本号,说明安装成功了。注意看libavformat、libavcodec、libavutil这三个——它们就是我们后面课程的主角。

1.4 快速上手:第一个转码命令

装好了总得试试吧?来,把任意一个视频文件转成H.264编码的MP4:

ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mp4

这个命令的意思是:用libx264编码视频,用AAC编码音频,输出MP4文件。就这么简单。

你可能会问:「为什么选H.264和AAC?」因为这是目前兼容性最好的组合。几乎所有设备都支持。

本章小结:FFmpeg是一个强大的多媒体框架,核心组件包括libavformat(封装/解封装)、libavcodec(编解码)、libavutil(工具库)。安装方式灵活,推荐从源码编译以获得最大控制权。下一章我们会深入libavformat,看看它到底是怎么把音视频流「装」进容器的。