YouTube料理動画40本をObsidianレシピノートに自動変換する仕組みを作った

YouTubeの「後で作ろう」再生リストが43本に膨れ上がっていた。料理動画を保存するだけ保存して、結局キッチンで「あのレシピなんだっけ」とスマホでYouTubeを開き直す、というのを何度繰り返したかわからない。レシピは普段Obsidianで管理しているので、動画の中身をObsidianのノートに変換できれば解決する。Cowork(Claudeのデスクトップ版)でやってみたら、思ったより紆余曲折があって面白かったので記録しておく。

まず1本やってみた

最初は素朴に、Coworkに動画URLを渡して「このレシピをObsidianに入れて」と頼んだ。笠原将弘さんの自家製なめたけの動画。CoworkはChromeの拡張を通じてYouTubeを開けるので、説明欄を読んだりWebで補足情報を検索したりして、なんとか1本分のレシピを作ってくれた。

ただこの方法には致命的な問題がある。1本あたりのトークン消費がえぐい。ブラウザ操作、ページ取得、Web検索、テキスト整形。これを43本繰り返したらセッションの上限に余裕で到達する。別のアプローチが必要だった。

ローカルwhisperで文字起こしする

トークンを大量に消費しているのは「動画の中身を知る」部分だ。ここをローカルで済ませれば、Claudeに渡すのは短いテキストだけになる。

MacBook Neo(A18 Pro / 8GB)で動くか気になったが、Whisperのmediumモデル(750MB)なら余裕だった。Apple Siliconの Neural Engine のおかげで、12分の動画が1〜3分で文字起こしできる。

使ったのは yt-dlp(YouTubeから音声だけ抽出)と mlx-whisper(Apple Silicon最適化されたWhisper実装)の2つ。

ただしセットアップが一筋縄ではいかなかった。まず yt-dlp が ffmpeg を要求するのでそれも入れ、mlx-whisper を入れようとしたら pip が古くてアップグレードから。さらにシステムの Python が 3.9 で、mlx-whisper が要求する 3.10+ を満たさない。Homebrew で Python 3.12 を入れたら今度は PEP 668 の externally-managed-environment に弾かれる。結局 venv を切って解決した。

brew install yt-dlp ffmpeg python@3.12
python3.12 -m venv ~/scripts/.venv
source ~/scripts/.venv/bin/activate
pip install mlx-whisper

こういう「本題にたどり着く前の環境構築で時間が溶ける」のは相変わらずである。

Coworkのサンドボックスの壁

当初はCoworkのLinuxサンドボックス内でyt-dlpもwhisperも動かそうとしたが、YouTubeへのアクセスがプロキシで弾かれた。サンドボックスからは外部サイトに自由にアクセスできない仕様らしい。そのため、音声ダウンロードと文字起こしはMacローカルで実行し、テキストだけをCoworkに渡す構成にした。

ollamaを試して、やめた

文字起こしテキストからレシピ形式への変換もローカルで完結させたくて、ollamaでgemma3:4bを動かしてみた。動くには動くが、料理の文字起こしから材料と手順を正確に抜き出す精度がいまいち。特に分量の聞き取りや、雑談とレシピ部分の切り分けが甘い。

結局、文字起こし(重い処理)はローカルのwhisper、レシピ整形(知的な処理)はClaudeという分担に落ち着いた。餅は餅屋である。

Coworkスキルにした

Coworkには「スキル」という仕組みがある。タスクのやり方をMarkdownで記述しておくと、「レシピ化して」と言うだけで、そのスキルに従って処理してくれる。

今回作ったスキルの中身はシンプルで、_transcripts/ にある文字起こしテキストを読み、既存レシピのフォーマット(frontmatter + 材料リスト + 手順)に合わせて変換し、Obsidianフォルダに保存する。スキルには既存レシピの実例も埋め込んであるので、フォーマットのブレが少ない。

Claude CLIで全自動化

最後のピースはClaude Code CLI。ターミナルから claude -p でプロンプトを渡せるので、シェルスクリプトで全部つなげた:

#!/bin/bash
URL="${1:-https://www.youtube.com/playlist?list=PLh4huXs8Qi9HkMIXptPbw2gIYUDNtqNic}"

# Step 1: ローカルで文字起こし(進捗が見える)
"$HOME/scripts/.venv/bin/python3" ~/scripts/transcribe.py "$URL"
if [ $? -ne 0 ]; then
  echo "文字起こしでエラーが発生しました。中断します。"
  exit 1
fi

# Step 2: Claude CLIでレシピ化
claude -p "_transcripts内の.txtをObsidianレシピ形式に変換して保存して"

Step 1ではwhisperの進捗が [1/43], [2/43] と表示され、Step 2でClaude CLIがまとめてレシピに変換する。文字起こしが全滅した場合はStep 2に進まず中断する。最初はエラーでもClaude CLIが走ってしまい、空振りで課金だけ食うという罠があった。~/scripts/recipe を叩くだけで再生リストが丸ごとObsidianのレシピノートになる。

最終的な構成

YouTube再生リストからObsidianレシピノートへの変換フロー

重い処理(音声→テキスト)はMacのNeural Engineで、知的な処理(テキスト→構造化レシピ)はClaudeで。それぞれ得意なところを担当させている。

所感

もともとは「YouTube動画のレシピをObsidianに入れたい」という素朴な要望だったが、やってみるとCoworkのサンドボックスはネットワーク制限がある、YouTubeの字幕APIは素直に取れない、ローカルLLMの精度はタスク次第で足りない、といった壁にぶつかり、さらにPythonのバージョン問題やvenvの必要性といった環境構築の定番ハマりポイントも踏み抜いた。結果的にローカルwhisper + Claude CLIという組み合わせに行き着いた。

面白いのは、この試行錯誤の過程自体がCoworkとの対話で進んだこと。エラーが出たらターミナルの出力を貼り、Coworkが次の手を提案し、また試す。デバッグのペアプロ相手としてはかなり優秀だった。43本の再生リストが片付いたら、キッチンに立つ回数が増えるかもしれない。増えないかもしれない。