You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用FFmpeg的blackdetect滤镜导出非黑场片段时间码CSV

黑场间隔正片序列时间码批量导出方案

核心逻辑

blackdetect滤镜本身只能输出黑场区间,不需要修改滤镜底层逻辑,通过「黑场区间反推正片区间」的方式就能拿到需要的分段数据,流程适配批量处理、CSV导出、RPA调用全链路要求。

前置依赖

  • 已安装FFmpeg,且已将ffmpeg、ffprobe加入系统环境变量
  • 已安装Python3环境(跨平台兼容Windows/macOS/Linux,RPA工具普遍支持Python脚本调用)

单文件处理脚本

将以下代码保存为extract_content.py,脚本会自动调用FFmpeg检测黑场、计算正片区间、导出标准CSV文件:

import subprocess
import re
import csv
import sys
from pathlib import Path

def get_video_duration(video_path):
    cmd = ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", str(video_path)]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return float(result.stdout.strip())

def detect_black_intervals(video_path, min_black_duration=0.5, pixel_threshold=0.1):
    cmd = [
        "ffmpeg", "-i", str(video_path),
        "-vf", f"blackdetect=d={min_black_duration}:pix_th={pixel_threshold}",
        "-an", "-f", "null", "-"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    log = result.stderr
    pattern = r"black_start:([0-9.]+)\s+black_end:([0-9.]+)"
    black_intervals = []
    for match in re.finditer(pattern, log):
        black_start = float(match.group(1))
        black_end = float(match.group(2))
        black_intervals.append((black_start, black_end))
    return sorted(black_intervals, key=lambda x: x[0])

def get_content_intervals(black_intervals, total_duration):
    content_intervals = []
    prev_black_end = 0.0
    for b_start, b_end in black_intervals:
        if b_start > prev_black_end + 0.01:
            content_intervals.append((round(prev_black_end, 3), round(b_start, 3)))
        prev_black_end = b_end
    if prev_black_end < total_duration - 0.01:
        content_intervals.append((round(prev_black_end, 3), round(total_duration, 3)))
    return content_intervals

def seconds_to_tc(seconds):
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = seconds % 60
    return f"{hours:02d}:{minutes:02d}:{secs:06.3f}"

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("用法: python extract_content.py <视频文件路径> [黑场最小时长] [像素阈值]")
        sys.exit(1)
    video_path = Path(sys.argv[1])
    min_black_dur = float(sys.argv[2]) if len(sys.argv) >2 else 0.5
    pix_th = float(sys.argv[3]) if len(sys.argv)>3 else 0.1
    total_dur = get_video_duration(video_path)
    black_intervals = detect_black_intervals(video_path, min_black_dur, pix_th)
    content_intervals = get_content_intervals(black_intervals, total_dur)
    csv_path = video_path.with_suffix(".csv")
    with open(csv_path, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.writer(f)
        writer.writerow(["filename", "clip_index", "start_tc", "end_tc", "start_sec", "end_sec"])
        for idx, (s, e) in enumerate(content_intervals, 1):
            writer.writerow([video_path.name, idx, seconds_to_tc(s), seconds_to_tc(e), s, e])
    print(f"处理完成,CSV已导出至: {csv_path}")

批量处理方法

将所有待处理素材放入同一文件夹,根据操作系统选择对应批量执行脚本即可:

Windows系统

将以下代码保存为batch_run.bat,和extract_content.py、素材文件夹放在同一目录,双击运行:

@echo off
for %%f in (./video_batch/*.mp4, ./video_batch/*.mov, ./video_batch/*.mxf) do (
    python extract_content.py "%%f"
)
pause

macOS/Linux系统

将以下代码保存为batch_run.sh,终端执行chmod +x batch_run.sh赋予执行权限后运行:

#!/bin/bash
for file in ./video_batch/*.{mp4,mov,mxf}; do
  python3 extract_content.py "$file"
done

参数调整说明

  • 黑场最小判定时长:脚本默认0.5秒,执行时可在文件路径后追加参数修改,比如python extract_content.py test.mp4 1代表将黑场最小时长设为1秒,过滤正片内短暂暗帧误判
  • 黑场亮度阈值:脚本默认0.1,追加第三个参数可修改,比如python extract_content.py test.mp4 0.5 0.2代表黑场最小时长0.5秒、亮度阈值0.2,适配非纯黑的暗场转场场景
  • 导出CSV默认字段包含文件名、片段序号、时:分:秒.毫秒格式时间码、浮点型秒数时间,适配绝大多数非编软件、RPA工具的导入要求,采用utf-8-sig编码避免中文乱码

内容的提问来源于stack exchange,提问作者Soapa Tune

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:39:20