4、音频信息查看:使用 ffprobe 查看音频文件元数据、流信息、编码参数、时长、格式详情

拿到一个音频文件,第一件事是什么?

我个人习惯是先「盘问」它一番——什么格式、什么编码、多长、多少声道、采样率多少。这些信息不搞清楚,后面做任何处理都是盲人摸象。

ffprobe 就是干这个的。它是 FFmpeg 家族里的「侦察兵」,专门用来读取多媒体文件的内部信息。今天我们就把它用透。

4.1 为什么需要 ffprobe?

你想想看,一个 .mp3 文件,表面上看就是个音频。但里面藏着多少东西?

  • 容器格式是 MP3 还是 MP4 伪装?
  • 编码器是 MP3 还是 AAC?
  • 采样率是 44100 还是 48000?
  • 码率是 CBR 还是 VBR?
  • 有没有内嵌封面图?
  • 有没有专辑、艺术家等元数据?

这些用眼睛看不出来,得靠 ffprobe 一条命令搞定。

核心观点:ffprobe 是 FFmpeg 套件中专门用于探测和输出多媒体文件信息的工具。它不会转码、不会修改文件,只读不写,绝对安全。

4.2 基础用法:一条命令看全貌

先来个最简单的。打开终端,输入:

ffprobe input.mp3

输出大概长这样:

Input #0, mp3, from 'input.mp3':
  Metadata:
    title           : 晴天
    artist          : 周杰伦
    album           : 叶惠美
    date            : 2003
  Duration: 00:04:29.78, start: 0.000000, bitrate: 192 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 192 kb/s

嗯,信息很全。但说实话,这个输出格式有点「人类友好但机器不友好」。如果你要写脚本批量处理,或者只想提取某个字段,就得用更精准的参数。

4.3 输出格式控制:JSON 和 XML

我个人做自动化脚本时,几乎只用 JSON 输出。结构清晰,解析方便。

ffprobe -v quiet -print_format json -show_format -show_streams input.mp3

参数拆解:

  • -v quiet:只输出结果,不输出日志和警告
  • -print_format json:输出 JSON 格式
  • -show_format:显示容器格式信息
  • -show_streams:显示所有流信息

输出 JSON 片段示例:

{
  "streams": [
    {
      "index": 0,
      "codec_name": "mp3",
      "codec_long_name": "MP3 (MPEG audio layer 3)",
      "sample_rate": "44100",
      "channels": 2,
      "channel_layout": "stereo",
      "bit_rate": "192000",
      "duration": "269.780000"
    }
  ],
  "format": {
    "filename": "input.mp3",
    "format_name": "mp3",
    "duration": "269.780000",
    "size": "6480000",
    "bit_rate": "192000"
  }
}

XML 格式也支持,加 -print_format xml 就行。但我建议你直接用 JSON,几乎所有编程语言都有现成的解析库。

4.4 只看你关心的字段

有时候你只想知道时长,或者只想知道采样率。ffprobe 提供了精确提取的选项。

4.4.1 只看时长

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp3

输出:269.780000(单位:秒)

4.4.2 只看采样率和声道数

ffprobe -v error -show_entries stream=sample_rate,channels -of default=noprint_wrappers=1:nokey=1 input.mp3

输出:

44100
2

4.4.3 只看编码器名称

ffprobe -v error -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 input.mp3

输出:mp3

小技巧:-of default=noprint_wrappers=1:nokey=1 这个参数组合的意思是「只输出值,不输出键名,不包装」。这样拿到的结果可以直接赋值给变量,省去解析步骤。

4.5 查看元数据(Metadata)

音频文件里经常藏着专辑封面、歌手、曲目号等信息。这些属于元数据,不是流数据。

ffprobe -v quiet -print_format json -show_format input.mp3

在 JSON 的 format.tags 字段里,你会看到:

"tags": {
  "title": "晴天",
  "artist": "周杰伦",
  "album": "叶惠美",
  "date": "2003",
  "genre": "Pop",
  "track": "1/10"
}

我曾经帮一个音乐 App 团队排查过问题——用户上传的歌曲封面图显示不出来。一查才发现,有些文件的封面图不是嵌在元数据里,而是作为独立流存在的。这时候得用 -show_streams 才能看到。

4.6 查看流信息(Stream Info)

一个音频文件可能包含多个流。比如一个 MP4 文件,既有音频流又有视频流(封面图动画)。

