mcpField
V
videodb

videodb

github.com/sickn33创意与媒体48.7k52 次安装今天更新
代码仓库

关于 videodb

VideoDB Skill 指导 Agent 使用 VideoDB 处理视频、音频、直播流和桌面会话,涵盖索引检索、剪辑编辑与实时监控。适合需要从媒体中提取可搜索证据并生成媒体内容的工作流。

主要功能

  1. 01采集桌面、麦克风和系统音频
  2. 02导入文件或 URL 并生成播放流
  3. 03建立视觉、语音和关键词索引
  4. 04按时间戳搜索并生成剪辑
  5. 05编辑时间线、字幕、叠加层和音频
  6. 06监控 RTSP 直播并触发告警

适用场景

  1. 01查找视频中出现某场景或语句的时刻
  2. 02录制桌面会话并生成摘要和证据链接
  3. 03为视频生成字幕、配音或背景音乐
  4. 04监控直播画面并对指定事件告警

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill videodb

安装后在 Claude Code 中输入/videodb确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
rtstream.md
capture.md
use-cases.md
search.md
streaming.md
generative.md
capture-reference.md
rtstream-reference.md
editor.md
api-reference.md
scripts/
ws_listener.py

详细介绍

VideoDB Skill

面向视频、直播流和桌面会话的感知 + 记忆 + 操作。

当你需要执行以下操作时,请使用此 Skill:

何时使用

  • 你需要从文件、URL、桌面会话或直播流中进行视频或音频感知、索引、搜索或时间线编辑。
  • 任务涉及时间戳、可搜索的证据、字幕、片段、叠加层或实时监控告警。
  • 你希望用一个工作流将摄取、理解、检索和媒体操作结合起来。

1) 桌面感知

  • 启动/停止一个捕获 屏幕、麦克风和系统音频 的 桌面会话
  • 流式传输 实时上下文 并存储 情景式会话记忆
  • 针对所说内容和屏幕上发生的情况运行 实时告警/触发器
  • 生成 会话摘要、可搜索的时间线和 可播放的证据链接

2) 视频摄取 + 流

  • 摄取 文件或 URL 并返回 可播放的 Web 流链接
  • 转码/规范化:编解码器、比特率、fps、分辨率、宽高比

3) 索引 + 搜索(时间戳 + 证据)

  • 构建 视觉、语音 和 关键词 索引
  • 搜索并返回带 时间戳 和 可播放证据 的确切时刻
  • 根据搜索结果自动创建 片段

4) 时间线编辑 + 生成

  • 字幕:生成、翻译、烧录
  • 叠加层:文本/图像/品牌、动态字幕
  • 音频:背景音乐、配音、混音
  • 通过 时间线操作 进行程序化合成和导出

5) 直播流(RTSP)+ 监控

  • 连接 RTSP/直播源
  • 运行 实时视觉和语音理解,并为监控工作流发出 事件/告警

常见输入

  • 本地 文件路径、公开 URL 或 RTSP URL
  • 桌面捕获请求:启动 / 停止 / 总结会话
  • 期望的操作:获取用于理解的上下文、转码规格、索引规格、搜索查询、片段范围、时间线编辑、告警规则

常见输出

  • 流 URL
  • 带 时间戳 和 证据链接 的搜索结果
  • 生成的资产:字幕、音频、图像、片段
  • 用于直播流的 事件/告警负载
  • 桌面 会话摘要 和记忆条目

典型提示词(示例)

  • "启动桌面捕获,并在出现密码字段时告警。"
  • "录制我的会话,并在结束时生成可操作的摘要。"
  • "摄取此文件并返回可播放的流链接。"
  • "索引此文件夹,找出所有包含人物的场景,返回时间戳。"
  • "生成字幕,将其烧录,并添加轻柔的背景音乐。"
  • "连接此 RTSP URL,并在有人进入区域时告警。"

运行 Python 代码

在运行任何 VideoDB 代码之前,切换到项目目录并加载环境变量:

from dotenv import load_dotenv
load_dotenv(".env")

import videodb
conn = videodb.connect()

这会从以下位置读取 VIDEO_DB_API_KEY:

  1. 环境(如果已导出)
  2. 当前目录下项目的 .env 文件

如果缺少该密钥,videodb.connect() 会自动引发 AuthenticationError。

当简短的内联命令可以完成时,不要编写脚本文件。

