01素材
試合動画をPCに置く
スマホやカメラから取り込んだ元動画を、そのまま手元に保存します。
match.mp4動画そのものは各ユーザーのPCに置いたまま。ローカルAIで得点タイミングJSONを作り、ブラウザで微修正し、その場でスコアボード入り動画を書き出します。
スマホやカメラから取り込んだ元動画を、そのまま手元に保存します。
match.mp4Claude Codeなどでスコア表を読み、得点タイミングの候補をJSON化します。
timeline.jsonページ上で動画ファイルを選び、JSONはファイル選択またはペーストで読み込みます。
アップロードなしタイムライン上の点をドラッグ。クリック&ドラッグで動画をスクラブできます。
0.1秒調整位置・サイズ・表示範囲を調整。プレビューはその場で反映されます。
Scale / X / Y動画フレームとSVGスコアボードをCanvasで合成し、WebMとして保存します。
scored.webm動画ファイルをローカルAIに読ませられる環境で、右のプロンプトをそのまま渡します。 出てきたJSONをこのWebツールに読み込ませると、タイムライン上に得点候補が並びます。
あなたはローカルPC上の動画ファイルを扱えるAIアシスタントです。
Claude Code、ChatGPT、Gemini、Cursor、その他のAIエージェントのどれであっても構いません。
このセッションに過去の文脈が一切ない前提で、以下の手順だけを頼りに作業してください。
目的:
ユーザーPC上のテニス動画を解析し、Fleek Tennis Toolで読み込める timeline JSON を生成する。
最終的に必要なのはJSONだけ。返答にはJSONだけを出力する。
ユーザーが書き換える入力:
- video: "match.mp4"
- tournament: "FLEEK CUP"
- round: "MATCH"
- team1: "Team1名"
- team2: "Team2名"
- format: "1set"
- firstServer: 1
Team定義:
- winner: 1 は team1 の得点。
- winner: 2 は team2 の得点。
- 動画内のスコア表示は参照しない前提。
- ユーザー指定のチーム配置、サーブ順、選手の位置、ラリー終了後の反応を手がかりに winner を推定する。
- 不明な点は削除せず、confidenceを下げて残す。
出力:
- ファイル保存は不要。
- LLMの最終返答としてJSON全文だけを出力する。
- Markdownコードフェンス、説明文、補足コメントは付けない。
- JSONとしてそのままパースできる形にする。
JSONスキーマ:
{
"source": "local-ai-subagents",
"video": "match.mp4",
"match": {
"tournament": "FLEEK CUP",
"round": "MATCH",
"team1": "Team1名",
"team2": "Team2名",
"format": "1set",
"firstServer": 1
},
"points": [
{ "t": "0:12.3", "winner": 1, "confidence": 0.82, "note": "任意の短い根拠" }
],
"visibilityRanges": [
{ "start": 0, "end": 120 }
]
}
厳守:
- points は時刻昇順。
- t は "分:秒" または "分:秒.小数"。
- winner は数値の 1 または 2。
- confidence は 0〜1。
- note は任意。分からない場合は省略してよい。
- 末尾カンマは禁止。
- JSON以外の説明をJSONファイル内に入れない。
推奨ワークフロー:
1. ffprobe で動画の長さ、fps、解像度を確認する。
2. 必要なら作業用ディレクトリ .fleek-detect を作る。
3. ffmpeg で確認用フレームを抽出する。
- まず 5秒間隔で全体フレームを抽出する。
- 例:
ffmpeg -i match.mp4 -vf "fps=1/5,scale=960:-1" .fleek-detect/frame-%04d.jpg
4. 複数エージェント、サブエージェント、並列タスク、別チャットなどを使える場合は、動画を時間帯ごとに分割して並列に読む。
- 使えない場合は、同じ作業を1区間ずつ順番に行う。
- 1担当あたり 1〜3分程度を読む。
- 各担当には、その区間のフレーム一覧を見せる。
- 各担当の出力は「観測状態列」にする。
区間担当AIへの依頼テンプレート:
あなたはテニス動画の一部区間だけを読む担当AIです。
担当区間: START_SEC〜END_SEC秒。
渡されたフレームを時刻順に見て、スコア状態の変化を観測してください。
返答はJSON配列のみ:
[
{
"t": 35.0,
"visible": true,
"team1Games": 0,
"team1Points": "15",
"team2Games": 0,
"team2Points": "0",
"server": 1,
"confidence": 0.8,
"evidence": "スコア表が15-0に見える"
}
]
注意:
- 得点そのものではなく、その時刻に見えているスコア状態を読む。
- 読めないフレームは visible:false にする。
- 推測ならconfidenceを下げる。
- 返答に説明文を混ぜない。
統合作業:
1. 全担当AI、または自分で順番に読んだ全区間の観測状態を時刻順に並べる。
2. 同じスコア状態が連続している場合は1つに畳む。
3. 状態Aから状態Bへ遷移する間に入った得点を推定する。
4. 得点タイミングは、状態変化が初めて観測された時刻の少し前を候補にする。
- 5秒間隔観測なら、前状態の時刻と新状態の時刻の中間を初期候補にする。
- ラリー終了や拍手、選手の反応が見える場合はその瞬間へ寄せる。
5. サーバー交代やゲーム取得と矛盾しないか確認する。
6. 迷う点は削除せず、confidenceを下げて残す。ブラウザ上で人間が修正する。
精度を上げるコツ:
- 動画内のスコア表示には頼らない。ラリー終了、拍手、ボール回収、次サーブ位置、選手の表情や移動を手がかりにする。
- 状態変化の直前直後だけ、追加で1秒間隔または0.5秒間隔のフレームを抽出して再確認する。
- 自信がない場合は confidence を 0.4〜0.6 にする。
検証:
1. 作成したJSONをローカルで JSON.parse できることを確認する。
2. points が時刻昇順であることを確認する。
3. winner が 1 または 2 以外になっていないことを確認する。
4. visibilityRanges が空なら、動画全体を覆う { "start": 0, "end": 動画秒数 } を入れる。
最終出力:
JSON全文のみを返す。