옵션
집집 Skill API 개발 videodb

파일, URL, 실시간 스트림 또는 데스크톱 화면 캡처에서 동영상 및 오디오 콘텐츠를 가져오고, 색인화하고, 검색하고, 편집하고, 생성할 수 있습니다.

...모든 것을 확장하십시오
0
업데이트 된 시간 2026년 9월 30일

VideoDB 기술

동영상, 라이브 스트리밍 및 데스크톱 세션에 대한 인지력 + 기억력 + 실행 능력.

사용 시점

데스크톱 인식

  • 화면, 마이크, 시스템 오디오를 캡처하는 데스크톱 세션을 시작/중지
  • 실시간 상황을 스트리밍하고 세션별 기록을 저장
  • 화면에서 일어나는 상황과 대화 내용에 대한 실시간 알림/트리거 실행
  • 세션 요약, 검색 가능한 타임라인 및 재생 가능한 증거 링크 생성

동영상 수집 및 스트리밍

  • 파일 또는 URL을 인제스트하고 재생 가능한 웹 스트림 링크를 반환
  • 트랜스코딩/정규화: 코덱, 비트레이트, fps, 해상도, 화면비

색인 + 검색 (타임스탬프 + 증거 자료)

  • 영상, 음성 및 키워드 인덱스 생성
  • 타임스탬프와 재생 가능한 증거와 함께 정확한 순간을 검색하여 반환
  • 검색 결과에서 클립을 자동으로 생성

타임라인 편집 및 생성

  • 자막: 생성, 번역, 화면에 삽입
  • 오버레이: 텍스트/이미지/브랜딩, 모션 캡션
  • 오디오: 배경 음악, 내레이션, 더빙
  • 타임라인 작업을 통한 자동 구성 및 내보내기

라이브 스트리밍 (RTSP) + 모니터링

  • RTSP/라이브 피드 연결
  • 실시간 시각 및 음성 인식 실행, 모니터링 워크플로우를 위한 이벤트/알림 전송

작동 원리

일반적인 입력

  • 로컬 파일 경로, 공개 URL 또는 RTSP URL
  • 데스크톱 캡처 요청: 세션 시작/중지/요약
  • 원하는 작업: 이해를 위한 컨텍스트 가져오기, 트랜스코딩 사양, 인덱싱 사양, 검색 쿼리, 클립 범위, 타임라인 편집, 알림 규칙

일반적인 출력

  • 스트림 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 -c "...")을 작성할 때는 항상 올바른 형식을 갖춘 코드를 사용하십시오. 세미콜론을 사용하여 문장을 구분하고 가독성을 유지하십시오. 문장이 3개 이상인 경우에는 대신 헤레독을 사용하십시오:

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

설정

사용자가 “videodb 설정” 또는 이와 유사한 요청을 할 경우:

1. SDK 설치

pip install "videodb[capture]" python-dotenv

만약 videodb[capture] Linux에서 설치가 실패하면, `capture` 옵션을 제외하고 설치하십시오:

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 파일에서저장

콘솔(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 오류에서 scene_index_id 다음 명령어를 사용하여 re.search(r"id\s+([a-f0-9]+)", str(e))
검색 결과 일치 항목 없음 InvalidRequestError: No results found 예외를 처리하고 결과를 비어 있는 것으로 간주합니다 (shots = [])
리프레임 시간 초과 긴 동영상의 경우 무한정 멈춤 다음과 같이 start/end 를 사용하여 세그먼트를 제한하거나, callback_url 를 비동기 처리에 사용
타임라인의 음수 타임스탬프 오류가 발생한 스트림을 아무런 경고 없이 생성합니다 항상 유효성 검사 start >= 0 생성 전에 VideoAsset
generate_video() / create_collection() 실패 Operation not allowed 또는 maximum limit 계획 기반 기능 — 사용자에게 계획 한도를 알립니다

예시

표준 프롬프트

  • "데스크톱 캡처를 시작하고, 비밀번호 입력란이 나타나면 알림을 보내주세요."
  • "내 세션을 녹화하고, 세션이 끝나면 실행 가능한 요약 보고서를 생성합니다."
  • "이 파일을 가져와 재생 가능한 스트림 링크를 반환하세요."
  • "이 폴더를 색인화하고 사람이 등장하는 모든 장면을 찾아 타임스탬프를 반환해 주세요."
  • "자막을 생성하고 화면에 삽입한 뒤, 가벼운 배경 음악을 추가해 주세요."
  • "이 RTSP URL에 연결하고, 사람이 구역에 들어오면 알림을 보내세요."

화면 녹화 (데스크톱 캡처)

녹화 세션 중 ws_listener.py 를 사용하여 녹화 세션 중 WebSocket 이벤트를 캡처할 수 있습니다. 데스크톱 캡처는 macOS에서만 지원됩니다.

빠른 시작

  1. 상태 디렉터리 선택: STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}"
  2. 리스너 시작: VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" &
  3. WebSocket ID 가져오기: cat "$STATE_DIR/videodb_ws_id"
  4. 캡처 코드 실행 (전체 워크플로는 reference/capture.md 참조)
  5. 이벤트 기록 위치: $STATE_DIR/videodb_events.jsonl

