3、命令行基础:ffmpeg、ffprobe、ffplay的基本用法,常用参数(-i、-c、-f、-t、-ss等),查看媒体信息,简单转码

FFmpeg 是一个极其强大的多媒体处理框架,其核心交互方式就是命令行工具。对于任何希望深入掌握音视频处理的技术人员而言,熟练使用 ffmpeg、ffprobe 和 ffplay 这三个命令行工具是必修课。它们分别承担着“处理”、“探查”和“播放预览”的职责。本章将系统性地拆解这三个工具的基本用法,深入解析最常用的核心参数,并通过实际案例演示如何查看媒体信息与执行简单转码。我们将从命令行参数的本质出发,理解 FFmpeg 的工作流模型,从而为后续复杂滤镜、硬件加速与流媒体处理打下坚实基础。

FFmpeg 命令行工具族与数据流转模型 输入媒体 input.mp4 / .ts ffprobe 查看封装/编码信息 ffplay 播放预览/音视频同步 ffmpeg 核心引擎 解封装 → 解码 → 滤镜 → 编码 → 封装 -i 输入参数 / -c 编码器 / -f 格式 输出媒体 output.avi / .flv 常用控制参数 -t 时长 / -ss 跳转 / -f 强制格式 -c:v 视频编码 / -c:a 音频编码 主处理链路 信息探查 预览回放

上图清晰地展示了 FFmpeg 工具族的分工与协作关系。核心的 ffmpeg 命令负责处理输入媒体并生成输出,而 ffprobe 和 ffplay 则分别从“分析”和“预览”两个维度辅助我们理解媒体文件。在实际工作中,我们通常先用 ffprobe 探查输入文件的编码格式、封装格式、分辨率、码率等关键信息,再决定 ffmpeg 的转码策略,最后用 ffplay 快速验证输出效果。这种“先探查、再处理、后验证”的工作流是高效使用 FFmpeg 的基础。

3.1 三大工具的核心定位与基本用法

核心原理:工具分工与命令行解析逻辑

FFmpeg 项目提供了三个独立的可执行文件,它们共享底层库但面向不同任务。理解它们的分工是避免混淆的第一步。ffmpeg 是全能型选手,负责音视频的转码、滤镜处理、封装转换等一切“改变”操作;ffprobe 是分析型工具,只读取媒体文件的元数据与流信息,不做任何修改;ffplay 是播放器,基于 SDL 库实现音视频同步播放,常用于快速预览源文件或转码后的结果。

命令行参数遵循“全局参数 + 输入参数 + 输出参数”的排列顺序。FFmpeg 的解析规则是:-i 后面的文件视为输入,其余未以 -i 开头的文件视为输出。参数作用于其后的第一个文件。例如:

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

这里 -i input.mp4 定义了输入,-c:v libx264 和 -c:a aac 作用于输出文件 output.mkv。理解这个顺序至关重要,因为同样的参数放在不同位置会产生完全不同的效果。

操作流程:快速上手三个命令

对于 ffprobe,最常用的操作是查看媒体文件的详细信息。使用 -show_streams 可以列出所有流(视频流、音频流、字幕流)的详细参数,-show_format 则显示封装格式的全局信息。更简洁的方式是使用 -show_entries 配合 -of 指定输出格式(如 JSON),便于程序化解析。

# 查看文件基本信息(一行摘要)
ffprobe -v error -show_entries format=filename,duration,size,bit_rate -of default=noprint_wrappers=1 input.mp4

# 查看视频流编码信息
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate -of json input.mp4

对于 ffplay,基本用法就是直接跟文件名播放。但有几个实用参数值得注意:-window_title 自定义窗口标题,-volume 设置初始音量(0-100),-loop 循环播放。在调试滤镜链时,ffplay 还可以直接预览滤镜效果:

# 直接预览视频的灰度效果
ffplay -i input.mp4 -vf "hue=s=0"

对于 ffmpeg,最简单的转码命令是:

ffmpeg -i input.mp4 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k output.mp4

这条命令将输入文件重新编码为 H.264 视频和 AAC 音频,-crf 23 是质量参数(数值越小质量越高),-preset fast 平衡编码速度与压缩率。

案例拆解:用 ffprobe 诊断一个“打不开”的视频文件

假设我们收到一个用户反馈,某个 .flv 文件在播放器中无法打开。我们先用 ffprobe 进行诊断:

ffprobe -v error -show_streams -show_format problem.flv

输出显示:视频流编码为 h264,分辨率 1920x1080,但音频流编码为 aac,采样率 44100。封装格式为 flv。关键问题在于,FLV 封装格式对 H.264 有特殊的 AVC sequence header 要求,如果文件在录制时没有正确写入这个 header,很多播放器会拒绝播放。通过 ffprobe 我们确认了编码本身没问题,问题出在封装层。解决方案是使用 ffmpeg 重新封装:

ffmpeg -i problem.flv -c copy -f flv fixed.flv

这里 -c copy 表示不重新编码,只复制流数据,-f flv 强制输出 FLV 格式。FFmpeg 在重新封装时会自动生成缺失的 header,问题得以解决。这个案例说明,ffprobe 不仅是查看信息的工具,更是排查问题的第一道防线。

常见误区与总结复盘

误区一:混淆输入输出参数位置。例如将 -ss(跳转时间)放在输出位置,会导致 FFmpeg 先解码再丢弃数据,效率极低。正确做法是放在 -i 之前作为输入参数,实现快速 seek。

误区二:认为 -c copy 是万能的。流复制要求源文件和目标封装格式兼容。例如,将包含 PCM 音频的 AVI 文件复制到 MP4 容器中,MP4 不支持 PCM 编码,命令会失败。

总结:三大工具各司其职,ffprobe 是“眼睛”,ffplay 是“耳朵”,ffmpeg 是“双手”。熟练掌握它们的基本用法,是后续学习滤镜、硬件加速和复杂转码的前提。

3.2 核心参数深度解析:-i、-c、-f、-t、-ss

核心原理:参数的本质是控制数据流

FFmpeg 的参数体系可以理解为对“输入流 → 处理图 → 输出流”这条管线的控制。-i 定义输入源,-c 定义编码方式,-f 定义封装格式,-t 和 -ss 则控制时间维度上的截取。理解这些参数的本质,就能灵活组合出各种处理方案。

参数 全称/含义 典型值示例 作用对象 注意事项
-i input(输入文件) -i input.mp4 输入 可多次使用以支持多输入(如拼接、混流)
-c codec(编码器) -c:v libx264 / -c:a copy 输出 :v 指视频流,:a 指音频流,copy 表示流复制
-f format(封装格式) -f mp4 / -f flv 输入/输出 强制指定封装格式,常用于输出到管道或流媒体
-t duration(时长) -t 10(10秒) 输入/输出 作为输出参数时,限制输出时长;作为输入参数时,限制读取时长
-ss seek start(跳转起点) -ss 00:01:30 输入/输出 放在 -i 前为快速 seek,放在输出位置为精确 seek(较慢)

操作流程:参数组合的决策路径

在实际使用中,我们通常按照“确定输入 → 选择编码策略 → 设定时间范围 → 指定输出格式”的流程来构建命令。例如,要截取视频的第 1 分钟到第 2 分钟,并转换为 GIF 动图:

ffmpeg -ss 00:01:00 -i input.mp4 -t 60 -vf "fps=10,scale=320:-1" -loop 0 output.gif

这里 -ss 放在 -i 前实现快速定位,-t 60 限制输出 60 秒,-vf 设置滤镜(帧率 10fps,宽度 320 像素),-loop 0 让 GIF 无限循环。

案例拆解:从 MKV 提取字幕并转码视频

假设我们有一个 movie.mkv,包含 H.264 视频流、DTS 音频流和 PGS 字幕流。目标是将视频转为 MP4(H.264 + AAC),并单独提取字幕为 SRT 文件。分析:MKV 容器支持 DTS 和 PGS,但 MP4 不支持这两种格式,因此音频需要转码,字幕需要提取转换。

# 第一步:提取字幕(PGS 转 SRT)
ffmpeg -i movie.mkv -map 0:s:0 -c:s srt subtitles.srt

# 第二步:转码视频和音频
ffmpeg -i movie.mkv -map 0:v:0 -map 0:a:0 -c:v libx264 -crf 20 -preset medium -c:a aac -b:a 192k -sn output.mp4

在第一步中,-map 0:s:0 选择第一个字幕流,-c:s srt 将 PGS 图形字幕转换为文本 SRT。第二步中,-sn 忽略所有字幕流,避免输出文件中包含无法处理的字幕。这个案例展示了 -map 参数与 -c 参数配合的威力,也提醒我们封装格式的兼容性限制。