在编写内联 Python(python -c "...")时,始终使用格式正确的代码——使用分号分隔语句并保持可读性。对于超过约 3 条语句的任何内容,请改用 heredoc:

python << 'EOF'
from dotenv import load_dotenv
load_dotenv(".env")

import videodb
conn = videodb.connect()
coll = conn.get_collection()
print(f"Videos: {len(coll.get_videos())}")
EOF

设置

当用户要求"setup videodb"或类似操作时:

1. 安装 SDK
pip install "videodb[capture]" python-dotenv

如果 videodb[capture] 在 Linux 上失败,请在不带 capture extra 的情况下安装:

pip install videodb python-dotenv
2. 配置 API 密钥

用户必须使用 以下任一 方法设置 VIDEO_DB_API_KEY:

  • 在终端中导出(在启动 Claude 之前):export VIDEO_DB_API_KEY=your-key
  • 项目 .env 文件:将 VIDEO_DB_API_KEY=your-key 保存到项目的 .env 文件中

在 https://console.videodb.io 获取免费 API 密钥(50 次免费上传,无需信用卡)。

不要 自行读取、写入或处理 API 密钥。始终让用户自行设置。

快速参考

上传媒体
# URL
video = coll.upload(url="https://example.com/video.mp4")

# YouTube
video = coll.upload(url="https://www.youtube.com/watch?v=VIDEO_ID")

# Local file
video = coll.upload(file_path="/path/to/video.mp4")
转录 + 字幕
# force=True skips the error if the video is already indexed
video.index_spoken_words(force=True)
text = video.get_transcript_text()
stream_url = video.add_subtitle()
在视频内搜索
from videodb.exceptions import InvalidRequestError

video.index_spoken_words(force=True)

# search() raises InvalidRequestError when no results are found.
# Always wrap in try/except and treat "No results found" as empty.
try:
    results = video.search("product demo")
    shots = results.get_shots()
    stream_url = results.compile()
except InvalidRequestError as e:
    if "No results found" in str(e):
        shots = []
    else:
        raise
场景搜索
import re
from videodb import SearchType, IndexType, SceneExtractionType
from videodb.exceptions import InvalidRequestError

# index_scenes() has no force parameter — it raises an error if a scene
# index already exists. Extract the existing index ID from the error.
try:
    scene_index_id = video.index_scenes(
        extraction_type=SceneExtractionType.shot_based,
        prompt="Describe the visual content in this scene.",
    )
except Exception as e:
    match = re.search(r"id\s+([a-f0-9]+)", str(e))
    if match:
        scene_index_id = match.group(1)
    else:
        raise

# Use score_threshold to filter low-relevance noise (recommended: 0.3+)
try:
    results = video.search(
        query="person writing on a whiteboard",
        search_type=SearchType.semantic,
        index_type=IndexType.scene,
        scene_index_id=scene_index_id,
        score_threshold=0.3,
    )
    shots = results.get_shots()
    stream_url = results.compile()
except InvalidRequestError as e:
    if "No results found" in str(e):
        shots = []
    else:
        raise
时间线编辑

重要: 在构建时间线之前,务必验证时间戳:

  • start 必须 >= 0(负值会被静默接受,但会产生损坏的输出)
  • start 必须 < end
  • end 必须 <= video.length
from videodb.timeline import Timeline
from videodb.asset import VideoAsset, TextAsset, TextStyle

timeline = Timeline(conn)
timeline.add_inline(VideoAsset(asset_id=video.id, start=10, end=30))
timeline.add_overlay(0, TextAsset(text="The End", duration=3, style=TextStyle(fontsize=36)))
stream_url = timeline.generate_stream()
转码视频(更改分辨率 / 质量)
from videodb import TranscodeMode, VideoConfig, AudioConfig

# Change resolution, quality, or aspect ratio server-side
job_id = conn.transcode(
    source="https://example.com/video.mp4",
    callback_url="https://example.com/webhook",
    mode=TranscodeMode.economy,
    video_config=VideoConfig(resolution=720, quality=23, aspect_ratio="16:9"),
    audio_config=AudioConfig(mute=False),
)
重构图宽高比(用于社交平台)

警告: reframe() 是一项缓慢的服务端操作。对于长视频,它可能需要 数分钟,并可能超时。最佳实践:

  • 尽可能使用 start/end 限制为短片段
  • 对于完整长度的视频,使用 callback_url 进行异步处理
  • 先在 Timeline 上裁剪视频,再对较短的结​​果进行重构
