提示

返回博客列表

FFmpeg 实战手册:截图、GIF、剪辑、合并、加字幕——20 个高频场景一行命令搞定

FFmpeg 实战手册:截图、GIF、剪辑、合并、加字幕——20 个高频场景一行命令搞定

FFmpeg 是视频处理领域的"瑞士军刀",但它的命令行参数实在太复杂了——每次都要去 Stack Overflow 复制粘贴。本文整理了20 个最高频的视频处理场景,每个场景都给出可直接复制使用的命令,并解释每个参数的含义,让你从"复制粘贴工程师"升级为"知道自己在干什么的 FFmpeg 用户"。涵盖:精准截图、高质量 GIF、无损剪辑、TS 合并、视频拼接、加水印、加字幕、音频提取、倍速播放、格式转换、横竖屏旋转、视频压缩等。

TL;DR:FFmpeg 核心语法:ffmpeg -i 输入 [选项] 输出。关键参数速查:-ss 起始时间、-t 持续时长、-to 结束时间、-vf 视频滤镜、-c:v 视频编码、-c:a 音频编码、-preset 编码速度。两个最重要的时间参数规则:-ss-i 前是快速 seek(关键帧精度),放 -i 后是精确 seek(逐帧解码)。

目录

一、FFmpeg 基础:你必须知道的 5 个核心概念

1.1 命令结构

ffmpeg [输入选项] -i 输入文件 [编码选项] [滤镜选项] 输出文件

1.2 时间参数:-ss、-t、-to

参数 含义 示例
-ss 开始时间 -ss 00:01:30-ss 90(秒)
-t 持续时长 -t 30 截取 30 秒
-to 结束时间 -to 00:02:00 截到第 2 分钟

关键技巧:-ss 的位置决定精度和速度

# 快速但不够精确(跳到最近的关键帧)
ffmpeg -ss 00:01:30 -i input.mp4 -t 30 output.mp4

# 精确但慢(逐帧解码到指定位置)
ffmpeg -i input.mp4 -ss 00:01:30 -t 30 output.mp4

# 最佳实践:先用关键帧快速跳,再精确截取
ffmpeg -ss 00:01:25 -i input.mp4 -ss 5 -t 30 output.mp4

1.3 编码参数

参数 含义 常用值
-c:v / -vcodec 视频编码器 libx264, libx265, copy(不重新编码)
-c:a / -acodec 音频编码器 aac, libmp3lame, copy
-preset 编码速度 ultrafastfastmediumslowveryslow
-crf 质量控制(H.264) 0(无损) ~ 51(最差),默认 23,推荐 18-28
-b:v 视频码率 2M, 5000k

1.4 流映射(-map)

FFmpeg 默认只选一个视频流和一个音频流。多流文件需要手动指定:

# 选择第 2 个视频流和第 1 个音频流
ffmpeg -i input.mkv -map 0:v:1 -map 0:a:0 output.mp4

# 选择所有视频流
ffmpeg -i input.mkv -map 0:v output.mp4

1.5 copy 模式——无损处理的秘诀

# 不重新编码,直接复制流(几乎零损耗)
ffmpeg -i input.mp4 -c copy output.mp4

# 截取时也用 copy(注意:必须从关键帧开始)
ffmpeg -ss 00:01:00 -i input.mp4 -t 30 -c copy output.mp4

二、截图与缩略图

2.1 单帧截图

# 截取第 10 秒的画面
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 output.jpg

# 指定分辨率
ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 -s 1920x1080 output.jpg

2.2 定时截图(每秒一张)

# 每秒截一张图,命名 output_001.jpg, output_002.jpg ...
ffmpeg -i input.mp4 -vf fps=1 output_%03d.jpg

# 每 5 秒截一张
ffmpeg -i input.mp4 -vf fps=1/5 output_%03d.jpg

2.3 生成视频缩略图网格(联系表)

# 生成 4x4 网格的缩略图(共 16 张)
ffmpeg -i input.mp4 \
  -vf "fps=1/$(echo $(ffprobe -v error -show_entries format=duration \
    -of default=noprint_wrappers=1:nokey=1 input.mp4) / 16 | bc), \
    scale=320:-1,tile=4x4" \
  -frames:v 1 contact_sheet.jpg

2.4 用 Python 批量生成

import subprocess
import os