常见误区与总结复盘

经验提示:当需要精确截取片段时,建议将 -ss 放在 -i 之前(快速 seek),但要注意关键帧对齐问题。如果截取点不在关键帧上,输出画面可能从最近的关键帧开始,导致起始画面不准确。此时可以加上 -accurate_seek 参数(默认开启)并配合 -avoid_negative_ts make_zero 来修正时间戳。

总结:-i、-c、-f、-t、-ss 是 FFmpeg 最常用的五个参数,它们分别控制输入源、编码器、封装格式、时长和起始位置。掌握它们的组合技巧,可以解决绝大多数日常转码需求。

3.3 查看媒体信息与简单转码实战

核心原理:信息探查是转码的前提

在转码之前,我们必须了解源文件的“底细”。ffprobe 输出的信息包括:封装格式(如 MP4、MKV、FLV)、视频编码(H.264、HEVC、VP9)、分辨率、帧率、码率、像素格式、音频编码(AAC、MP3、AC3)、采样率、声道数等。这些参数直接决定了转码策略。例如,如果源视频是隔行扫描(interlaced),转码时需要添加 -deinterlace 滤镜;如果音频是 5.1 声道,而目标设备只支持立体声,则需要使用 -ac 2 进行声道转换。

操作流程:标准转码五步法

  1. 探查输入:使用 ffprobe 获取源文件的完整信息。
  2. 确定目标:明确输出文件的用途(网络播放、本地存储、移动设备兼容等)。
  3. 选择编码器:根据目标格式选择视频和音频编码器,如 H.264、H.265、VP9、AV1 等。
  4. 设定参数:调整码率、分辨率、帧率、质量参数(CRF)等。
  5. 执行转码:运行 ffmpeg 命令,监控输出日志,确认无错误。

以下是一个典型的转码命令模板:

ffmpeg -i input.mkv \
  -c:v libx264 -preset slow -crf 21 \
  -c:a aac -b:a 160k -ac 2 \
  -vf "scale=1280:720" \
  -movflags +faststart \
  output.mp4

这里 -preset slow 提高压缩效率(但更慢),-crf 21 保证视觉质量,-ac 2 强制双声道,-vf scale 缩放分辨率,-movflags +faststart 将 moov atom 移到文件头部,便于网络流媒体播放。

案例拆解:批量转码脚本的优化过程

假设我们需要将一个目录下的 100 个 .avi 文件(DV 编码)批量转为 H.264 的 MP4 文件,用于上传到视频平台。初始脚本如下:

for f in *.avi; do
  ffmpeg -i "$f" -c:v libx264 -c:a aac "${f%.avi}.mp4"
done

这个脚本可以工作,但效率低下且质量不可控。我们通过 ffprobe 分析发现,这些 AVI 文件的音频是 PCM 格式,码率高达 1536kbps,而视频是 DV 编码,码率约 25Mbps。优化策略:

  1. 使用 -map 0 明确映射所有流,避免字幕或数据流干扰。
  2. 视频使用 -crf 23 配合 -preset veryfast 提高编码速度。
  3. 音频使用 -c:a aac -b:a 128k 降低码率。
  4. 添加 -threads 0 自动利用多核 CPU。
for f in *.avi; do
  ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 \
    -c:v libx264 -preset veryfast -crf 23 \
    -c:a aac -b:a 128k -ac 2 \
    -movflags +faststart \
    "${f%.avi}.mp4"
done

优化后,编码速度提升了约 40%,输出文件体积平均减少 60%,且播放兼容性更好。这个案例说明,ffprobe 的探查结果直接指导了转码参数的优化。

常见误区与总结复盘

风险提示:不要盲目使用 -crf 0(无损模式)。无损编码的文件体积巨大,且很多播放器不支持。对于一般用途,-crf 18-23 是视觉无损的合理范围。

误区:忽略音频采样率转换。当源音频是 48kHz 而目标设备只支持 44.1kHz 时,需要添加 -ar 44100 进行重采样,否则可能出现音调异常。

总结:查看媒体信息是转码的“侦察兵”,简单转码是 FFmpeg 的“基本功”。通过本章的学习,读者应能独立完成“探查 → 决策 → 转码 → 验证”的完整闭环。在实际工作中,建议将常用的转码参数组合保存为脚本或配置文件,以提高效率并减少人为错误。