from videodb import ReframeMode

# Always prefer reframing a short segment:
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)

# Async reframe for full-length videos (returns None, result via webhook):
video.reframe(target="vertical", callback_url="https://example.com/webhook")

# Presets: "vertical" (9:16), "square" (1:1), "landscape" (16:9)
reframed = video.reframe(start=0, end=60, target="square")

# Custom dimensions
reframed = video.reframe(start=0, end=60, target={"width": 1280, "height": 720})
生成式媒体
image = coll.generate_image(
    prompt="a sunset over mountains",
    aspect_ratio="16:9",
)

错误处理

from videodb.exceptions import AuthenticationError, InvalidRequestError

try:
    conn = videodb.connect()
except AuthenticationError:
    print("Check your VIDEO_DB_API_KEY")

try:
    video = coll.upload(url="https://example.com/video.mp4")
except InvalidRequestError as e:
    print(f"Upload failed: {e}")
常见陷阱
场景错误信息解决方案
对已建立索引的视频再次建立索引Spoken word index for video already exists使用 video.index_spoken_words(force=True) 在已建立索引时跳过
场景索引已存在Scene index with id XXXX already exists使用 re.search(r"id\s+([a-f0-9]+)", str(e)) 从错误中提取现有的 scene_index_id
搜索未找到匹配项InvalidRequestError: No results found捕获该异常并视为空结果(shots = [])
重构超时在长视频上无限期阻塞使用 start/end 限制片段,或传入 callback_url 进行异步处理
时间线上的负时间戳静默产生损坏的流在创建 VideoAsset 之前始终验证 start >= 0
generate_video() / create_collection() 失败Operation not allowed 或 maximum limit受套餐限制的功能 — 告知用户套餐限制

附加文档

参考文档位于与此 SKILL.md 文件相邻的 reference/ 目录中。如有需要,可使用 Glob 工具定位它。

屏幕录制(桌面捕获)

使用 ws_listener.py 在录制会话期间捕获 WebSocket 事件。桌面捕获仅支持 macOS。

快速开始
  1. 启动监听器:python scripts/ws_listener.py &
  2. 获取 WebSocket ID:cat /tmp/videodb_ws_id
  3. 运行捕获代码(完整工作流见 reference/capture.md)
  4. 事件写入至:/tmp/videodb_events.jsonl
查询事件
import json
events = [json.loads(l) for l in open("/tmp/videodb_events.jsonl")]

# Get all transcripts
transcripts = [e["data"]["text"] for e in events if e.get("channel") == "transcript"]

# Get visual descriptions from last 5 minutes
import time
cutoff = time.time() - 300
recent_visual = [e for e in events 
                 if e.get("channel") == "visual_index" and e["unix_ts"] > cutoff]
实用脚本

完整的捕获工作流,请参阅 reference/capture.md。

当 VideoDB 支持某项操作时,不要使用 ffmpeg、moviepy 或本地编码工具。以下操作均由 VideoDB 在服务端处理 —— 裁剪、合并片段、叠加音频或音乐、添加字幕、文字/图像叠加、转码、更改分辨率、宽高比转换、按平台要求调整尺寸、转录以及媒体生成。只有在 reference/editor.md 的 Limitations 中列出的操作(转场、变速、裁剪/缩放、调色、音量混合)才回退到本地工具。

何时使用何种方案
问题VideoDB 解决方案
平台拒绝视频宽高比或分辨率使用带 VideoConfig 的 video.reframe() 或 conn.transcode()
需要为 Twitter/Instagram/TikTok 调整视频尺寸video.reframe(target="vertical") 或 target="square"
需要更改分辨率(例如 1080p → 720p)使用带 VideoConfig(resolution=720) 的 conn.transcode()
需要在视频上叠加音频/音乐在 Timeline 上使用 AudioAsset
需要添加字幕video.add_subtitle() 或 CaptionAsset
需要合并/裁剪片段在 Timeline 上使用 VideoAsset
需要生成旁白、音乐或音效coll.generate_voice()、generate_music()、generate_sound_effect()

代码仓库

https://github.com/video-db/skills

维护者: VideoDB

限制

  • 仅当任务明确符合上述范围时才使用此技能。
  • 不要将输出视为针对特定环境的验证、测试或专家评审的替代品。
  • 如果缺少必需的输入、权限、安全边界或成功标准,请停止并请求澄清。

评论

支持 Markdown