FC Fleek Tennis Tool
エディタを開く

新しい試合動画を編集する流れ

動画そのものは各ユーザーのPCに置いたまま。ローカルAIで得点タイミングJSONを作り、ブラウザで微修正し、その場でスコアボード入り動画を書き出します。

Local video動画はアップロードしない
Local AIJSONだけを生成
Browser editタイミングを微調整
WebM exportブラウザ内で合成
FLEEK CUPPREVIEW
Team1
1
40
Team2
0
30

全体フロー

AIは下処理、ブラウザは編集と出力
01素材

試合動画をPCに置く

スマホやカメラから取り込んだ元動画を、そのまま手元に保存します。

match.mp4
02AI下処理

ローカルAIで得点候補を作る

動画のラリー終了や選手の反応を読み、得点タイミングの候補をJSON化します。

timeline.json
03読込

ブラウザに動画とJSONを入れる

ページ上で動画ファイルを選び、JSONはファイル選択またはペーストで読み込みます。

アップロードなし
04調整

得点タイミングを微修正

タイムライン上の点をドラッグ。クリック&ドラッグで動画をスクラブできます。

0.1秒調整
05見た目

スコアボードを合わせる

位置・サイズ・表示範囲を調整。プレビューはその場で反映されます。

Scale / X / Y
06出力

ブラウザで合成して書き出す

動画フレームとSVGスコアボードをCanvasで合成し、WebMとして保存します。

scored.webm

タイムラインで触るもの

点は得点、黄色帯はスコアボードの表示範囲
0:00
0:30
1:00
1:30
2:00

ローカルAIに渡すプロンプト

まず荒く作って、ブラウザで人間が微修正する前提

使い方

動画ファイルをローカルAIに読ませられる環境で、右のプロンプトをそのまま渡します。 出てきたJSONをこのWebツールに読み込ませると、タイムライン上に得点候補が並びます。

  • 区間ごとに得点イベント候補を読ませ、最後に1つのJSONへ統合します。
  • 得点タイミングはできるだけ近づけつつ、最後はブラウザでドラッグ調整します。
  • winner は 1 が Team1、2 が Team2 です。Team1はスコアカード上段・最初のサーバー側です。
  • 動画ファイル名、チーム名、試合情報だけ自分の動画に合わせて書き換えます。
  • 出力JSONはこのページでファイル選択またはペーストできます。
COPY PROMPT
あなたは動画ファイルを扱えるAIアシスタントです。
以下の手順を参考に作業してください。

目的:
テニス動画を解析し、timeline JSON を生成する。
最終的に必要なのはJSONだけ。返答にはJSONだけを出力する。

ユーザーが書き換える入力:
- video: "match.mp4"
- tournament: "FLEEK CUP"
- round: "MATCH"
- team1: "Team1"
- team2: "Team2"
- format: "1set"
- scoringRule: "no-ad"
- matchStartAt: "0:00.0"
- firstServer: 1

Team定義:
- winner: 1 は team1 の得点。
- winner: 2 は team2 の得点。
- team1 はファーストサービスのチーム。スコアカード上段に表示する。
- team2 はもう一方のチーム。スコアカード下段に表示する。
- Upper/Lower はチーム名ではなく、動画画面内のコート位置を表す。upper は画面上側、lower は画面下側。
- 最初の得点ピンには、team1 が最初に Upper/Lower どちら側からサーブしたかを serverCourtSide: "upper" または "lower" で入れる。
- serverCourtSide は team1/team2 の名前を入れ替えるためには使わない。あくまでサーブ位置の記録として使う。
- 練習風景が動画先頭にある場合、試合開始または最初のサーブ時刻を matchStartAt に入れる。
- firstServer は通常 1。
- scoringRule は "no-ad" または "advantage"。指定がなければ "no-ad"。
- 動画内のスコア表示は参照しない前提。
- ユーザー指定のチーム配置、サーブ順、選手の位置、ラリー終了後の反応を手がかりに winner を推定する。
- 得点後または次ポイント開始時のサーバーが分かる場合は serverAfter: 1 または 2 を入れる。
- サーブ動作またはインパクトの時刻が分かる場合は serveAt を入れる。ジェットカットは serveAt の2秒前から始まる。
- 不明な点は削除せず、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",
    "scoringRule": "no-ad",
    "matchStartAt": "0:00.0",
    "firstServer": 1
  },
  "points": [
    { "t": "0:12.3", "serveAt": "0:05.1", "serverCourtSide": "upper", "winner": 1, "confidence": 0.82, "serverAfter": 1, "note": "任意の短い根拠" }
  ],
  "visibilityRanges": [
    { "start": 0, "end": 120 }
  ]
}

