提示

返回博客列表

手里几千个视频怎么盘点?用 ffprobe 做媒体资产清单与自动化管理

手里几千个视频怎么盘点?用 ffprobe 做媒体资产清单与自动化管理

做资源库、影视站、或者单纯囤了一堆录像的人,迟早会遇到一个现实问题:硬盘里塞了几千个视频,编码格式、分辨率、时长、码率参差不齐,想整理却无从下手。靠手动打开看是不可能的。ffmpeg 套装里的 ffprobe 就是为这种场景而生的——它能把每个文件的详细技术参数吐成结构化 JSON,我们写个脚本批量扫一遍,资产盘点就一目了然。这篇文章从单文件解析讲起,一直到建成一个可查询的媒体资产数据库。

一、ffprobe 能拿到什么

基本覆盖所有技术参数:

  • 容器层:格式、时长、文件大小、总码率;
  • 视频流:编码(H.264/H.265/VP9/AV1)、分辨率、帧率、码率、profile、色彩空间、旋转角度;
  • 音频流:编码、采样率、声道数、语言、码率;
  • 字幕/附件:字幕流数量与语言、内嵌封面等。

二、最基础的 JSON 输出

ffprobe -v error -show_format -show_streams -of json input.mp4
  • -v error:只打印错误,屏蔽进度噪声;
  • -show_format:容器级信息;
  • -show_streams:每个流的详细信息;
  • -of json:结构化输出,方便程序解析。

三、只取关心的字段(更轻量)

全量 JSON 太啰嗦,用 select_streams + show_entries 精简:

ffprobe -v error -select_streams v:0 \
  -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate \
  -show_entries format=duration,size \
  -of csv=p=0 input.mp4

输出形如 h264,1920,1080,30/1,2500000,120.5,52428800,程序 split 即可。

四、批量扫描整个目录并导出 CSV

写个 Python 脚本,遍历目录、逐文件调 ffprobe、汇总成 CSV:

import subprocess, json, os, csv

def probe(path):
    out = subprocess.check_output([
        'ffprobe', '-v', 'error',
        '-show_format', '-show_streams', '-of', 'json', path
    ], stderr=subprocess.DEVNULL)
    return json.loads(out)

rows = []
for root, _, files in os.walk('D:/videos'):
    for f in files:
        if not f.lower().endswith(('.mp4', '.mkv', '.webm', '.avi', '.mov')):
            continue
        p = os.path.join(root, f)
        try:
            info = probe(p)
        except Exception:
            continue  # 损坏或 ffprobe 打不开的跳过
        v = next((s for s in info['streams'] if s['codec_type'] == 'video'), {})
        a = next((s for s in info['streams'] if s['codec_type'] == 'audio'), {})
        fmt = info.get('format', {})
        rows.append({
            'file': p,
            'vcodec': v.get('codec_name'),
            'w': v.get('width'), 'h': v.get('height'),
            'fps': v.get('r_frame_rate'),
            'vbitrate': int(v.get('bit_rate', 0) or 0),
            'acodec': a.get('codec_name'),
            'channels': a.get('channels'),
            'duration': round(float(fmt.get('duration', 0)), 1),
            'size_mb': round(int(fmt.get('size', 0)) / 1048576, 1),
        })

with open('inventory.csv', 'w', newline='', encoding='utf-8') as fp:
    w = csv.DictWriter(fp, fieldnames=rows[0].keys())
    w.writeheader()
    w.writerows(rows)

五、进阶:建成可查询的数据库

CSV 只能手动筛,量大了还是慢。把数据写进 SQLite,就能用 SQL 随意查:

import sqlite3
conn = sqlite3.connect('media.db')
conn.execute('''CREATE TABLE IF NOT EXISTS media(
    path TEXT, vcodec TEXT, w INT, h INT, fps TEXT,
    vbitrate INT, acodec TEXT, channels INT, duration REAL, size_mb REAL)''')
conn.executemany('INSERT INTO media VALUES (?,?,?,?,?,?,?,?,?,?)',
                 [(r['file'], r['vcodec'], r['w'], r['h'], r['fps'],
                   r['vbitrate'], r['acodec'], r['channels'],
                   r['duration'], r['size_mb']) for r in rows])
conn.commit()
# 例如:找出所有 1080p 以上但码率低于 2Mbps 的(疑似压烂了)
for row in conn.execute("SELECT path FROM media WHERE w>=1920 AND vbitrate<2000000"):
    print(row[0])

六、基于盘点能做什么

  • 找异常大文件size_mb > 5000 的,看是不是重复或需要转码;
  • 找老旧编码vcodec='mpeg4' 的标清老片,统一计划转 H.264;
  • 找分辨率不一:整理剧集时确认每集是否同一分辨率;
  • 查损坏文件:ffprobe 返回非 0 的就是打不开/损坏,直接挑出来;
  • 生成统计报表:总时长、总占用、编码分布,一眼看清资产状况。

七、提速:多进程并行

几百个文件串行还行,几千上万个就慢了。用多进程并行探测:

from multiprocessing import Pool
with Pool(8) as pool:
    results = pool.map(probe_safe, all_paths)

ffprobe 是单文件 CPU 轻量操作,8~16 路并行提升明显。

八、常见翻车现场

现象 根因 解法
ffprobe 卡死 个别文件损坏/假死 timeout 和异常跳过
时长显示 N/A 某些封装没写时长 duration_ts 估算或忽略
中文路径报错 命令行编码问题 subprocess 传列表参数而非字符串
扫描极慢 单进程逐个调 多进程并行
旋转视频分辨率反了 有 rotate 元数据 tags 里的 rotate 字段

九、常见问题

Q:能直接写 Postgres 吗? 能,把 CSV/SQLite 换成 INSERT 进 Postgres 即可,做成完整的资产管理系统(之前博客里提到的 BlogPost 资产同理)。

Q:为什么不用 mediainfo? mediainfo 也很好,但 ffprobe 与 ffmpeg 同源、参数风格统一,自动化流水线里更顺手。

Q:损坏文件怎么批量挑? ffprobe 返回非 0 退出码的,脚本里捕获异常即可归为"损坏/不可读"。

Q:能顺便生成缩略图吗? 能,扫的时候对每个视频 ffmpeg -ss 10 -i ... -frames:v 1 thumb.jpg,配合清单做成带预览的资产页。

小结

ffprobe 是媒体资产盘点的瑞士军刀:从单文件 JSON 到批量 CSV,再到 SQLite/Postgres 资产库,层层递进。掌握 select_streams + show_entries 精简输出,再用脚本汇总,几千个视频也能几分钟理清楚。

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

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

顶部