새로운 캡처 실행을 시작할 때마다 --clear 이 기능을 사용하십시오. 그래야 오래된 트랜스크립트 및 시각적 이벤트가 새 세션으로 유입되는 것을 방지할 수 있습니다.

이벤트 쿼리

import json
import os
import time
from pathlib import Path

events_dir = Path(os.environ.get("VIDEODB_EVENTS_DIR", Path.home() / ".local" / "state" / "videodb"))
events_file = events_dir / "videodb_events.jsonl"
events = []

if events_file.exists():
    with events_file.open(encoding="utf-8") as handle:
        for line in handle:
            try:
                events.append(json.loads(line))
            except json.JSONDecodeError:
                continue

transcripts = [e["data"]["text"] for e in events if e.get("channel") == "transcript"]
cutoff = time.time() - 300
recent_visual = [
    e for e in events
    if e.get("channel") == "visual_index" and e["unix_ts"] > cutoff
]

추가 문서

참조 문서는 reference/ 이 SKILL.md 파일 바로 옆 디렉터리에 있습니다. 필요한 경우 Glob 도구를 사용하여 찾아보세요.

  • reference/api-reference.md - VideoDB Python SDK API 전체 참조
  • reference/search.md - 동영상 검색(음성 및 장면 기반)에 대한 심층 가이드
  • reference/editor.md - 타임라인 편집, 자산 및 합성
  • reference/streaming.md - HLS 스트리밍 및 즉시 재생
  • reference/generative.md - AI 기반 미디어 생성(이미지, 동영상, 오디오)
  • reference/rtstream.md - 라이브 스트림 수집 워크플로(RTSP/RTMP)
  • reference/rtstream-reference.md - RTStream SDK 메서드 및 AI 파이프라인
  • reference/capture.md - 데스크톱 캡처 워크플로
  • reference/capture-reference.md - 캡처 SDK 및 WebSocket 이벤트
  • reference/use-cases.md - 일반적인 동영상 처리 패턴 및 예시

VideoDB에서 해당 작업을 지원하는 경우 ffmpeg, moviepy 또는 로컬 인코딩 도구를 사용하지 마십시오. 다음은 모두 VideoDB에서 서버 측으로 처리됩니다. — 트리밍, 클립 결합, 오디오 또는 음악 오버레이, 자막 추가, 텍스트/이미지 오버레이, 트랜스코딩, 해상도 변경, 화면비 변환, 플랫폼 요구 사항에 따른 크기 조정, 텍스트 변환 및 미디어 생성. reference/editor.md의 ‘제한 사항’에 나열된 작업(전환 효과, 속도 변경, 자르기/확대/축소, 색보정, 볼륨 믹싱)에 대해서만 로컬 도구를 대체 수단으로 사용하십시오.

무엇을 언제 사용할지

문제 VideoDB 해결 방법
플랫폼에서 동영상 화면비나 해상도를 허용하지 않는 경우 video.reframe() 또는 conn.transcode() 다음과 같은 경우 VideoConfig
Twitter/Instagram/TikTok에 맞게 동영상 크기를 조정해야 함 video.reframe(target="vertical") 또는 target="square"
해상도를 변경해야 함 (예: 1080p → 720p) conn.transcode() 다음과 같이 VideoConfig(resolution=720)
동영상에 오디오/음악을 오버레이해야 하는 경우 AudioAsset 에 Timeline
자막을 추가해야 함 video.add_subtitle() 또는 CaptionAsset
클립을 합치거나 자르려면 VideoAsset 에 Timeline
보이스오버, 음악 또는 SFX 생성 coll.generate_voice(), generate_music(), generate_sound_effect()

출처

이 스킬에 대한 참조 자료는 로컬에서 다음 경로를 통해 제공됩니다 skills/videodb/reference/에서 판매되고 있습니다. 실행 시 외부 저장소 링크를 따르기보다는 위의 로컬 사본을 사용하십시오.

GitHub에서 보기
---
name: videodb
description: Ingest, index, search, edit, and generate video and audio content from files, URLs, live streams, or desktop capture.
---

# VideoDB Skill

**Perception + memory + actions for video, live streams, and desktop sessions.**

## When to use

### Desktop Perception
- Start/stop a **desktop session** capturing **screen, mic, and system audio**
- Stream **live context** and store **episodic session memory**
- Run **real-time alerts/triggers** on what's spoken and what's happening on screen
- Produce **session summaries**, a searchable timeline, and **playable evidence links**