厳守:
- points は時刻昇順。
- t は "分:秒" または "分:秒.小数"。
- serveAt は任意。サーブ動作またはインパクトの時刻を "分:秒" または "分:秒.小数" で入れる。
- serverCourtSide は任意。ただし最初の得点ピンには必ず入れる。値は "upper" または "lower"。
- winner は数値の 1 または 2。
- confidence は 0〜1。
- serverAfter は任意。得点後または次サーブのサーバーが見える場合だけ 1 または 2 を入れる。
- 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,
    "serveAt": 27.4,
    "serverCourtSide": "upper",
    "winner": 1,
    "serverAfter": 1,
    "confidence": 0.8,
    "evidence": "ラリー終了後にteam1側がポイント取得した反応がある"
  }
]
注意:
- 動画内のスコア表示には頼らない。
- 得点が確定した瞬間、またはその直後の選手の反応を手がかりにする。
- サーブ開始またはインパクトが見える場合は serveAt として記録する。
- サーブした側が画面上側なら serverCourtSide:"upper"、画面下側なら serverCourtSide:"lower" を入れる。特に最初の得点候補では必須。
- 得点後、次にサーブする側が分かる場合は serverAfter に入れる。サーバーが変わった場合はゲーム取得の可能性が高い。
- winner が不明な候補も削除せず、推定してconfidenceを下げる。
- 推測ならconfidenceを下げる。
- 返答に説明文を混ぜない。

統合作業:
1. 全担当AI、または自分で順番に読んだ全区間の得点イベント候補を時刻順に並べる。
2. 同じ得点を複数候補として拾っている場合は、最も確からしい1件に畳む。
3. 得点タイミングは、ラリーが終わり得点が確定した瞬間、またはその直後を候補にする。
4. scoringRule と firstServer を使い、サーブ交代、次のサーブ位置、選手の反応と矛盾しないか確認する。
   - no-ad では 40-40 の次点でゲームが終わり、サーバーが交代する。
   - advantage では 40-40 の次点はADになり、ゲーム終了とは限らない。
   - winner が怪しい低confidence候補は、serverAfter とゲーム取得タイミングの辻褄を優先して判断する。
5. 迷う点は削除せず、confidenceを下げて残す。ブラウザ上で人間が修正する。

精度を上げるコツ:
- 動画内のスコア表示には頼らない。ラリー終了、拍手、ボール回収、次サーブ位置、選手の表情や移動を手がかりにする。
- 得点候補の直前直後だけ、追加で1秒間隔または0.5秒間隔のフレームを抽出して再確認する。
- 自信がない場合は confidence を 0.4〜0.6 にする。

検証:
1. 作成したJSONをローカルで JSON.parse できることを確認する。
2. points が時刻昇順であることを確認する。
3. winner が 1 または 2 以外になっていないことを確認する。
4. serverAfter を入れる場合は 1 または 2 以外になっていないことを確認する。
5. serveAt がある場合は、同じ point の t より後になっていないことを確認する。
6. 最初の points[0] に serverCourtSide があることを確認する。
7. visibilityRanges が空なら、動画全体を覆う { "start": 0, "end": 動画秒数 } を入れる。

最終出力:
JSON全文のみを返す。

役割分担

重いAI処理は各自の環境、編集は共通URL

ユーザーのPC

  • 元動画を保持
  • 動画ファイルをブラウザに選択
  • WebMを書き出し保存

ユーザーのAI

  • 得点タイミング候補を検出
  • timeline.jsonを生成
  • 必要なら再検出だけやり直す

FleekのWebツール

  • 動画とJSONをローカル読込
  • タイムラインで微調整
  • スコアボードを合成表示

新規動画でやること

実作業チェックリスト
1. AIにJSONを作らせる動画名、チーム名、得点時刻、勝者を入れたJSONを用意します。
2. ブラウザで合わせる得点点をドラッグして、スコアが切り替わる瞬間を目で合わせます。
3. WebMを書き出す位置・音量・可視範囲を確認して、ブラウザで合成出力します。