目录
- 一、FFmpeg 概述
- 二、FFmpeg 安装与配置
- 三、FFmpeg 核心概念
- 四、ffprobe 媒体分析
- 五、ffmpeg 命令行详解
- 六、FFmpeg 滤镜详解
- 七、流媒体与直播
- 八、FFmpeg API 编程
- 九、性能优化与最佳实践
- 十、常见问题与解决方案
- 十一、进阶主题
- 十二、总结
- 参考资源
一、FFmpeg 概述
FFmpeg 是音视频领域最强大、最流行的开源工具集,被誉为“音视频处理领域的瑞士军刀”。无论是日常的视频格式转换、音视频剪辑,还是专业的视频编解码、流媒体服务器搭建,FFmpeg 都能胜任。
FFmpeg 项目由法国程序员 Fabrice Bellard 于 2000 年发起,目前由 Michael Niedermayer 领导的团队维护。项目名称中的“FF”代表"Fast Forward",“mpeg”则来源于 MPEG 视频编码标准。经过二十多年的发展,FFmpeg 已成为音视频处理领域的基石,几乎所有商业和非商业的音视频软件都在使用 FFmpeg 的代码或技术。
1.1 FFmpeg 8.0 新特性(2025年8月发布)
2025 年 8 月发布的 FFmpeg 8.0 “Huffman” 是迄今为止最大的版本之一,主要新增特性包括:
编解码器扩展
- 新增 APV(Advanced Professional Video)原生解码器
- ProRes RAW 原生解码支持
- RealVideo 6.0 解码器
- VVC 解码器改进:IBC、ACT、Palette Mode 等
- G.728 音频解码器
硬件加速
- Vulkan 计算着色器编解码器:FFv1(编解码)、ProRes RAW(解码)
- Vulkan 硬件加速解码:VP9、VAAPI VVC、OpenHarmony H264/5
- Vulkan 硬件加速编码:Vulkan AV1、OpenHarmony H264/5
- 新增 GPU 滤镜:pad_cuda、scale_d3d11、colordetect
AI 与语音识别
- 新增 OpenAI Whisper 滤镜,支持在转码流程内直接完成语音识别与字幕生成
1.2 FFmpeg 核心组件
FFmpeg 包含多个核心组件,理解这些组件有助于深入掌握 FFmpeg:
| 组件 | 说明 |
|---|---|
| ffmpeg | 命令行工具,用于音视频编解码和格式转换 |
| ffprobe | 多媒体流分析工具,用于查看媒体文件元数据 |
| ffplay | 简单的多媒体播放器,用于测试和调试 |
| libavcodec | 编解码库,支持数百种音视频编码格式 |
| libavformat | 容器格式库,支持数十种封装格式 |
| libavfilter | 音视频滤镜库,提供丰富的处理能力 |
| libavutil | 工具库,提供通用辅助函数 |
二、FFmpeg 安装与配置
2.1 Windows 安装
Windows 平台有多种安装方式,推荐以下两种:
方式一:官方预编译版本
访问 https://ffmpeg.org/download.html 下载 Windows 构建版本,解压后将 bin 目录添加到系统 PATH 环境变量。
方式二:winget 安装(推荐)
winget install ffmpeg
安装完成后,验证安装:
ffmpeg -version
ffprobe -version
2.2 Linux 安装
Ubuntu/Debian
sudo apt update
sudo apt install ffmpeg
CentOS/RHEL
sudo yum install epel-release
sudo yum install ffmpeg
从源码编译(高级用户)
如果需要最新特性或自定义编译选项:
# 安装依赖
sudo apt install build-essential yasm nasm libass-dev libssl-dev \
libx264-dev libx265-dev libvpx-dev libmp3lame-dev libopus-dev
# 下载源码
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
# 配置编译选项
./configure --prefix=/usr/local \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libmp3lame \
--enable-libopus
# 编译安装
make -j$(nproc)
sudo make install
2.3 macOS 安装
brew install ffmpeg
三、FFmpeg 核心概念
3.1 容器与编解码器
理解音视频处理需要区分两个核心概念:
- 容器(Container/Muxer):文件的封装格式,如 MP4、MKV、AVI、MOV。容器负责存储音频、视频、字幕等流,并提供索引信息。
- 编解码器(Codec):音视频数据的压缩/解压缩算法,如 H.264、H.265、VP9、AV1、AAC、MP3。编解码器决定了压缩效率和质量。
一个常见的误解是将“MP4”视为编码格式,实际上 MP4 是容器格式,内部可以使用 H.264、H.265、AV1 等多种视频编码。
3.2 像素格式与色彩空间
视频的像素格式决定了每个像素如何存储颜色信息:
| 像素格式 | 说明 |
|---|---|
| yuv420p | 最常见的平面格式,Y 分量单独存储,U/V 分量交错存储 |
| yuv422p | 4:2:2 采样,水平方向减半 |
| yuv444p | 4:4:4 采样,无降采样 |
| rgb24 | RGB 格式存储 |
| nv12 | NVIDIA 常用的 GPU 格式 |
色彩空间(Color Space)如 BT.709(高清)、BT.601(标清)影响视频显示效果,跨设备转码时需注意色彩空间转换。
3.3 时间戳与帧率
FFmpeg 使用时间基(Time Base)来表示时间,通常以分数形式如 1/1000 表示毫秒级精度。帧率(Frame Rate)如 30fps、60fps 表示每秒帧数,在转码时可以通过调整帧率来控制视频流畅度和文件大小。
四、ffprobe 媒体分析
4.1 基本用法
ffprobe 是分析媒体文件的利器,可以获取视频的编码信息、时长、分辨率、码率等关键数据:
# 基本信息输出
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
# 简洁信息
ffprobe input.mp4
# 只显示视频流信息
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,bit_rate -of csv=p=0 input.mp4
4.2 常用输出格式
# 输出为 JSON(适合程序解析)
ffprobe -print_format json -show_format input.mp4
# 输出为 CSV(适合数据分析)
ffprobe -print_format csv -show_format input.mp4
# 输出为 INI 风格
ffprobe -print_format ini input.mp4
4.3 关键参数说明
| 参数 | 说明 |
|---|---|
| -v quiet | 静默模式,只输出指定内容 |
| -print_format | 指定输出格式(json/csv/ini) |
| -show_format | 显示格式信息(时长、码率等) |
| -show_streams | 显示所有流信息 |
| -select_streams | 选择特定流(v:0 视频流,a:0 音频流) |
五、ffmpeg 命令行详解
5.1 基本语法
ffmpeg 的基本语法结构:
ffmpeg [全局选项] -i 输入文件 [编解码选项] -f 输出格式 输出文件
一个简单的示例:
ffmpeg -i input.mp4 -c:v libx264 -preset fast -crf 23 output.mp4
这条命令将输入视频重新编码为 H.264,使用快速预设,CRF 值为 23。
5.2 常用参数分类
输入/输出选项
| 参数 | 说明 |
|---|---|
| -i | 指定输入文件 |
| -y | 覆盖输出文件(不询问) |
| -n | 不覆盖输出文件 |
| -t | 指定时长(秒或 HH:MM:SS 格式) |
| -ss | 跳转到指定位置 |
视频编码选项
| 参数 | 说明 |
|---|---|
| -c:v | 指定视频编码器 |
| -b:v | 视频码率 |
| -crf | CRF 质量控制(值越小质量越高) |
| -preset | 编码预设(ultrafast/superfast/veryfast/faster/fast/medium/slow/slower/veryslow) |
| -tune | 调优参数(film/animation/grain/stillimage/psnr/ssim) |
音频编码选项
| 参数 | 说明 |
|---|---|
| -c:a | 指定音频编码器 |
| -b:a | 音频码率 |
| -ar | 音频采样率 |
| -ac | 音频声道数 |
5.3 常见应用场景
1. 格式转换
# MP4 转 MKV
ffmpeg -i input.mp4 -c copy output.mkv
# AVI 转 MP4(H.264 编码)
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
# WebM(VP9 + Opus)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -c:a libopus output.webm
# MOV 转 FLV
ffmpeg -i input.mov -c copy output.flv
2. 视频压缩
# CRF 方式压缩(推荐)
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -c:a aac -b:a 128k output.mp4
# 指定码率压缩
ffmpeg -i input.mp4 -b:v 1M -b:a 128k output.mp4
# H.265 压缩(更高压缩率)
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
# AV1 压缩(最新编码,压缩率最高)
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 output.mkv
3. 分辨率调整
# 缩放到 720p
ffmpeg -i input.mp4 -vf scale=-2:720 -c:a copy output.mp4
# 缩放到指定宽度(自动计算高度)
ffmpeg -i input.mp4 -vf scale=1280:-2 output.mp4
# 缩放到 50%大小
ffmpeg -i input.mp4 -vf scale=iw/2:ih/2 output.mp4
# 指定输出尺寸并保持宽高比
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4
4. 视频剪辑
# 剪切前 60 秒
ffmpeg -i input.mp4 -t 60 -c copy output.mp4
# 从第 30 秒开始剪切,剪切 60 秒
ffmpeg -i input.mp4 -ss 30 -t 60 -c copy output.mp4
# 剪切指定时间段
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:03:00 -c copy output.mp4
5. 提取音视频
# 提取视频流(无音频)
ffmpeg -i input.mp4 -c:v copy -an output.mp4
# 提取音频流(无视频)
ffmpeg -i input.mp4 -c:a copy -vn output.aac
# 提取视频为 GIF
ffmpeg -i input.mp4 -vf "fps=15,scale=320:-1" output.gif
6. 音频处理
# 提取音频
ffmpeg -i input.mp4 -vn -c:a copy output.aac
# 转码音频
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3
# 调整采样率
ffmpeg -i input.mp4 -ar 44100 output.mp4
# 合并音视频
ffmpeg -i video.mp4 -i audio.aac -c copy output.mp4
7. 添加水印
# 添加图片水印
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" output.mp4
# 添加文字水印
ffmpeg -i input.mp4 -vf "drawtext=text='Hello':fontsize=24:fontcolor=white:x=10:y=10" output.mp4
8. 视频拼接
# 方法一:concat 协议(适合有相同编码的 AVI/MP4)
ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4
# 方法二:concat 滤镜(更通用)
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
# filelist.txt 内容:
# file 'input1.mp4'
# file 'input2.mp4'
# file 'input3.mp4'
9. 视频旋转
# 旋转 90 度
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
# 旋转 180 度
ffmpeg -i input.mp4 -vf "transpose=2,transpose=2" output.mp4
# 水平翻转
ffmpeg -i input.mp4 -vf "hflip" output.mp4
# 垂直翻转
ffmpeg -i input.mp4 -vf "vflip" output.mp4
10. 视频截图
# 截取单帧
ffmpeg -i input.mp4 -ss 00:01:30 -vframes 1 screenshot.jpg
# 每秒截图
ffmpeg -i input.mp4 -vf fps=1 screenshot_%04d.jpg
# 截取多帧
ffmpeg -i input.mp4 -vf "select=eq(n\,100)" -vframes 1 frame.jpg
5.4 高级参数
强制关键帧
# 每秒一个关键帧
ffmpeg -i input.mp4 -g 60 -keyint_min 60 output.mp4
# 每 5 秒一个关键帧(假设 30fps)
ffmpeg -i input.mp4 -g 150 -keyint_min 150 -sc_threshold 0 output.mp4
双通转码(两次编码,更高质量)
# 第一遍:分析并生成映射文件
ffmpeg -i input.mp4 -pass 1 -f rawvideo -y /dev/null
# 第二遍:使用映射文件编码
ffmpeg -i input.mp4 -pass 2 -c:v libx264 -preset slow -crf 20 -c:a copy output.mp4
硬件加速编码
# NVIDIA GPU 加速(H.264)
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p7 -cq 23 output.mp4
# NVIDIA GPU 加速(H.265)
ffmpeg -i input.mp4 -c:v hevc_nvenc -preset p7 -cq 28 output.mp4
# Intel QSV 加速
ffmpeg -i input.mp4 -c:v h264_qsv -preset fast -look_ahead 1 output.mp4
# macOS VideoToolbox 加速
ffmpeg -i input.mp4 -c:v h264_videotoolbox -b:v 5M output.mp4
流映射
# 只保留视频流
ffmpeg -i input.mkv -map 0:v -c copy output.mp4
# 只保留第一个音频流
ffmpeg -i input.mkv -map 0:a:0 -c copy output.mp4
# 多个输入的流映射
ffmpeg -i video.mp4 -i audio.mp3 -map 0:v -map 1:a -c copy output.mp4
六、FFmpeg 滤镜详解
6.1 滤镜链语法
滤镜(Filter)是 FFmpeg 最强大的功能之一,可以使用 -vf(视频滤镜)或 -af(音频滤镜)参数:
ffmpeg -i input.mp4 -vf "scale=1280:720,rotate=90" output.mp4
多个滤镜用逗号分隔,形成滤镜链(Filterchain)。如果有多个输入输出,需要使用 -filter_complex。
6.2 常用视频滤镜
缩放与裁剪
# 缩放
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4
# 保持宽高比缩放
ffmpeg -i input.mp4 -vf "scale=1280:-1" output.mp4
# 裁剪
ffmpeg -i input.mp4 -vf crop=1920:1080:0:0 output.mp4
# 裁剪中心区域
ffmpeg -i input.mp4 -vf "crop=w=1920:h=1080" output.mp4
色彩调整
# 亮度调整
ffmpeg -i input.mp4 -vf eq=brightness=0.2 output.mp4
# 对比度调整
ffmpeg -i input.mp4 -vf eq=contrast=1.5 output.mp4
# 饱和度调整
ffmpeg -i input.mp4 -vf eq=saturation=2 output.mp4
# 色彩平衡
ffmpeg -i input.mp4 -vf colorbalance=rs=0.3:gs=0:-0.3 output.mp4
# 转换为灰度
ffmpeg -i input.mp4 -vf hue=s=0 output.mp4
视频效果
# 锐化
ffmpeg -i input.mp4 -vf unsharp=5:5:1.0:5:5:0.0 output.mp4
# 模糊
ffmpeg -i input.mp4 -vf boxblur=2:1 output.mp4
# 叠加(画中画)
ffmpeg -i main.mp4 -i pip.mp4 -filter_complex "[0:v][1:v]overlay=10:10[out]" -map "[out]" output.mp4
# 淡入淡出
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=2,fade=t=out:st=8:d=2" output.mp4
音视频同步
# 调整音视频同步
ffmpeg -i input.mp4 -itsoffset 1.5 -i input.mp4 -map 0:v -map 1:a -c copy output.mp4
6.3 常用音频滤镜
# 调整音量
ffmpeg -i input.mp4 -af volume=0.5 output.mp4
# 音频淡入淡出
ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=5,afade=t=out:st=55:d=5" output.mp4
# 音频降噪
ffmpeg -i input.mp4 -af anlmdn=s=25:p=0.8:m=30 output.mp4
# 音频均衡器
ffmpeg -i input.mp4 -af "equalizer=f=1000:t=h:width_type=s:width=200:g=-10" output.mp4
6.4 滤镜表达式
FFmpeg 滤镜支持变量和表达式,可以实现动态效果:
# 根据帧号添加帧号水印
ffmpeg -i input.mp4 -vf "drawtext=text='%{frame_num}':start_number=0:x=10:y=10" output.mp4
# 渐变透明背景
ffmpeg -i input.mp4 -vf "color=c=black:s=1280x720:d=10[bg];[bg][0]overlay=format=auto:x=0:y=0" output.mp4
七、流媒体与直播
7.1 推流到 RTMP 服务器
# 推流到 RTMP 服务器
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -tune zerolatency \
-f flv rtmp://live.example.com/live/stream_key
参数说明:
-re:按原始帧率读取输入(实时推流需要)-tune zerolatency:优化延迟
7.2 拉流并转码
# 拉取 RTMP 流并转码后推送
ffmpeg -i rtmp://live.example.com/live/stream -c:v libx264 -c:a aac \
-f flv rtmp://output.example.com/live/output
# 拉取 HLS 流
ffmpeg -i https://example.com/stream.m3u8 -c copy output.mp4
7.3 SRT 协议支持
SRT(Secure Reliable Transport)是新一代低延迟传输协议:
# 推送 SRT 流
ffmpeg -re -i input.mp4 -c:v libx264 -preset fast -f mpegts srt://192.168.1.100:8888
# 拉取 SRT 流
ffmpeg -i srt://192.168.1.100:8888 -c copy output.mp4
7.4 HLS 流媒体输出
# 生成 HLS 流
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f hls -hls_time 4 \
-hls_playlist_type vod -hls_segment_filename stream_%03d.ts \
stream.m3u8
7.5 WebRTC 输出
# 输出到 WebRTC(需要支持 WebRTC 的后端)
ffmpeg -re -i input.mp4 -c:v libx264 -preset fast -tune zerolatency \
-f WebRTMP -insert_srt_pkt_info 1 -fmp4 \
webrtc://127.0.0.1:8000/stream
八、FFmpeg API 编程
8.1 开发环境配置
C/C++ 开发
安装 FFmpeg 开发库:
# Ubuntu
sudo apt install libavcodec-dev libavformat-dev libavfilter-dev libavutil-dev libswscale-dev
# macOS
brew install ffmpeg
# Windows
# 下载 ffmpeg-full-shared 或 ffmpeg-full-dev 包
CMake 配置:
find_package(PkgConfig REQUIRED)
pkg_check_modules(FFMPEG REQUIRED libavcodec libavformat libavfilter libavutil libswscale)
include_directories(${FFMPEG_INCLUDE_DIRS})
target_link_libraries(your_target ${FFMPEG_LIBRARIES})
8.2 核心数据结构
// 主要数据结构
AVFormatContext // 封装格式上下文
AVCodecContext // 编解码器上下文
AVCodec // 编解码器
AVStream // 流(视频/音频/字幕)
AVPacket // 包数据
AVFrame // 解码后的帧数据
8.3 视频转码示例
以下是一个完整的视频转码示例:
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
int transcode_video(const char *input_path, const char *output_path) {
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVPacket *pkt = NULL;
AVFrame *frame = NULL;
int ret = 0;
int video_stream_idx = -1;
// 打开输入文件
ret = avformat_open_input(&ifmt_ctx, input_path, NULL, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
// 获取流信息
ret = avformat_find_stream_info(ifmt_ctx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream info\n");
goto end;
}
// 查找视频流
for (unsigned int i = 0; i < ifmt_ctx->nb_streams; i++) {
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_idx = i;
break;
}
}
if (video_stream_idx == -1) {
av_log(NULL, AV_LOG_ERROR, "Cannot find video stream\n");
ret = -1;
goto end;
}
// 打开输出文件
ret = avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, output_path);
if (ret < 0 || !ofmt_ctx) {
av_log(NULL, AV_LOG_ERROR, "Cannot create output context\n");
goto end;
}
// 创建输出流
AVStream *out_stream = avformat_new_stream(ofmt_ctx, NULL);
if (!out_stream) {
av_log(NULL, AV_LOG_ERROR, "Cannot create output stream\n");
ret = -1;
goto end;
}
// 复制编解码器参数
AVStream *in_stream = ifmt_ctx->streams[video_stream_idx];
ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot copy codec parameters\n");
goto end;
}
// 打开输出文件
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
ret = avio_open(&ofmt_ctx->pb, output_path, AVIO_FLAG_WRITE);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open output file\n");
goto end;
}
}
// 写入文件头
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing header\n");
goto end;
}
// 初始化包和帧
pkt = av_packet_alloc();
frame = av_frame_alloc();
// 读取和转码
while (1) {
ret = av_read_frame(ifmt_ctx, pkt);
if (ret < 0) break;
if (pkt->stream_index != video_stream_idx) {
av_packet_unref(pkt);
continue;
}
// 简单复制(可用 FFmpeg API 进行编解码转换)
pkt->stream_index = out_stream->index;
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing frame\n");
break;
}
}
// 写入文件尾
av_write_trailer(ofmt_ctx);
end:
av_packet_free(&pkt);
av_frame_free(&frame);
avformat_close_input(&ifmt_ctx);
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
return ret;
}
8.4 Python 调用 FFmpeg
使用 Python 的 subprocess 模块调用 FFmpeg:
import subprocess
import shlex
def run_ffmpeg(command: str) -> subprocess.CompletedProcess:
"""执行 FFmpeg 命令"""
return subprocess.run(
command,
shell=True,
capture_output=True,
text=True
)
def convert_video(input_path: str, output_path: str, codec: str = "libx264",
crf: int = 23) -> bool:
"""视频转码"""
cmd = f'ffmpeg -i "{input_path}" -c:v {codec} -crf {crf} -c:a aac -b:a 128k "{output_path}"'
result = run_ffmpeg(cmd)
return result.returncode == 0
def get_video_info(file_path: str) -> dict:
"""获取视频信息"""
cmd = f'ffprobe -v quiet -print_format json -show_format -show_streams "{file_path}"'
import json
result = run_ffmpeg(cmd)
if result.returncode == 0:
return json.loads(result.stdout)
return {}
# 使用示例
if __name__ == "__main__":
# 转码
convert_video("input.mp4", "output.mkv")
# 获取信息
info = get_video_info("input.mp4")
print(f"时长: {info['format']['duration']}秒")
8.5 使用 ffmpeg-python 库
更优雅的 Python 调用方式:
import ffmpeg
# 视频转码
(
ffmpeg
.input('input.mp4')
.output('output.mp4', vcodec='libx264', crf=23, acodec='aac', ab='128k')
.run()
)
# 视频缩放
(
ffmpeg
.input('input.mp4')
.filter('scale', 1280, 720)
.output('output.mp4')
.run()
)
# 提取音频
(
ffmpeg
.input('input.mp4')
.output('output.mp3', acodec='libmp3lame', ab='192k')
.run()
)
# 视频剪辑
(
ffmpeg
.input('input.mp4', ss=30, t=60)
.output('output.mp4', c='copy')
.run()
)
九、性能优化与最佳实践
9.1 编码速度与质量权衡
FFmpeg 提供了多种预设来平衡编码速度与质量:
| 预设 | 编码速度 | 压缩效率 | 适用场景 |
|---|---|---|---|
| ultrafast | 最快 | 最低 | 实时编码、直播 |
| superfast | 很快 | 较低 | 快速处理 |
| veryfast | 较快 | 中等 | 一般转码 |
| faster | 快 | 中等 | 批量处理 |
| fast | 中等 | 较好 | 常用预设 |
| medium | 标准 | 好 | 默认值 |
| slow | 较慢 | 较好 | 高质量输出 |
| slower | 很慢 | 很好 | 高质量存档 |
| veryslow | 最慢 | 最好 | 最佳质量 |
建议:
- 直播场景:使用
-preset ultrafast或-preset veryfast - 普通转码:使用
-preset fast或-preset medium - 高质量输出:使用
-preset slow或-preset slower - 存档用途:使用
-preset veryslow
9.2 CRF 与码率控制
CRF(Constant Rate Factor)方式
CRF 是质量导向的压缩方式,值越小质量越高:
| 编码器 | 推荐 CRF 范围 | 说明 |
|---|---|---|
| H.264 (libx264) | 18-28 | 23 为默认值 |
| H.265 (libx265) | 23-33 | 28 为默认值 |
| VP9 (libvpx-vp9) | 30-40 | 31 为默认值 |
| AV1 (libaom-av1) | 30-50 | 35 为默认值 |
码率控制方式
# CBR(恒定码率)
ffmpeg -i input.mp4 -b:v 5M -maxrate 5M -minrate 5M -bufsize 10M output.mp4
# VBR(可变码率)
ffmpeg -i input.mp4 -b:v 5M -pass 1 -f rawvideo -y /dev/null
ffmpeg -i input.mp4 -b:v 5M -pass 2 output.mp4
# CQP(恒定量化参数)
ffmpeg -i input.mp4 -c:v libx264 -qp 23 output.mp4
9.3 多线程与硬件加速
多线程编码
# 使用多线程
ffmpeg -i input.mp4 -c:v libx264 -threads 8 output.mp4
# 自动检测最优线程数
ffmpeg -i input.mp4 -c:v libx264 -threads 0 output.mp4
硬件加速
# NVIDIA CUDA
ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4
# Intel Quick Sync Video
ffmpeg -hwaccel qsv -i input.mp4 -c:v h264_qsv output.mp4
# VideoToolbox (macOS)
ffmpeg -hwaccel videotoolbox -i input.mp4 -c:v h264_videotoolbox output.mp4
9.4 性能监控
# 显示编码统计信息
ffmpeg -i input.mp4 -c:v libx264 -preset slow -pass 1 -f null -
ffmpeg -i input.mp4 -c:v libx264 -preset slow -pass 2 -stats output.mp4
# 实时显示编码进度
ffmpeg -i input.mp4 -progress pipe:1 -c:v libx264 output.mp4 | head -n 20
十、常见问题与解决方案
10.1 视频方向问题
手机拍摄的视频方向不正确:
# 自动检测并旋转
ffmpeg -i input.mp4 -c copy -metadata:s:v rotate=0 output.mp4
# 强制旋转
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
10.2 音视频不同步
# 延迟音频
ffmpeg -i input.mp4 -itsoffset 1.0 -i input.mp4 -map 0:v -map 1:a -c copy output.mp4
# 延迟视频
ffmpeg -i input.mp4 -itsoffset -1.0 -i input.mp4 -map 0:a -map 1:v -c copy output.mp4
10.3 码率控制问题
文件体积过大或质量不佳:
# 两遍编码(更精确的码率控制)
ffmpeg -i input.mp4 -pass 1 -c:v libx264 -b:v 5M -f mp4 -y /dev/null
ffmpeg -i input.mp4 -pass 2 -c:v libx264 -b:v 5M -c:a aac -b:a 192k output.mp4
10.4 编码器不支持
某些编码器需要安装额外库:
# 安装 x264
sudo apt install libx264-dev
# 安装 x265
sudo apt install libx265-dev
# 安装 VP9
sudo apt install libvpx-dev
# 安装 AAC
sudo apt install libfdk-aac-dev
# 重新编译 FFmpeg
./configure --enable-libx264 --enable-libx265 --enable-libvpx --enable-nonfree
十一、进阶主题
11.1 自定义滤镜开发
开发自定义滤镜需要使用 FFmpeg 的 Filter API:
// 滤镜结构示例
typedef struct MyFilterContext {
int width;
int height;
float brightness;
} MyFilterContext;
// 初始化滤镜
static int init(AVFilterContext *ctx) {
MyFilterContext *s = ctx->priv;
s->brightness = 0.0f;
return 0;
}
// 处理帧
static int filter_frame(AVFilterLink *inlink, AVFrame *in) {
AVFilterContext *ctx = inlink->dst;
MyFilterContext *s = ctx->priv;
AVFrame *out = ff_get_video_buffer(ctx->outputs[0], in->width, in->height);
// 处理像素数据...
av_frame_copy_props(out, in);
av_frame_free(&in);
return ff_filter_frame(ctx->outputs[0], out);
}
// 注册滤镜
static const AVFilter myfilter = {
.name = "myfilter",
.description = "My custom filter",
.priv_size = sizeof(MyFilterContext),
.init = init,
.inputs = (const AVFilterPad[]) {
{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .filter_frame = filter_frame },
{ .name = NULL }
},
.outputs = (const AVFilterPad[]) {
{ .name = "default", .type = AVMEDIA_TYPE_VIDEO },
{ .name = NULL }
},
};
11.2 容器格式深入
理解不同容器的特点:
| 容器 | 特点 | 适用场景 |
|---|---|---|
| MP4 | 兼容性最好,支持流媒体 | 通用格式、在线播放 |
| MKV | 开放格式,支持多音轨/字幕 | 高清视频、蓝光备份 |
| MOV | QuickTime 格式,编辑友好 | 视频编辑、Final Cut |
| AVI | 较老,兼容性差 | 遗留系统兼容 |
| WebM | Web 标准,配合 VP9/AV1 | Web 视频 |
| FLV | Adobe Flash,直播常用 | 直播、点播(逐渐淘汰) |
11.3 下一代编解码器
AV1
- 由开放媒体联盟(AOM)开发
- 无专利费,压缩效率最高
- 支持硬件加速(Intel/AMD/NVIDIA)
- 逐渐成为 Web 视频标准
# AV1 编码
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 35 -cpu-used 4 output.mkv
# AV1 硬件编码
ffmpeg -i input.mp4 -c:v av1_nvenc -preset p7 -cq 35 output.mkv
VVC(H.266)
- 最新视频编码标准
- 压缩效率比 H.265 提升 30-50%
- FFmpeg 8.0 已支持解码
十二、总结
FFmpeg 是音视频处理领域的瑞士军刀,功能强大且应用广泛。本文从基础概念、安装配置、命令行使用、滤镜应用到 API 编程,全面介绍了 FFmpeg 的核心知识。
关键要点回顾:
- 理解核心概念:容器与编解码器的区别,像素格式与色彩空间
- 掌握命令行:格式转换、视频压缩、剪辑、截图等常用操作
- 善用滤镜:视频缩放、色彩调整、水印、叠加等高级处理
- 性能优化:合理选择编码预设、CRF 值、硬件加速
- API 编程:通过 C/C++/Python 调用 FFmpeg 实现自动化处理
FFmpeg 8.0 带来了 Vulkan 计算着色器、AI 语音识别等新特性,建议读者持续关注项目更新。随着 AV1、VVC 等新一代编解码器的普及和硬件支持的完善,FFmpeg 将在音视频领域发挥更重要的作用。
参考资源
- 官方网站:https://ffmpeg.org
- 官方文档:https://ffmpeg.org/documentation.html
- Wiki:https://trac.ffmpeg.org/wiki
- FFmpeg 8.0 Release Notes

1119

被折叠的 条评论
为什么被折叠?



