使用 ffprobe 获取视频各项属性与元数据

ffprobe 是 FFmpeg 工具集里的"情报员",专门负责分析多媒体文件的"身份证信息"。无论是视频的分辨率、格式、时长,还是音频的采样率、声道数,它都能一键提取。对于视频处理工程师、内容创作者或流媒体平台开发者来说,掌握 ffprobe 就像拥有了一把能快速了解视频底细的钥匙——在转码、播放优化或质量控制前,先摸清视频的基本属性至关重要。

ffprobe 工作原理 🔍

ffprobe 通过解析媒体文件的容器格式(如 MP4、MKV、AVI 等)来提取流信息,而无需对整个媒体文件进行解码,这使得它非常高效。其工作流程包括:

  1. 打开并识别媒体文件格式
  2. 解析文件中的所有流(视频、音频、字幕等)
  3. 提取每个流的元数据信息
  4. 根据用户指定的格式输出结果

这种非解码方式不仅速度快,还能处理损坏或部分下载的媒体文件。

快速上手:基础命令 ⚡

获取视频基本信息的最简命令:

ffprobe -v error -show_format -show_streams -print_format json your-video.mp4

参数解析

简化输出常用信息

# 获取视频流基本信息(分辨率、编码格式等)
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,r_frame_rate -of json your-video.mp4

# 获取音频流基本信息
ffprobe -v error -select_streams a:0 -show_entries stream=sample_rate,channels,codec_name -of json your-video.mp4

# 以 CSV 格式输出视频分辨率
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 your-video.mp4

将结果输出到文件

ffprobe -v error -show_format -show_streams -print_format json your-video.mp4 > meta.json

输出示例详解

运行基础命令后,会得到类似以下的 JSON 输出:

{
    "programs": [],
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
            "width": 1920,
            "height": 1080,
            "r_frame_rate": "25/1",
            "avg_frame_rate": "25/1",
            "time_base": "1/12800",
            "duration_ts": 283942,
            "duration": "22.182969",
            "bit_rate": "1200000",
            "tags": {
                "language": "und",
                "handler_name": "VideoHandler"
            }
        },
        {
            "index": 1,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "sample_rate": "44100",
            "channels": 2,
            "channel_layout": "stereo",
            "time_base": "1/44100",
            "duration_ts": 978256,
            "duration": "22.182676",
            "bit_rate": "128000",
            "tags": {
                "language": "und",
                "handler_name": "SoundHandler"
            }
        }
    ],
    "format": {
        "filename": "your-video.mp4",
        "nb_streams": 2,
        "nb_programs": 0,
        "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
        "format_long_name": "QuickTime / MOV",
        "start_time": "0.000000",
        "duration": "22.182969",
        "size": "4011572",
        "bit_rate": "1447332",
        "probe_score": 100,
        "tags": {
            "major_brand": "mp42",
            "minor_version": "0",
            "compatible_brands": "mp42mp41iso4",
            "creation_time": "2023-02-18T01:50:29.000000Z"
        }
    }
}

实用示例:获取特定信息 🚀

1. 获取视频时长

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 your-video.mp4

2. 获取视频编码格式

ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 your-video.mp4

3. 获取音频采样率

ffprobe -v error -select_streams a:0 -show_entries stream=sample_rate -of default=noprint_wrappers=1:nokey=1 your-video.mp4

4. 批量提取多个视频信息

创建一个 extract_metadata.sh 脚本:

#!/bin/bash

# 批量提取当前目录下所有视频文件的元数据
for file in *.{mp4,mkv,avi,mov}; do
    if [ -f "$file" ]; then
        echo "处理文件: $file"
        # 获取分辨率
        resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$file")
        # 获取时长
        duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file")
        # 获取视频编码
        video_codec=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$file")
        # 获取音频编码
        audio_codec=$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null || echo "无音频")

        echo "分辨率: $resolution"
        echo "时长: $duration"
        echo "视频编码: $video_codec"
        echo "音频编码: $audio_codec"
        echo "----------------------------------"
    fi
done

运行脚本:

chmod +x extract_metadata.sh
./extract_metadata.sh

5. 获取视频分辨率并处理特殊情况

获取视频分辨率是常见需求,但有时需要处理旋转视频等特殊情况:

# 获取基础分辨率
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 your-video.mp4

# 获取包含旋转信息的分辨率
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,rotate -of csv=s=x:p=0 your-video.mp4

对于旋转视频,实际显示分辨率可能与存储分辨率不同。例如,如果输出包含旋转角度(如1920x1080x90),则实际显示分辨率为1080x1920(高度和宽度互换)。

详细的分辨率获取技巧和特殊场景处理方法,请参考 使用 ffprobe 获取视频分辨率 一文。

常见问题与解决方案 ❓

Q: 命令执行后无输出或报错?

A: 可能原因及解决方法:

Q: 如何处理包含多个视频流的文件?

A: 可以通过指定流索引来获取特定流的信息:

# 获取第二个视频流的信息
ffprobe -v error -select_streams v:1 -show_entries stream=width,height -of json your-video.mkv

Q: 如何在程序中解析 ffprobe 输出?

A: 推荐使用 JSON 格式输出,然后使用对应语言的 JSON 解析库进行处理。例如,在 Python 中:

import subprocess
import json

def get_video_metadata(file_path):
    cmd = [
        'ffprobe',
        '-v', 'error',
        '-show_format',
        '-show_streams',
        '-print_format', 'json',
        file_path
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return json.loads(result.stdout)

metadata = get_video_metadata('your-video.mp4')
print(f"分辨率: {metadata['streams'][0]['width']}x{metadata['streams'][0]['height']}")
print(f"时长: {metadata['format']['duration']}")

操作速查 📋

功能命令
获取基本元数据ffprobe -v error -show_format -show_streams -print_format json your-video.mp4
获取视频分辨率ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 your-video.mp4
获取视频时长ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 your-video.mp4
获取视频编码ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 your-video.mp4
获取音频信息ffprobe -v error -select_streams a:0 -show_entries stream=sample_rate,channels -of json your-video.mp4
输出到文件ffprobe -v error -show_format -show_streams -print_format json your-video.mp4 > meta.json

相关文章 📚


参考:

  1. FFmpeg 官方文档
  2. ourcodeworld.com