### Video ingest + stream
- Ingest a **file or URL** and return a **playable web stream link**
- Transcode/normalize: **codec, bitrate, fps, resolution, aspect ratio**

### Index + search (timestamps + evidence)
- Build **visual**, **spoken**, and **keyword** indexes
- Search and return exact moments with **timestamps** and **playable evidence**
- Auto-create **clips** from search results

### Timeline editing + generation
- Subtitles: **generate**, **translate**, **burn-in**
- Overlays: **text/image/branding**, motion captions
- Audio: **background music**, **voiceover**, **dubbing**
- Programmatic composition and exports via **timeline operations**

### Live streams (RTSP) + monitoring
- Connect **RTSP/live feeds**
- Run **real-time visual and spoken understanding** and emit **events/alerts** for monitoring workflows

## How it works

### Common inputs
- Local **file path**, public **URL**, or **RTSP URL**
- Desktop capture request: **start / stop / summarize session**
- Desired operations: get context for understanding, transcode spec, index spec, search query, clip ranges, timeline edits, alert rules

### Common outputs
- **Stream URL**
- Search results with **timestamps** and **evidence links**
- Generated assets: subtitles, audio, images, clips
- **Event/alert payloads** for live streams
- Desktop **session summaries** and memory entries

### Running Python code

Before running any VideoDB code, change to the project directory and load environment variables:

```python
from dotenv import load_dotenv
load_dotenv(".env")

import videodb
conn = videodb.connect()
```

This reads `VIDEO_DB_API_KEY` from:
1. Environment (if already exported)
2. Project's `.env` file in current directory

If the key is missing, `videodb.connect()` raises `AuthenticationError` automatically.

Do NOT write a script file when a short inline command works.

When writing inline Python (`python -c "..."`), always use properly formatted code — use semicolons to separate statements and keep it readable. For anything longer than ~3 statements, use a heredoc instead:

```bash
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

When the user asks to "setup videodb" or similar:

### 1. Install SDK

```bash
pip install "videodb[capture]" python-dotenv
```

If `videodb[capture]` fails on Linux, install without the capture extra:

```bash
pip install videodb python-dotenv
```

### 2. Configure API key

The user must set `VIDEO_DB_API_KEY` using **either** method:

- **Export in terminal** (before starting Claude): `export VIDEO_DB_API_KEY=your-key`
- **Project `.env` file**: Save `VIDEO_DB_API_KEY=your-key` in the project's `.env` file

Get a free API key at [console.videodb.io](https://console.videodb.io) (50 free uploads, no credit card).

**Do NOT** read, write, or handle the API key yourself. Always let the user set it.

### Quick Reference

### Upload media

```python
# 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")
```

### Transcript + subtitle

```python
# 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()
```

### Search inside videos

```python
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
```

### Scene search

```python
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
```

### Timeline editing

**Important:** Always validate timestamps before building a timeline:
- `start` must be >= 0 (negative values are silently accepted but produce broken output)
- `start` must be < `end`
- `end` must be <= `video.length`

```python
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()
```

### Transcode video (resolution / quality change)

```python
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 aspect ratio (for social platforms)

**Warning:** `reframe()` is a slow server-side operation. For long videos it can take
several minutes and may time out. Best practices:
- Always limit to a short segment using `start`/`end` when possible
- For full-length videos, use `callback_url` for async processing
- Trim the video on a `Timeline` first, then reframe the shorter result

```python
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})
```

### Generative media

```python
image = coll.generate_image(
    prompt="a sunset over mountains",
    aspect_ratio="16:9",
)
```

## Error handling

```python
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}")
```

### Common pitfalls

| Scenario | Error message | Solution |
|----------|--------------|----------|
| Indexing an already-indexed video | `Spoken word index for video already exists` | Use `video.index_spoken_words(force=True)` to skip if already indexed |
| Scene index already exists | `Scene index with id XXXX already exists` | Extract the existing `scene_index_id` from the error with `re.search(r"id\s+([a-f0-9]+)", str(e))` |
| Search finds no matches | `InvalidRequestError: No results found` | Catch the exception and treat as empty results (`shots = []`) |
| Reframe times out | Blocks indefinitely on long videos | Use `start`/`end` to limit segment, or pass `callback_url` for async |
| Negative timestamps on Timeline | Silently produces broken stream | Always validate `start >= 0` before creating `VideoAsset` |
| `generate_video()` / `create_collection()` fails | `Operation not allowed` or `maximum limit` | Plan-gated features — inform the user about plan limits |

## Examples

### Canonical prompts
- "Start desktop capture and alert when a password field appears."
- "Record my session and produce an actionable summary when it ends."
- "Ingest this file and return a playable stream link."
- "Index this folder and find every scene with people, return timestamps."
- "Generate subtitles, burn them in, and add light background music."
- "Connect this RTSP URL and alert when a person enters the zone."

