ブログ一覧

Claude Code に YouTube 動画編集を任せた

更新: Web開発者向け

YouTube 用の動画編集を Claude Code(Anthropic のコーディング用 AI エージェント)に任せました。どの場面を使い、どこを早送りし、重量をどう表示するかという判断だけを動画ごとの設定ファイル(JSON)1つに書かせ、切り貼り・BGM・書き出しは Claude Code がその場で書いた Python のスクリプトに任せています。同じ設定ファイルから作り直すと、完成動画・BGM・重量表示・サムネイルは OK を出した版とバイト単位で一致しました。判断が設定ファイルに残っていれば、LLM に頼らずに同じ動画を作り直せます。

素材は、自宅の筋トレを定点長回し(カメラを1か所に固定し、最初から最後まで止めずに撮った動画)で撮った60分07秒の動画です。Mac の動画フォルダに置き、細かい指定はせず、YouTube 用に編集してと一言頼みました。Claude のアプリから Remote Control(Claude のアプリから、自分の端末のフォルダで Claude Code を動かす機能)を使い、Mac のそのフォルダで動かしています。

約16分で、私が映っていない無人の時間を落とした18分44秒版が返り、注文3回で4分27秒の完成版になりました。私が出した注文は、次の3つです。

  • 構成と BGM・サムネイルの注文(長さは5分程度に、字幕は無し、BGM がほしい、サムネイルを作ってほしい)
  • 失敗したセットのカット
  • 最後の場面のカットと重量表示

依頼から完成までの約1時間40分で、私がしたのは仕上がりを見て注文と OK を返すことだけです。タイトルと概要欄もそのまま使いました。

半分は Claude Code の判断で、半分はスクリプトの機械処理だった

仕上がったあと、これは Claude Code の性能に頼って作れたのか、それとも機械的に作れたのかが気になり、Claude Code 自身に聞いてみました。答えは半々で、機械的な部分と判断の部分が次のように分かれるというものでした。

  • 機械的(スクリプトだけで同じ結果が出る): 動きと音量の解析、無人の時間やデスクで PC を見ている時間(カメラの手前に私の PC デスクが映っている)の除外、決めた区間どおりの切り貼り・早送り、BGM の合成と音量調整、書き出し、重量表示とサムネイルの画像作成
  • 判断が要る(Claude Code の目に頼った): どこがセットかの特定、失敗セットの判別、トレーニング後に服を脱ぎ始める場面を映さないための終わりの切りどころ、サムネイルに使うコマの選択、タイトルと概要欄の文面

約5分に縮める場面選びは判断で、それを毎回同じ品質で形にするのは Claude Code 自身が書いたスクリプトです。

判断の出口を設定ファイル1つに絞り、その先は同じ物を出す道具にした

どうやって動かしたかは、次の流れです。

  1. Claude のアプリから Remote Control で、Mac の動画フォルダの Claude Code に依頼する
  2. Claude Code がその場で Python のスクリプトを書く
  3. 動画は再生して見るのではなく、下調べのスクリプトが書き出す2秒ごとのコマ一覧の静止画と時刻の対応表を Claude Code が読んで、どこで何をしているかを判断する。音は聴けないので、BGM の良し悪しは私が聴いて判断する
  4. 判断した使う区間や重量表示の文字を設定ファイルに書き、1つのコマンドで動画・サムネイル・BGM・重量表示を一括で作る

動画フォルダには、Claude Code が作業を始めるときに自動で読む CLAUDE.md(方針と判断の基準を書いておくファイル)などがあり、次のような構成です(どの会話から頼んでも前回までを引き継げるよう、GitHub の非公開リポジトリに置いています)。

<動画フォルダ>/
├── CLAUDE.md                方針と判断基準(Claude Code が最初に読む)
├── README.md                手順
├── pyproject.toml
├── src/workout_video/       道具(動画に依存しない)
│   ├── project.py           設定ファイルの読み込みと検証
│   ├── ffmpeg.py            ffmpeg の呼び出し(外部コマンドはここだけ)
│   ├── analysis.py          下調べ(動き・音量の解析とコマ一覧)
│   ├── render.py            書き出し(フィルタの組み立ては純粋関数)
│   └── cli.py               コマンド
├── tests/
└── videos/<日付>/           動画1本ごと
    ├── <日付>.mov           元動画(git の対象外。中身は編集しない)
    ├── video.json           この回の判断(使う区間・重量・サムネイル・BGM)
    ├── notes.md             作業記録、指摘されて直したこと、YouTube のタイトルと概要欄
    └── out/                 完成物(git の対象外)

LLM が手作業で切り貼りすると結果がぶれて遅くなるので、作業は道具に任せています。判断の出口は、動画ごとの設定ファイル(JSON)1つに絞っています。中身は使う区間・速度・重量表示・サムネイル・BGM の設定値で、Claude Code が書くのはここだけ、あとは1つのコマンドで動画・サムネイル・BGM・重量表示がすべて出来上がります。設定ファイルは読み込み時に不備をまとめて報告し、書き出し前にタイムラインを確認できます。

最初の1本はばらばらのスクリプトで作り、OK を出したあとで1つのパッケージ(上のツリーの「道具」)に整えました。この道具で同じ動画を作り直すと、完成動画・BGM・重量表示・サムネイルが OK を出した版とバイト単位で一致しました。

ライブラリは numpy と Pillow だけで、残りは ffmpeg が担う

実行時の依存ライブラリは numpy と Pillow の2つだけで、映像と音の処理は ffmpeg が担います。動画編集ソフトや外部の生成 AI サービスは使っていません。各工程は、次のように動いています。

  • 下調べ: 動画を4fps に縮め、画素の変化と音量が一定を超える区間だけを残す
  • 書き出し: 使う区間をつなぎ、休憩は8倍速で約4秒にして、1080p・YouTube の基準の音量(-14 LUFS。人が感じる音の大きさの単位)で書き出す
  • 重量表示とサムネイル: Homebrew で入れた ffmpeg には文字を動画に描く機能(drawtext フィルタ)が入っていないため、Pillow で文字の画像を作って重ねる
  • BGM: numpy で合成する自作曲で、著作権の申し立ての心配が無い

場面選びはルールにせず、判断の基準だけを文書に残した

次の動画でも同じように場面を選べるように、判断の基準を動画フォルダの CLAUDE.md に書きました。

  • 場面選びは毎回映像を見て判断する(ベンチやダンベルに限らない)
  • セットは同じ動作を繰り返している区間で、構えから置くまでを含める
  • 種目や重量が分からなければ推測で進め、確認はまとめて聞く
  • 迷った場面は外して報告する

判断の精度はその時のモデル次第で、私が完成品を見て OK を出す確認で補っています。Claude Code は「ベンチ付近の動きが20秒以上続けばセット、短ければ失敗」という固定ルールへの機械化を提案しましたが、筋トレは毎回ベンチを使うわけでも、毎回ダンベルを使うわけでもないので、私はこれを採りませんでした。

指摘は、その場の修正で終わらせず設計に戻した

5分版の最初の案は7セットで、1セット目はベンチに寝てすぐ起き上がった失敗でした。私が指摘し、Claude Code が外して6セットになりました。この指摘は「すぐ中断した短いセットは失敗としてカットする」という方針として CLAUDE.md に書き足しました。

参考リンク

関連

この記事をシェア