FFmpeg 入门到精通学习指南:全面掌握音视频处理神器

目录


一、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 分量交错存储
yuv422p4:2:2 采样,水平方向减半
yuv444p4:4:4 采样,无降采样
rgb24RGB 格式存储
nv12NVIDIA 常用的 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视频码率
-crfCRF 质量控制(值越小质量越高)
-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-2823 为默认值
H.265 (libx265)23-3328 为默认值
VP9 (libvpx-vp9)30-4031 为默认值
AV1 (libaom-av1)30-5035 为默认值

码率控制方式

# 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开放格式,支持多音轨/字幕高清视频、蓝光备份
MOVQuickTime 格式,编辑友好视频编辑、Final Cut
AVI较老,兼容性差遗留系统兼容
WebMWeb 标准,配合 VP9/AV1Web 视频
FLVAdobe 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 的核心知识。

关键要点回顾

  1. 理解核心概念:容器与编解码器的区别,像素格式与色彩空间
  2. 掌握命令行:格式转换、视频压缩、剪辑、截图等常用操作
  3. 善用滤镜:视频缩放、色彩调整、水印、叠加等高级处理
  4. 性能优化:合理选择编码预设、CRF 值、硬件加速
  5. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值