def generate_thumbnails(video_path, output_dir, interval=10):
    """每隔 interval 秒截取一张缩略图"""
    os.makedirs(output_dir, exist_ok=True)
    output_pattern = os.path.join(output_dir, 'thumb_%04d.jpg')

    cmd = [
        'ffmpeg', '-i', video_path,
        '-vf', f'fps=1/{interval}',
        '-q:v', '2',  # 高质量(1-31,越小越好)
        output_pattern
    ]
    subprocess.run(cmd, check=True)

三、GIF 制作与优化

3.1 基础 GIF 制作

# 将 5 秒视频转为 GIF(10fps)
ffmpeg -i input.mp4 -ss 00:00:10 -t 5 \
  -vf "fps=10,scale=480:-1:flags=lanczos" \
  output.gif

3.2 高质量 GIF(调色板优化)

# 两步法:先生成调色板,再编码(颜色更准确,体积更小)
ffmpeg -i input.mp4 -ss 00:00:10 -t 5 \
  -vf "fps=10,scale=480:-1:flags=lanczos,palettegen" \
  palette.png

ffmpeg -i input.mp4 -ss 00:00:10 -t 5 \
  -i palette.png \
  -filter_complex "fps=10,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" \
  output.gif

3.3 体积与质量平衡

参数 小体积 平衡 高质量
fps 8 12 15
scale 320 480 640
dither bayer floyd_steinberg none
# 小体积版(适合聊天表情)
ffmpeg -i input.mp4 -t 3 \
  -vf "fps=8,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse=dither=bayer" \
  small.gif

# 高质量版(适合展示)
ffmpeg -i input.mp4 -t 5 \
  -vf "fps=15,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=5" \
  high_quality.gif

四、视频剪辑与截取

4.1 精确截取一段

# 从第 1 分 30 秒开始,截取 30 秒
ffmpeg -ss 00:01:30 -i input.mp4 -t 30 -c copy output.mp4

# 截取 01:30 到 02:00
ffmpeg -ss 00:01:30 -to 00:02:00 -i input.mp4 -c copy output.mp4

4.2 删除片头片尾

# 删除前 10 秒和后 20 秒
# 先获取总时长
DURATION=$(ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4)

# 截取中间部分
ffmpeg -ss 10 -i input.mp4 -t $(echo "$DURATION - 30" | bc) -c copy output.mp4

4.3 多段截取并合并

# 创建截取列表文件 cut_list.txt
# file 'input.mp4'
# inpoint 30
# outpoint 60
# file 'input.mp4'
# inpoint 120
# outpoint 180

ffmpeg -f concat -safe 0 -i cut_list.txt -c copy output.mp4

4.4 裁剪画面(Crop)

# 从 1920x1080 的视频中裁剪中央 640x480 区域
# crop=宽:高:左上角x:左上角y
ffmpeg -i input.mp4 -vf "crop=640:480:(in_w-640)/2:(in_h-480)/2" output.mp4

# 去掉上下黑边(自动检测)
ffmpeg -i input.mp4 -vf "cropdetect=limit=0:round=2" -t 10 -f null -
# 输出示例:crop=1920:816:0:132
ffmpeg -i input.mp4 -vf "crop=1920:816:0:132" output.mp4

五、视频合并与拼接

5.1 同格式合并(无损,最快)

# 创建文件列表 concat_list.txt
# file 'part1.ts'
# file 'part2.ts'
# file 'part3.ts'

ffmpeg -f concat -safe 0 -i concat_list.txt -c copy output.ts

5.2 不同格式拼接

# 需要重新编码,统一格式
ffmpeg -i part1.mp4 -i part2.avi -i part3.mkv \
  -filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
  -map "[outv]" -map "[outa]" output.mp4

5.3 M3U8 TS 分片合并

# 方法 1:concat 协议(TS 格式兼容)
ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c copy output.ts

# 方法 2:用 concat demuxer(通过文件列表)
# 先读取 m3u8 生成列表
grep -v '^#' playlist.m3u8 | sed 's/^/file /' > ts_list.txt
ffmpeg -f concat -safe 0 -i ts_list.txt -c copy output.mp4

# 方法 3:直接下载 m3u8(推荐)
ffmpeg -i "https://example.com/playlist.m3u8" -c copy output.mp4

5.4 视频横向/纵向拼接

# 左右拼接(hstack)
ffmpeg -i left.mp4 -i right.mp4 \
  -filter_complex hstack output.mp4

# 上下拼接(vstack)
ffmpeg -i top.mp4 -i bottom.mp4 \
  -filter_complex vstack output.mp4