### Screen Recording (Desktop Capture)

Use `ws_listener.py` to capture WebSocket events during recording sessions. Desktop capture supports **macOS** only.

#### Quick Start

1. **Choose state dir**: `STATE_DIR="${VIDEODB_EVENTS_DIR:-$HOME/.local/state/videodb}"`
2. **Start listener**: `VIDEODB_EVENTS_DIR="$STATE_DIR" python scripts/ws_listener.py --clear "$STATE_DIR" &`
3. **Get WebSocket ID**: `cat "$STATE_DIR/videodb_ws_id"`
4. **Run capture code** (see reference/capture.md for the full workflow)
5. **Events written to**: `$STATE_DIR/videodb_events.jsonl`

Use `--clear` whenever you start a fresh capture run so stale transcript and visual events do not leak into the new session.

#### Query Events

```python
import json
import os
import time
from pathlib import Path

events_dir = Path(os.environ.get("VIDEODB_EVENTS_DIR", Path.home() / ".local" / "state" / "videodb"))
events_file = events_dir / "videodb_events.jsonl"
events = []

if events_file.exists():
    with events_file.open(encoding="utf-8") as handle:
        for line in handle:
            try:
                events.append(json.loads(line))
            except json.JSONDecodeError:
                continue

transcripts = [e["data"]["text"] for e in events if e.get("channel") == "transcript"]
cutoff = time.time() - 300
recent_visual = [
    e for e in events
    if e.get("channel") == "visual_index" and e["unix_ts"] > cutoff
]
```

## Additional docs

Reference documentation is in the `reference/` directory adjacent to this SKILL.md file. Use the Glob tool to locate it if needed.

- [reference/api-reference.md](reference/api-reference.md) - Complete VideoDB Python SDK API reference
- [reference/search.md](reference/search.md) - In-depth guide to video search (spoken word and scene-based)
- [reference/editor.md](reference/editor.md) - Timeline editing, assets, and composition
- [reference/streaming.md](reference/streaming.md) - HLS streaming and instant playback
- [reference/generative.md](reference/generative.md) - AI-powered media generation (images, video, audio)
- [reference/rtstream.md](reference/rtstream.md) - Live stream ingestion workflow (RTSP/RTMP)
- [reference/rtstream-reference.md](reference/rtstream-reference.md) - RTStream SDK methods and AI pipelines
- [reference/capture.md](reference/capture.md) - Desktop capture workflow
- [reference/capture-reference.md](reference/capture-reference.md) - Capture SDK and WebSocket events
- [reference/use-cases.md](reference/use-cases.md) - Common video processing patterns and examples

**Do not use ffmpeg, moviepy, or local encoding tools** when VideoDB supports the operation. The following are all handled server-side by VideoDB — trimming, combining clips, overlaying audio or music, adding subtitles, text/image overlays, transcoding, resolution changes, aspect-ratio conversion, resizing for platform requirements, transcription, and media generation. Only fall back to local tools for operations listed under Limitations in reference/editor.md (transitions, speed changes, crop/zoom, colour grading, volume mixing).

### When to use what

| Problem | VideoDB solution |
|---------|-----------------|
| Platform rejects video aspect ratio or resolution | `video.reframe()` or `conn.transcode()` with `VideoConfig` |
| Need to resize video for Twitter/Instagram/TikTok | `video.reframe(target="vertical")` or `target="square"` |
| Need to change resolution (e.g. 1080p → 720p) | `conn.transcode()` with `VideoConfig(resolution=720)` |
| Need to overlay audio/music on video | `AudioAsset` on a `Timeline` |
| Need to add subtitles | `video.add_subtitle()` or `CaptionAsset` |
| Need to combine/trim clips | `VideoAsset` on a `Timeline` |
| Need to generate voiceover, music, or SFX | `coll.generate_voice()`, `generate_music()`, `generate_sound_effect()` |

## Provenance

Reference material for this skill is vendored locally under `skills/videodb/reference/`.
Use the local copies above instead of following external repository links at runtime.

videodb 설치

스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.

ZIP 다운로드

저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.

git clone https://github.com/affaan-m/ECC/tree/main/skills/videodb # Copy SKILL.md to your .claude/skills/ directory

복사 복사
빠른 설정: 스킬 폴더를 .claude/skills/로 복사하세요. Claude가 해당 스킬을 자동으로 감지하여 사용할 것입니다.
저장소 affaan-m/ECC

관련 스킬

agentwallet
업데이트 된 시간 2026년 7월 7일
brightdata-cli
업데이트 된 시간 2026년 6월 29일
humanize
업데이트 된 시간 2026년 7월 7일
korean-stock-search
업데이트 된 시간 2026년 7월 8일
OR