Communitygithub.com

DekaPrayoga/AurixAgent

ビデオとオーディオを認識、理解、操作します。ローカルファイル、URL、RTSP/ライブフィードからの取り込み、またはデスクトップのライブ録画を行い、リアルタイムコンテキストと再生可能なストリームリンクを返します。フレーム抽出、視覚・意味・時間インデックスの構築、タイムスタンプと自動クリップによる瞬間検索、トランスコードと正規化、タイムライン編集、メディアアセット生成、ライブストリームやデスクトップキャプチャからのイベントに対するリアルタイムアラートを実行します。

AurixAgent とは?

このスキルは、VideoDB プラットフォームを活用して、ビデオ、ライブストリーム、デスクトップセッションのための知覚、記憶、アクションを提供します。主な機能は次のとおりです。ファイル/URL/RTSP/デスクトップの取り込み、再生可能なストリームリンク生成、トランスコード(コーデック、FPS、解像度、アスペクト比)、視覚・音声・キーワードインデックス構築、タイムスタンプ付きの瞬間検索と自動クリップ作成、字幕生成/翻訳/焼き込み、テキスト/画像/ブランディングオーバーレイ、音声/吹き替え/翻訳、画像/音声/ビデオ生成、ライブストリームとデスクトップキャプチャからのリアルタイムイベント/アラートです。Claude CodeやCursorなどのAIエージェント向けに設計されており、セットアップは `pip install videodb[capture] python-dotenv` と `VIDEO_DB_API_KEY` 環境変数または `.env` ファイルで行います。SDKはPythonで、アップロード、インデックス、検索、タイムライン編集、トランスコード、メディア生成のためのシンプルなAPIを提供します。エラーハンドリング、タイムスタンプ検証、一定の操作(リフレームなど)の制限に対応したベストプラクティスが組み込まれており、ローカルのffmpegやmoviepyに頼ることなく、ほとんどのビデオ処理をサーバーサイドで処理します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/DekaPrayoga/AurixAgent/tree/HEAD/skills/videodb

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

VideoDB スキル

ビデオ、ライブストリーム、デスクトップセッションに対する認識 + メモリ + アクション。

使用するタイミング

デスクトップ認識

  • 画面、マイク、システムオーディオをキャプチャするデスクトップセッションの開始/停止
  • ライブコンテキストのストリーミングとエピソード的セッションメモリの保存
  • 画面上で話されている内容や発生しているイベントに対するリアルタイムアラート/トリガーの実行
  • セッションサマリー、検索可能なタイムライン、再生可能なエビデンスリンクの生成

ビデオ取り込み + ストリーム

  • ファイルまたはURLを取り込み、再生可能なWebストリームリンクを返す
  • トランスコード/正規化: コーデック、ビットレート、FPS、解像度、アスペクト比

インデックス + 検索 (タイムスタンプ + エビデンス)

  • 視覚、音声、キーワードインデックスを構築
  • 正確な瞬間をタイムスタンプと再生可能なエビデンスで検索して返す
  • 検索結果からクリップを自動生成

タイムライン編集 + 生成

  • 字幕: 生成、翻訳、焼き込み
  • オーバーレイ: テキスト/画像/ブランディング、モーションキャプション
  • オーディオ: BGM、ナレーション、吹き替え
  • タイムライン操作によるプログラム的な合成とエクスポート

