2. FFmpeg 环境搭建:工欲善其事,必先利其器
做流媒体开发,环境搭建是第一道坎。我记得刚入行那会儿,光编译 FFmpeg 就折腾了两天,各种依赖报错看得人头皮发麻。这一章我把 Windows 和 Linux 两种环境下的安装方法都捋一遍,再附上我平时最常用的命令速查表,最后聊聊 FFmpeg 的组件架构——搞懂这些,后面推流拉流才不会抓瞎。
2.1 Windows 下 FFmpeg 安装
Windows 用户图省事,直接下载编译好的二进制包就行。我个人习惯用 gyan.dev 的构建版本,更新及时,稳定性也不错。
安装步骤
- 打开浏览器,访问
https://www.gyan.dev/ffmpeg/builds/ - 下载
ffmpeg-release-full.7z或ffmpeg-release-essentials.7z(full 版包含更多编码器) - 解压到
C:\ffmpeg目录 - 将
C:\ffmpeg\bin添加到系统环境变量Path中 - 打开 cmd,输入
ffmpeg -version验证
ffmpeg.exe、ffprobe.exe、ffplay.exe 这三个文件单独复制到 C:\Windows\System32 里。这样不用配环境变量也能直接用,省事。
验证安装
C:\Users\dev> ffmpeg -version
ffmpeg version 6.1.1-full_build-www.gyan.dev
Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
看到版本信息就说明装好了。如果提示 不是内部或外部命令,多半是环境变量没生效,重启 cmd 或者重启电脑试试。
2.2 Linux 下 FFmpeg 编译安装
Linux 环境我强烈建议源码编译。为什么?因为发行版自带的 FFmpeg 通常阉割了太多功能——比如不支持 libx264、libx265,甚至没有 RTSP 协议支持。你想想看,做流媒体开发连这些都没有,那还玩什么?
编译前的依赖准备
以 Ubuntu/Debian 为例,先把依赖装齐:
sudo apt update
sudo apt install -y \
autoconf automake build-essential cmake git \
libass-dev libfreetype6-dev libsdl2-dev libtool \
libva-dev libvdpau-dev libvorbis-dev libxcb1-dev \
libxcb-shm0-dev libxcb-xfixes0-dev \
pkg-config texinfo wget zlib1g-dev \
nasm yasm libx264-dev libx265-dev libvpx-dev \
libfdk-aac-dev libmp3lame-dev libopus-dev
nasm 版本太旧,导致 x264 编码器编译失败。后来我改用 yum install nasm 升级到 2.14 以上才解决。所以编译前一定检查一下汇编器版本。
编译 FFmpeg
# 下载源码
wget https://ffmpeg.org/releases/ffmpeg-6.1.1.tar.bz2
tar -xjf ffmpeg-6.1.1.tar.bz2
cd ffmpeg-6.1.1
# 配置编译选项
./configure \
--prefix=/usr/local/ffmpeg \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libfdk-aac \
--enable-libmp3lame \
--enable-libopus \
--enable-libvpx \
--enable-libass \
--enable-libfreetype \
--enable-libvorbis \
--enable-pthreads \
--enable-version3 \
--extra-cflags="-I/usr/local/include" \
--extra-ldflags="-L/usr/local/lib"
# 编译(建议用多核加速)
make -j$(nproc)
# 安装
sudo make install
编译过程大概 10-20 分钟,取决于机器性能。我习惯把 --prefix 指定到 /usr/local/ffmpeg,这样不会污染系统自带的 ffmpeg。
配置环境变量
echo 'export PATH=/usr/local/ffmpeg/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
ffmpeg -version
验证关键编码器:
ffmpeg -encoders | grep -E "libx264|libx265|libfdk_aac"
ffmpeg -protocols | grep rtsp
如果能看到 libx264、libx265、rtsp 等输出,说明编译成功。
2.3 FFmpeg 常用命令速查
下面这张表是我平时用得最多的命令,做流媒体开发基本够用。我把它贴在工位上,省得每次都要翻文档。
| 功能 | 命令示例 | 说明 |
|---|---|---|
| 查看媒体信息 | ffprobe input.mp4 |
显示视频/音频编码、码率、分辨率等 |
| 格式转换 | ffmpeg -i input.avi output.mp4 |
自动选择编码器,最常用 |
| 提取音频 | ffmpeg -i input.mp4 -vn -acodec copy output.aac |
-vn 表示不要视频 |
| 截取片段 | ffmpeg -i input.mp4 -ss 00:01:00 -t 30 output.mp4 |
从第1分钟开始,截取30秒 |
| 缩放分辨率 | ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4 |
-vf 是视频滤镜 |
| RTSP 推流 | ffmpeg -re -i input.mp4 -c copy -f rtsp rtsp://server/live/stream |
-re 按原始帧率读取 |
| RTSP 拉流 | ffmpeg -i rtsp://server/live/stream -c copy output.mp4 |
直接保存为本地文件 |
| 屏幕录制 | ffmpeg -f gdigrab -i desktop output.mp4 |
Windows 下可用 |
| 推流到 RTMP | ffmpeg -re -i input.mp4 -c copy -f flv rtmp://server/live/stream |
直播平台常用 |
ffplay rtsp://... 拉流看看能不能正常播放。如果 ffplay 能播,那问题多半在推流端;如果 ffplay 也播不了,那就是网络或服务器的问题了。
2.4 FFmpeg 组件架构
FFmpeg 不是一个单体程序,而是一套库的集合。搞懂这些组件,你才能知道出了问题该查哪个模块。说白了,就像修车你得知道发动机、变速箱、刹车各管什么。
下面这张图是我自己画的 FFmpeg 组件架构图,把核心库和它们之间的关系理清楚了:
各组件详解
- libavformat:负责封装和解封装。说白了就是处理容器格式——MP4、FLV、TS、RTSP 流这些。我遇到过一个问题:用 FFmpeg 推 RTSP 流时,客户端一直连不上,后来发现是
-f rtsp参数没加,libavformat 默认用了 flv 格式,当然推不出去。 - libavcodec:编解码核心。H.264、H.265、AAC、MP3 这些编码器都在这里。注意,有些编码器(如 libx264)是外部库,需要编译时开启
--enable-libx264。 - libavutil:工具库。提供内存管理、数学运算、日志系统、CRC 校验等基础功能。其他所有组件都依赖它,相当于 FFmpeg 的“地基”。
- libswscale:图像缩放和色彩空间转换。比如把 1920x1080 缩到 1280x720,或者把 YUV420P 转成 RGB24。
- libswresample:音频重采样。比如把 44100Hz 的音频转成 48000Hz,或者把 16 位整型转成 32 位浮点。
- libavfilter:滤镜系统。视频缩放、裁剪、加水印、画中画,音频混音、延迟、降噪,全在这里。
一句话总结:
你输入一个视频文件,libavformat 负责拆开包装,libavcodec 负责解码里面的内容,libswscale/libswresample 负责格式转换,libavfilter 负责加特效,最后 libavcodec 重新编码,libavformat 重新打包输出。整个流程就像一条流水线,每个组件各司其职。
组件依赖关系
| 组件 | 依赖 | 说明 |
|---|---|---|
| libavformat | libavcodec, libavutil | 解封装时需要解码器信息 |
| libavcodec | libavutil | 编解码需要工具函数支持 |
| libavfilter | libavutil, libswscale, libswresample | 滤镜处理需要格式转换 |
| libswscale | libavutil | 图像处理需要内存分配 |
| libswresample | libavutil | 音频处理需要数学运算 |
--enable-network 和 --enable-protocol=rtsp。这两个选项默认是开启的,但如果你用了 --disable-everything 再手动开启某些功能,很容易漏掉网络协议支持。切记!
环境搭好了,组件也搞懂了,后面我们就可以正式开始 RTSP 推流和拉流的实战了。嗯,先把基础打牢,后面才走得稳。