blog-audio について
blog-audio は、ブログ記事を Gemini TTS で音声化するスキルです。短い要約、全文朗読、2人の対話形式に対応し、音声の選択と HTML5 埋め込み方法も扱います。
主な機能
- 01要約・全文・対話の各モード
- 02Gemini TTS による音声生成
- 03プリセット音声の選択
- 04長文の分割とチャンク数制限
- 05HTML5 音声埋め込みの案内
活用シーン
- 01記事の短い音声要約の作成
- 02全文を朗読音声として提供
- 032人のポッドキャスト風音声の制作
- 04ブログへの音声プレーヤー追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agricidaniel/ claude-blog --skill blog-audioインストール後、Claude Code で/blog-audioを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/voices.mdscripts/__init__.pygenerate_audio.pyrequirements.lockrequirements.txtrun.pyruntime_paths.pysetup_environment.py詳細
ブログ音声:ブログ記事向け Gemini TTS ナレーション
以下のバンドルパスでは、ホスト側の Markdown 置換で ${CLAUDE_SKILL_DIR} を使用します。
これはエクスポートされたシェル変数ではありません。実行前にパスを解決し、パスを引用符で囲み、絶対パスでないオーバーライドは拒否してください。${CLAUDE_SKILL_DIR}/../blog/references から解決した blog_reference_root、${CLAUDE_SKILL_DIR}/../blog/templates から解決した blog_template_root、および必要な兄弟ルートをエージェントに渡してください。
プロジェクトのコンテキストを読み込む前に、メインリファレンスの orchestration-details.md を読み込んでください。下流のエージェントには、そのヘルパーで囲まれた出力のみを渡してください。
Google の Gemini TTS を使用して、ブログ記事のプロフェッショナルな音声ナレーションを生成します。 モードは3つあります。要約(200~300語の音声向け概要)、記事全文の読み上げ、2人の話者によるポッドキャスト形式の対話です。Gemini 3.8 Flash TTS では30種類の事前構築済み音声と130以上の言語に対応し、Flash-Lite では100以上の言語に対応しています(Google の音声生成ページ、2026-10-12確認)。HTML5 埋め込み形式で出力します。
コストと同意の確認(必須、最初に読む)
このスキルはユーザーの Google AI クレジットを消費し、音声ファイルを書き込みます。
- 消費するもの: テキストチャンクごとに、有料の Gemini TTS 呼び出しを1回行います。長いテキストはチャンクに分割されるため、全文読み上げでは複数回の呼び出しが必要です。スクリプトの
--max-chunksフラグで1回の実行あたりのチャンク数を制限できます(デフォルトは12)。ユーザーに新たな最悪ケースの費用を伝えずに、上限を引き上げてはいけません。 - 費用の根拠: 音声出力トークンは音声1秒あたり25トークンです。2026-10-12時点で、https://ai.google.dev/gemini-api/docs/pricing には
gemini-3.8-flash-ttsが音声トークン100万個あたり$9.00(10秒あたり約$0.00225)、gemini-3.8-flash-lite-ttsが$6.00(10秒あたり約$0.0015)と記載されており、いずれも2026-12-31までの価格です。2027-01-01からは記載価格が上がります。まず--dry-run --jsonを実行して、スクリプトによる見積もりを確認してください。 - 書き込むもの:
audio/(または--output)内の音声ファイル、およびセットアップ時のみ、管理対象の.venvを書き込みます。 - 同意: セッション中に最初の有料呼び出しを行う前に、モード、モデル、チャンク数、推定費用を伝え、明示的な同意を待ってください。同意が有効なのはその実行に限られます。ブログ記事の執筆は音声生成への同意を意味しません。
- 上限のない支出は禁止: 上限を超えて有料呼び出しを再試行したり、ループしたりしてはいけません。一時的なエラーの場合は1回だけ再試行し、その後は報告してください。
- スキップ条件: ユーザーが同意しない場合、キーがない場合、またはセットアップが済んでいない場合はスキップし、オーケストレーターの「フォールバックとスキップ」サマリー用に「Audio: no API key set, skipped」のような1行のみを返してください。
クイックリファレンス
| コマンド | 説明 |
|---|---|
/blog audio generate <file> | ブログ記事の音声ナレーションを生成します |
/blog audio voices | 利用可能な音声とその特徴を表示します |
/blog audio setup | Gemini TTS の API キーを確認・設定します |
前提条件
- Python 3.11 以降。管理対象の venv は明示的なセットアップ操作で管理します
GOOGLE_AI_API_KEYまたはGEMINI_API_KEY環境変数(GOOGLE_AI_API_KEYは blog-image が使用するキーです。音声スクリプトではどちらも使用できます)- FFmpeg(WAV から MP3 への変換に使用。不在の場合は WAV にフォールバックします)。暗黙にインストールしてはいけません。ユーザーに伝え、インストールはユーザーに任せてください
永続ランタイムディレクトリ
CLAUDE_BLOG_RUNTIME_DIR を指定すると、信頼できる絶対パスの永続ルートを任意で選択できます。この連携では <root>/blog-audio/.venv を使用します。NotebookLM もライブラリ、認証情報、ブラウザーの状態に <root>/blog-notebooklm/data を使用します。この設定がない場合は、既存のスキルローカルのデフォルトが引き続き使用されます。Google の共有認証情報設定/トークンのパスは変更されません。状態が自動的にコピーまたは移行されることはなく、通常の実行でセットアップが行われることもありません。
既存の検証済みのオペレーター設定は保持してください。設定がないプラグインでは、セットアップ時とその後のすべてのランナー呼び出し時に、ホストによって置換される ${CLAUDE_PLUGIN_DATA}/claude-blog-runtime のパスを明示的に渡してください。これは Markdown の置換であり、エクスポートされたシェル変数ではありません。解決済みの絶対パスになってからのみ実行してください。シングルクォートで囲むと、未解決のプレースホルダーが文字どおりに保持されるため、別のシェルパスに展開されず、検証で拒否されます。
CLAUDE_BLOG_RUNTIME_DIR='${CLAUDE_PLUGIN_DATA}/claude-blog-runtime' python3 "${CLAUDE_SKILL_DIR}/scripts/setup_environment.py" --check --json
CLAUDE_BLOG_RUNTIME_DIR='${CLAUDE_PLUGIN_DATA}/claude-blog-runtime' python3 "${CLAUDE_SKILL_DIR}/scripts/run.py" generate_audio.py --help
--check を付けずに明示的にセットアップした場合にのみ、依存関係がインストールされます。スタンドアロンユーザーは、絶対パスのランタイムルートを明示的に選択しない限り、デフォルトを引き続き使用します。相対パス、未解決のパス、またはリンクされた管理対象サブディレクトリは、フェイルクローズで拒否されます。ルートを変更すると別の状態が選択されますが、古いルートの移行やクリーンアップが許可されることはありません。プラグインの永続データには、ホストのアンインストール時の保持ルールが適用されます。引き続き必要な場合は、アンインストール時に明示的に保持してください。
インストール済みの run.py ラッパーを使用する
BLOG_SKILLS_DIR="${CLAUDE_BLOG_SKILLS_DIR:-${CLAUDE_SKILL_DIR}/..}"
case "$BLOG_SKILLS_DIR" in /*) ;; *) echo "ERROR: skills dir must be absolute" >&2; exit 1 ;; esac
AUDIO_RUN="$BLOG_SKILLS_DIR/blog-audio/scripts/run.py"
python3 "$AUDIO_RUN" generate_audio.py --text "..." --voice Charon --model flash38 --json
通常の generate コマンドと voices コマンドは、変更を加えずに機能を確認します。管理対象環境が存在しない場合は、セットアップが必要であることを示す結果を返します。.venv の作成や依存関係のインストールを行えるのは /blog audio setup だけです。現在のプロジェクトの scripts/ ディレクトリからラッパーを解決しないでください。
API キーの確認(ゲートパターン)
音声を生成する前に、API キーを確認します(スクリプトは最初に
GOOGLE_AI_API_KEY、次に GEMINI_API_KEY を読み取ります)。
if [ -n "${GOOGLE_AI_API_KEY:-}" ] || [ -n "${GEMINI_API_KEY:-}" ]; then echo "API key is set"; else echo "API key is not set"; fi
- いずれかが設定されている場合:同意ゲートに進み、その後生成します
- どちらも設定されていない場合:ユーザーに次のように案内します:
「音声の生成には Google AI API キーが必要です。https://aistudio.google.com/apikey で取得してください。
その後、シェルでエクスポートします:
export GOOGLE_AI_API_KEY=your-key(またはGEMINI_API_KEY)。/blog imageで使用するキーと同じものを使用できます。」 - 内部から呼び出された場合(blog-write から):キーが設定されていなければ、呼び出し元の最終サマリー用に、何を・なぜスキップしたかを示す1行のメモを返します。執筆ワークフローを妨げないでください。
セットアップ
/blog audio setup の場合:
- 環境内に
GOOGLE_AI_API_KEYまたはGEMINI_API_KEYが設定されていることを確認します - blog-image がプロジェクトの
.mcp.jsonを使用している場合は、参照されている環境変数がエクスポートされていることを確認します - 設定されていない場合は、https://aistudio.google.com/apikey をユーザーに案内します
- ユーザーの承諾を得て、管理対象環境を作成または更新します。依存関係をインストールするのはこの手順だけです:
python3 "$BLOG_SKILLS_DIR/blog-audio/scripts/setup_environment.py"(インストールせずに確認するには--check --jsonを追加します) - ドライラン(API 呼び出しなし)で検証します:
python3 "$AUDIO_RUN" generate_audio.py --text "Test" --dry-run --json
音声の選択
/blog audio voices の場合:
${CLAUDE_SKILL_DIR}/references/voices.md を読み込み、音声カタログをユーザーに提示します。
ユーザーに希望する音声を尋ねるか、コンテンツの種類に基づいて推奨します:
- 記事のナレーション:Charon(情報豊富)または Sadaltager(知識豊富)
- チュートリアル/ハウツー:Achird(親しみやすい)または Sulafat(温かみのある)
- ニュース/分析:Rasalgethi(情報豊富)または Schedar(落ち着いた)
- ライフスタイル/ウェルネス:Aoede(軽やか)または Vindemiatrix(穏やか)
- 対話のホスト:Puck(陽気)または Laomedeia(陽気)
- 対話の専門家:Kore(毅然とした)または Charon(情報豊富)
生成ワークフロー
/blog audio generate <file> の場合:
ステップ 1:ブログ記事を読む
ファイルを読み、次の内容を抽出します:
- タイトル(H1 またはフロントマターから)
- 全文(Markdown の本文)
- おおよその単語数
ステップ 2:モードを選択する
ユーザーに確認するか(または --mode が指定されている場合は自動で選択します):
| モード | 使用する場面 | 出力 |
|---|---|---|
| Summary | 音声で手短に概要を伝える(1~2 分) | 200~300 語の読み上げ用要約 |
| Full | 全文を読み上げる(5~15 分) | 記事全体を自然な話し言葉にしたもの |
| Dialogue | ポッドキャスト形式(3~8 分) | 記事についての 2 人の会話 |
ステップ 3:テキストを準備する
Claude がテキストを準備し、スクリプトは TTS のみを実行します。
Summary モード: 記事の 200~300 語の読み上げ用要約を書きます。ルール:
- 書き言葉ではなく、自然な話し言葉にします
- 記事の主要な発見や回答から始めます
- 主なポイントを 3~5 個取り上げます
- 実践的なアドバイスで締めくくります
- Markdown、「この記事では……」などの前置き、メタ的なコメントは使いません
- 「ここで重要なのは……」「重要な発見は……」など、会話調のつなぎ表現を使います
Full モード: Markdown の内容を、自然に読み上げられるテキストに整えます:
- 見出しは自然なつなぎ表現にします(「次に、……を見てみましょう」など)
- リンクは通常のテキストにします(URL を削除し、アンカーテキストは残します)
- 画像やグラフは省略するか、簡単に説明します(「データが示すように……」など)
- コードブロックは口頭で説明します(「コードでは for ループを使って……」など)
- リストは自然な文章に直します
- フロントマター、スキーママークアップ、HTML タグは削除します
- 短い導入を追加します:「これは [タイトル] です。[日付] に公開されました。」
Dialogue モード: 記事についての 2 人の会話スクリプトを書きます:
- Speaker1 = ホスト(好奇心があり、よい質問をします)
- Speaker2 = 専門家(詳しく、わかりやすく回答します)
- 各行を次の形式にします:
Speaker1: ここで重要なポイントは何ですか? - 記事の主なポイントを会話調で取り上げます
- 15~25 回のやり取りにします(約 3~8 分の音声になります)
- 堅苦しくならないようにします(「まさにそのとおりですね」は、「研究が示すとおりです」より自然です)
ステップ 4:音声を選択する
ユーザーが音声を選択している場合は、それを使用します。選択していない場合は、モードに応じて推奨します:
- Summary/Full:デフォルトで Charon(情報提供向け)を使用します
- Dialogue:デフォルトで Puck(ホスト)+ Kore(専門家)を使用します
ステップ 5:音声を生成する
準備したテキストを作業ディレクトリ内のファイルに書き込み、次を呼び出します:
# Single voice (summary or full mode)
python3 "$AUDIO_RUN" generate_audio.py \
--text-file blog_audio_prepared.txt \
--voice Charon \
--model flash38 \
--output audio/post-slug.mp3 \
--json
# Two voices (dialogue mode)
python3 "$AUDIO_RUN" generate_audio.py \
--text-file blog_audio_dialogue.txt \
--voice Puck \
--voice2 Kore \
--model flash38 \
--output audio/post-slug-dialogue.mp3 \
--json
モデルの選択(明示的な 3.8 ID を使用):
flash38:gemini-3.8-flash-tts。安定した汎用モデルで、上記の例でも使用されています。130 以上の言語に対応しています。flash-lite38:gemini-3.8-flash-lite-tts。安定した低価格モデルです。100 以上の言語に対応していますが、フィンランド語やタイ語など、一部の言語は Flash のみで利用できます。- 従来のエイリアス
flash、flash31、pro、legacy-flash25、legacy-pro25は、gemini-3.1-flash-tts-preview、gemini-2.5-pro-preview-tts、gemini-2.5-flash-preview-ttsに対応しています。Google の非推奨化ページ(2026-10-12 確認)では、最も早い提供終了日が 2026-11-17 と記載されています。そのため、新しい作業には使用しないでください。利用料金を発生させる前に、--dry-run --jsonの出力で解決後のモデル ID を確認してください。
3.8 のエイリアスには、オフラインでの SDK スキーマ検証と WAV 解析チェックがあります。認証後の利用可否と音声品質については、引き続きプロバイダーでのテストが必要です。3.8 では、読み上げの指示を埋め込まず、逐語的なトランスクリプトを渡してください。Dialogue では、明示的な Speaker1: と Speaker2: の行を使用してください。ヘルパーが話者を推測することはありません。費用の見積もりには、12 月 31 日までの確認済みの 2026 年料金と、1 月 1 日以降に適用される公表済みの 2027 年料金が使われます。あくまで見積もりであり、請求額を保証するものではありません。
ステップ 6:結果を提示する
ユーザーに次の内容を提示します:
- ファイルパス:音声の保存先
- 長さ:「3:42」など、人が読みやすい形式
- 埋め込みコード:そのまま貼り付けられる HTML5 音声タグ
- 費用:API 利用料金の見積もり
- 配置の提案:ブログ記事内で埋め込みを挿入する場所
埋め込みガイド
標準 HTML(Hugo、Jekyll、静的サイト)
<audio controls preload="metadata">
<source src="audio/post-slug.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
MDX(Next.js、Gatsby)
<audio controls preload="metadata">
<source src="/audio/post-slug.mp3" type="audio/mpeg" />
</audio>
WordPress
[audio src="audio/post-slug.mp3"]
配置
音声プレーヤーは、導入部の後(最初の H2 の下)、または記事の最上部に「この記事を聴く」や「音声版」というラベルを付けて挿入します。
内部 API(blog-write 用)
blog-write から内部的に呼び出される場合:
入力:
text:準備済みのテキスト(Claude によるクリーニング済み)voice:音声名(デフォルト:Charon)voice2:対話用の 2 つ目の音声(任意)model:flash38(新しい作業でのデフォルト)またはflash-lite38。レガシーエイリアス(flash、flash31、pro、legacy-*)は、早ければ 2026-11-17 に終了しますoutput_path:ファイルの保存先
出力:
### Audio Narration
- **Path:** /path/to/audio/post-slug.mp3
- **Duration:** 3:42
- **Voice:** Charon
- **Embed:** `<audio controls preload="metadata"><source src="audio/post-slug.mp3" type="audio/mpeg"></audio>`
適切なフォールバック: GOOGLE_AI_API_KEY と GEMINI_API_KEY のどちらも設定されていない場合、またはユーザーがコスト確認を拒否した場合は、エラーを返さず直ちに戻り、呼び出し元の最終サマリー用に 1 行のスキップ通知を返します。音声なしで執筆ワークフローを続行します。音声生成が利用できないために blog-write を停止してはなりません。
エラー処理
| エラー | 解決方法 |
|---|---|
API キーが設定されていない(GOOGLE_AI_API_KEY または GEMINI_API_KEY) | https://aistudio.google.com/apikey でキーを取得します |
| FFmpeg が見つからない | WAV 出力にフォールバックします。ユーザーに伝え、代わりにインストールしてはなりません。 |
| レート制限 | 待ってから再試行します。https://aistudio.google.com/rate-limit で制限を確認します |
| テキストが長すぎる(入力トークン数が 8,192 超) | 約 7,800 トークンごとにセクションに分割します。スクリプトは準備済みテキストをチャンクに分割して結合し、1 回の実行につき --max-chunks(デフォルトは 12)まで処理します。上限を超えた場合は停止し、上限を引き上げる前にユーザーに確認します |
| 不明な音声名 | /blog audio voices を実行して有効なオプションを確認します |
| API エラー | キーの有効性とモデルの利用可否を確認します |
| API キーがない(内部呼び出し) | 1 行のスキップ通知を返します。執筆ワークフローは続行し、その旨を報告します |
リファレンスドキュメント
必要に応じて読み込みます。起動時にすべて読み込まないでください:
${CLAUDE_SKILL_DIR}/references/voices.md:全 30 種類の音声カタログ、コンテンツの種類ごとの推奨音声、対話向けの組み合わせ