ライブストリーム (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(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

Linuxで videodb[capture] が失敗した場合、capture拡張なしでインストール:

pip install videodb python-dotenv

2. APIキーの設定

ユーザーは 以下のいずれか の方法で VIDEO_DB_API_KEY を設定する必要があります:

  • ターミナルでエクスポート(Claude起動前): export VIDEO_DB_API_KEY=your-key
  • プロジェクトの .env ファイル: プロジェクトの .env ファイルに VIDEO_DB_API_KEY=your-key を保存

無料のAPIキーは console.videodb.io で取得できます(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")

# ローカルファイル
video = coll.upload(file_path="/path/to/video.mp4")

トランスクリプト + 字幕

# force=True は、ビデオがすでにインデックスされている場合のエラーをスキップします
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() は結果が見つからない場合に InvalidRequestError を発生させます。
# 常に try/except でラップし、「結果なし」を空として扱います。
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() には force パラメータがありません — シーンインデックスがすでに存在する場合はエラーを発生させます。
# エラーから既存のインデックスIDを抽出します。
try:
    scene_index_id = video.index_scenes(
        extraction_type=SceneExtractionType.shot_based,
        prompt="このシーンの視覚的な内容を説明してください。",
    )
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

# score_threshold を使用して低関連性のノイズをフィルタリングします(推奨: 0.3以上)
try:
    results = video.search(
        query="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

# 解像度、品質、アスペクト比をサーバーサイドで変更
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

# 常に短いセグメントのリフレームを優先:
reframed = video.reframe(start=0, end=60, target="vertical", mode=ReframeMode.smart)

# フルレングスビデオの非同期リフレーム(Noneを返し、結果はwebhook経由):
video.reframe(target="vertical", callback_url="https://example.com/webhook")

# プリセット: "vertical" (9:16), "square" (1:1), "landscape" (16:9)
reframed = video.reframe(start=0, end=60, target="square")

# カスタムサイズ
reframed = video.reframe(start=0, end=60, target={"width": 1280, "height": 720})

生成メディア

image = coll.generate_image(
    prompt="山の上の夕日",
    aspect_ratio="16:9",
)

エラーハンドリング

from videodb.exceptions import AuthenticationError, InvalidRequestError

try:
    conn = videodb.connect()
except AuthenticationError:
    print("VIDEO_DB_API_KEY を確認してください")

try:
    video = coll.upload(url="https://example.com/video.mp4")
except InvalidRequestError as e:
    print(f"アップロード失敗: {e}")

よくある落とし穴

シナリオエラーメッセージ解決策
すでにインデックスされているビデオにインデックスSpoken word index for video already existsvideo.index_spoken_words(force=True) を使用して、すでにインデックスされている場合はスキップ
シーンインデックスがすでに存在するScene index with id XXXX already existsre.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プランで制限される機能 — プラン制限についてユーザーに通知

例

正規のプロンプト

  • "デスクトップキャプチャを開始し、パスワードフィールドが表示されたらアラート"
  • "セッションを録画し、終了時に実用的なサマリーを生成"
  • "このファイルを取り込み、再生可能なストリームリンクを返す"
  • "このフォルダをインデックスし、人物が写っているすべてのシーンを見つけてタイムスタンプを返す"
  • "字幕を生成し、焼き込み、軽めのBGMを追加"
  • "この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
]

追加ドキュメント

リファレンスドキュメントは、この SKILL.md ファイルと同じディレクトリの reference/ にあります。必要に応じて Glob ツールを使用して見つけてください。

VideoDB が操作をサポートしている場合は、ffmpeg、moviepy、またはローカルエンコーディングツールを使用しないでください。 以下はすべて VideoDB によってサーバーサイドで処理されます: トリミング、クリップの結合、オーディオまたは音楽のオーバーレイ、字幕の追加、テキスト/画像オーバーレイ、トランスコード、解像度変更、アスペクト比変換、プラットフォーム要件に合わせたリサイズ、文字起こし、メディア生成。reference/editor.md の「制限事項」にリストされている操作(トランジション、速度変更、クロップ/ズーム、カラーグレーディング、ボリュームミキシング)にのみローカルツールを使用してください。

何をいつ使うか

問題VideoDB の解決策
プラットフォームがビデオのアスペクト比または解像度を拒否するvideo.reframe() または VideoConfig を指定した 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()

出典

このスキルのリファレンスマテリアルは、skills/videodb/reference/ の下にローカルでベンダリングされています。 実行時に外部リポジトリリンクをたどる代わりに、上記のローカルコピーを使用してください。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

関連スキル