# 画中画(覆盖)
ffmpeg -i main.mp4 -i pip.mp4 \
  -filter_complex "[1:v]scale=320:-1[pip];[0:v][pip]overlay=W-w-10:H-h-10" \
  output.mp4

六、音频处理

6.1 提取音频

# 提取为 AAC
ffmpeg -i input.mp4 -vn -c:a aac -b:a 192k output.aac

# 提取为 MP3
ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output.mp3

# 无损提取(不重新编码)
ffmpeg -i input.mp4 -vn -c:a copy output.aac

6.2 替换音频

# 保留视频流,替换音频
ffmpeg -i video.mp4 -i audio.mp3 \
  -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 \
  -shortest output.mp4

6.3 音量调节

# 音量增大 2 倍
ffmpeg -i input.mp4 -af "volume=2.0" output.mp4

# 音量减小一半
ffmpeg -i input.mp4 -af "volume=0.5" output.mp4

# 标准化音量(EBU R128 响度标准)
ffmpeg -i input.mp4 -af "loudnorm=I=-16:LRA=11:TP=-1.5" output.mp4

6.4 去除/添加背景音乐

# 混合背景音乐(背景音乐音量 30%)
ffmpeg -i video.mp4 -i bgm.mp3 \
  -filter_complex "[1:a]volume=0.3[bgm];[0:a][bgm]amix=inputs=2:duration=first" \
  -c:v copy output.mp4

七、字幕处理

7.1 内嵌字幕(烧录到画面)

# 烧录 SRT 字幕
ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt" output.mp4

# 指定字体和样式
ffmpeg -i input.mp4 \
  -vf "subtitles=subtitle.srt:force_style='FontName=Arial,FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BorderStyle=3,Outline=2,Shadow=1'" \
  output.mp4

# 烧录 ASS 字幕(支持更丰富的样式)
ffmpeg -i input.mp4 -vf "ass=subtitle.ass" output.mp4

7.2 提取内封字幕

# 查看有哪些字幕轨
ffprobe -v error -show_entries stream=index,codec_type,codec_name:stream_tags=language \
  -of default=noprint_wrappers=1 input.mkv

# 提取第 2 条字幕轨(索引从 0 开始)
ffmpeg -i input.mkv -map 0:s:1 -c copy subtitle.srt

7.3 添加软字幕(可开关,不重编码)

# 添加 SRT 为软字幕
ffmpeg -i input.mp4 -i subtitle.srt \
  -c copy -c:s mov_text \
  -map 0 -map 1 \
  -metadata:s:s:0 language=zh \
  output.mp4

八、格式转换与压缩

8.1 常用格式转换

# MKV → MP4(copy 模式,无损快转)
ffmpeg -i input.mkv -c copy output.mp4

# 注意:MKV 的某些编码 MP4 不支持,需要重编码
ffmpeg -i input.mkv -c:v libx264 -c:a aac output.mp4

# 任意格式 → MP4 (H.264 + AAC)
ffmpeg -i input.xxx -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4

8.2 视频压缩

# CRF 控制质量(推荐)
# CRF 18 → 接近无损,文件大
# CRF 23 → 默认,质量好
# CRF 28 → 明显压缩,适合分享
# CRF 35 → 高度压缩,适合预览
ffmpeg -i input.mp4 -c:v libx264 -preset slow -crf 28 -c:a aac -b:a 96k output.mp4

# 指定目标体积(2-Pass)
# 假设目标 50MB,视频 600 秒
# 视频码率 = (50 * 8 * 1024) / 600 - 音频码率 ≈ 640kbps
ffmpeg -i input.mp4 -c:v libx264 -b:v 640k -pass 1 -f mp4 /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 640k -pass 2 output.mp4

8.3 批量格式转换(Python)

import os
import subprocess
from pathlib import Path

def batch_convert(input_dir, output_dir, target_format='mp4'):
    """批量转换视频格式"""
    os.makedirs(output_dir, exist_ok=True)

    for file in Path(input_dir).glob('*'):
        if file.suffix.lower() in ['.mkv', '.avi', '.flv', '.mov', '.webm']:
            output = Path(output_dir) / f'{file.stem}.{target_format}'
            print(f'转换: {file.name}{output.name}')

            subprocess.run([
                'ffmpeg', '-i', str(file),
                '-c:v', 'libx264', '-preset', 'medium', '-crf', '23',
                '-c:a', 'aac', '-b:a', '128k',
                str(output)
            ], check=True)