ffprobe -v quiet -print_format json -show_streams input.mp4

输出中每个流都有一个 index 和 codec_type。你可以根据 codec_type 区分:

  • "codec_type": "audio" —— 音频流
  • "codec_type": "video" —— 视频流(封面图也算)

每个音频流还会包含:

字段 含义 示例值
codec_name 编码器名称 aac, mp3, flac
sample_rate 采样率(Hz) 44100, 48000
channels 声道数 1(单声道), 2(立体声)
channel_layout 声道布局 stereo, mono, 5.1
bit_rate 码率(bps) 128000, 192000
duration 时长(秒) 269.78

4.7 查看编码参数详情

有些编码参数藏得比较深。比如 AAC 的编码档次(LC、HE、HEv2),或者 MP3 的编码模式(CBR、VBR)。

用 -show_streams 加上 -show_entries stream=codec_name,profile,bit_rate:

ffprobe -v quiet -print_format json -show_entries stream=codec_name,profile,bit_rate input.aac

输出:

"profile": "LC"

嗯,LC 是低复杂度档次,最常见。如果是 HE(高效档次),说明文件用了 SBR(频带复制)技术,适合低码率场景。

注意:不是所有编码器都会暴露 profile 字段。比如 MP3 就没有 profile 概念,只有 MPEG 版本(Layer 1/2/3)。ffprobe 能显示什么,取决于文件本身和封装格式。

4.8 查看格式详情

格式信息指的是容器层面的数据,比如文件格式、总大小、总码率、起始时间等。

ffprobe -v quiet -print_format json -show_format input.flac

关键字段:

字段 含义 示例值
format_name 容器格式 flac, mp3, mov, mp4
duration 总时长(秒) 269.78
size 文件大小(字节) 6480000
bit_rate 总码率(bps) 192000
start_time 起始时间(秒) 0.000000

这里有个坑:bit_rate 是总码率,包含所有流(音频+视频+字幕)。如果你只想要音频流的码率,得去 streams 里找。

4.9 实战:一键生成音频信息报告

我经常写一个脚本,把上面所有信息汇总成一个可读的报告。这里给个 Shell 示例:

#!/bin/bash
FILE="$1"
echo "========== 音频信息报告 =========="
echo "文件: $FILE"
echo ""
echo "--- 格式信息 ---"
ffprobe -v error -show_entries format=format_name,duration,size,bit_rate -of default=noprint_wrappers=1 "$FILE"
echo ""
echo "--- 流信息 ---"
ffprobe -v error -show_entries stream=index,codec_name,codec_type,sample_rate,channels,channel_layout,bit_rate,duration -of default=noprint_wrappers=1 "$FILE"
echo ""
echo "--- 元数据 ---"
ffprobe -v error -show_entries format_tags=title,artist,album,date,genre -of default=noprint_wrappers=1 "$FILE"
echo "================================"

运行 ./audio_info.sh input.mp3,一目了然。

4.10 本章知识体系

下面这张图帮你理清 ffprobe 的信息结构:

ffprobe 音频信息查看体系 ffprobe 命令 格式信息 (-show_format) 流信息 (-show_streams) 元数据 (format.tags) format_name / duration size / bit_rate / start_time codec_name / codec_type sample_rate / channels channel_layout / bit_rate duration / profile title / artist / album date / genre / track 输出格式控制 -print_format json -print_format xml -of default=noprint_wrappers=1

4.11 避坑指南

最后分享几个我踩过的坑:

  • 坑一:时长不准。 有些 VBR(可变码率)的 MP3 文件,ffprobe 显示的时长是估算值,可能差几秒。这时候用 -show_entries format=duration 拿到的值更可靠。
  • 坑二:元数据乱码。 中文标签在终端里可能显示为 \uXXXX 转义序列。加 -print_format json 后,JSON 会正确处理 Unicode,但终端输出可能还是乱码。建议重定向到文件查看。
  • 坑三:多流文件搞混。 一个文件里有多个音频流(比如多语言音轨),-show_streams 会全部列出。记得用 index 区分,或者加 -select_streams a:0 只选第一个音频流。

我的习惯:每次处理新文件,先跑一遍 ffprobe -v quiet -print_format json -show_format -show_streams input.file,把输出存成 JSON 文件。后面写脚本时直接读这个 JSON,不用反复探测,效率高很多。