九、滤镜与特效

9.1 视频水印

# 右下角添加图片水印(留 10px 边距)
ffmpeg -i input.mp4 -i watermark.png \
  -filter_complex "overlay=W-w-10:H-h-10" \
  output.mp4

# 添加文字水印
ffmpeg -i input.mp4 \
  -vf "drawtext=text='VidDown':fontsize=24:fontcolor=white@0.5:\
       x=W-tw-10:y=H-th-10:shadowcolor=black:shadowx=2:shadowy=2" \
  output.mp4

9.2 倍速播放

# 2 倍速(视频 + 音频同步加速)
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" \
  -map "[v]" -map "[a]" output.mp4

# 视频 2 倍速,音频正常
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]setpts=0.5*PTS[v]" \
  -map "[v]" -map 0:a output.mp4

# 慢放 0.5 倍速
ffmpeg -i input.mp4 \
  -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" \
  -map "[v]" -map "[a]" output.mp4

9.3 旋转与翻转

# 顺时针旋转 90 度
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4
# transpose=0: 逆时针 90 度 + 垂直翻转
# transpose=1: 顺时针 90 度
# transpose=2: 逆时针 90 度
# transpose=3: 顺时针 90 度 + 垂直翻转

# 水平翻转(镜像)
ffmpeg -i input.mp4 -vf "hflip" output.mp4

# 垂直翻转
ffmpeg -i input.mp4 -vf "vflip" output.mp4

9.4 模糊与马赛克

# 全画面高斯模糊
ffmpeg -i input.mp4 -vf "gblur=sigma=10" output.mp4

# 指定区域马赛克(覆盖 100x100 区域)
ffmpeg -i input.mp4 \
  -vf "delogo=x=100:y=200:w=150:h=150:show=0" \
  output.mp4

十、信息查看与调试

10.1 查看文件信息

# 基本信息
ffprobe input.mp4

# JSON 格式(方便程序解析)
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4

# 仅查看关键字段
ffprobe -v error -show_entries format=duration,size,bit_rate \
  -of default=noprint_wrappers=1 input.mp4

10.2 Python 解析视频信息

import json
import subprocess

def get_video_info(filepath):
    """获取视频元信息"""
    cmd = [
        'ffprobe', '-v', 'quiet', '-print_format', 'json',
        '-show_format', '-show_streams', filepath
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    info = json.loads(result.stdout)

    format_info = info.get('format', {})
    video_stream = next(
        (s for s in info.get('streams', []) if s['codec_type'] == 'video'),
        {}
    )

    return {
        'duration': float(format_info.get('duration', 0)),
        'size': int(format_info.get('size', 0)),
        'bitrate': int(format_info.get('bit_rate', 0)),
        'width': video_stream.get('width'),
        'height': video_stream.get('height'),
        'codec': video_stream.get('codec_name'),
        'fps': eval(video_stream.get('r_frame_rate', '0/1')),
    }

10.3 生成进度条(管道解析)

# FFmpeg 输出到 stderr,通过管道解析进度
ffmpeg -i input.mp4 -c:v libx264 output.mp4 2>&1 | \
  grep -oP "time=\K[\d:.]+"

10.4 静默运行

# 完全静默(不显示进度)
ffmpeg -hide_banner -loglevel error -i input.mp4 output.mp4

# 只显示错误
ffmpeg -loglevel error -i input.mp4 output.mp4

# 显示进度条(默认)
ffmpeg -loglevel info -stats -i input.mp4 output.mp4

速查表

场景 命令模板
截图 ffmpeg -i in.mp4 -ss 10 -vframes 1 out.jpg
GIF ffmpeg -i in.mp4 -t 5 -vf "fps=10,scale=480:-1" out.gif
截取 ffmpeg -ss 01:30 -i in.mp4 -t 30 -c copy out.mp4
合并 ffmpeg -f concat -i list.txt -c copy out.mp4
转格式 ffmpeg -i in.mkv -c:v libx264 -c:a aac out.mp4
压缩 ffmpeg -i in.mp4 -c:v libx264 -crf 28 out.mp4
提取音频 ffmpeg -i in.mp4 -vn -c:a aac out.aac
烧录字幕 ffmpeg -i in.mp4 -vf "subtitles=sub.srt" out.mp4
加水印 ffmpeg -i in.mp4 -i logo.png -filter_complex "overlay=W-w-10:H-h-10" out.mp4
倍速 ffmpeg -i in.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" out.mp4

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部