Claude Codeの処理が終わったらしゃべってもらうようにした

効率化
スポンサーリンク

Claude Codeで長めの処理を走らせていると、終わったタイミングに気づけないことがよくあります。

通知音を鳴らすだけでもいいんですが、なんとなく「しゃべってくれた方がうれしいな」と思って、処理完了時に音声で読み上げてくれる仕組みを作ってみました。音だけより、声で教えてもらえると可愛いし、内容もわかるしで一石二鳥な感じです。

やったこと

Claude Codeが処理を停止したタイミングで、出力内容を150文字に要約して音声で読み上げてくれるようにしました。

使ったもの:

  • Claude Code Hooksの「Stop」イベント – 処理停止時にスクリプトを実行できる機能
  • Edge TTS – Microsoftの音声合成エンジン(無料で使える)
  • pygame – 音声ファイルの再生用
  • Nanamiの声で+60%速度 – 等倍だと遅くて全体把握に時間がかかるので早くした。このへんは完全に個人の好み

全体の流れ

フロー図

セットアップ

必要なパッケージ

pip install edge-tts pygame

フックスクリプトの作成

以下のPythonスクリプトを適当な場所に保存します。

#!/usr/bin/env python3
import sys
import os
import subprocess
import tempfile
import pygame

# 標準入力から要約テキストを受け取る
summary = sys.stdin.buffer.read().decode("utf-8", errors="replace")

# 150文字に切り詰め
summary = summary[:150]

# 一時ファイルに音声を出力
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp:
    audio_path = tmp.name

# Edge TTSで音声合成
subprocess.run([
    "edge-tts",
    "--voice", "ja-JP-NanamiNeural",
    "--rate", "+60%",
    "--text", summary,
    "--write-media", audio_path
], check=True)

# pygameで再生
pygame.mixer.init()
pygame.mixer.music.load(audio_path)
pygame.mixer.music.play()

# 再生完了まで待機
while pygame.mixer.music.get_busy():
    pygame.time.Clock().tick(10)

# 後片付け
pygame.mixer.quit()
os.unlink(audio_path)

Claude Code Hooksへの登録

.claude/settings.jsonhooks セクションに、Stopイベントとしてスクリプトを登録します。

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "python /path/to/claude_stop_hook.py"
          }
        ]
      }
    ]
  }
}

/path/to/claude_stop_hook.py は実際のスクリプトパスに置き換えてください。matcher を空にしておくと、すべてのStop時に発動します。

音声のカスタマイズ

Edge TTSの日本語音声は2種類あります。

  • ja-JP-NanamiNeural – 女性の声(今回はこれ)
  • ja-JP-KeitaNeural – 男性の声

速度は --rate で調整できます。+60% で1.6倍速、+0% で等倍。自分は等倍だとまどろっこしかったので+60%にしています。

ハマったポイント

標準入力の文字化け(Windows環境)

最初 sys.stdin.read() で読んでいたら、Windows環境で日本語が文字化けしました。sys.stdin.read() はcp932で読み込んでしまうためです。

sys.stdin.buffer.read().decode("utf-8", errors="replace") にしたら解決。Windows + Pythonのstdinあるあるですね。

音声が途中で切れる

pygameで再生した直後にスクリプトが終了すると、音声が途中で切れます。

while pygame.mixer.music.get_busy():
    pygame.time.Clock().tick(10)

この待機ループが必須です。地味だけど忘れるとまったく聞こえない。

並列セッションでの音声再生

Claude Codeを複数セッション並列で走らせている場合、ほぼ同時にStopフックが発動することがあります。

pygameは内部でSDLを使っていて、各プロセスが独立したmixer.init()を持つので、プロセス間での直接的な競合は起きません。一時ファイルもtempfile.NamedTemporaryFileでユニークな名前が生成されるので衝突しません。

ただし、実際に並列セッションで同時にStopが走ると再生エラーが起きることがあります。Windowsのオーディオデバイスの同時再生数制限が原因のようで、自分の環境でも発生しました。頻繁に並列実行する人は注意してください。

まとめ

Edge TTS + pygame + Claude Code Hooksの組み合わせで、処理完了時にしゃべってもらえるようになりました。

通知音でもよかったんですが、内容を読み上げてくれると「ああ、あの処理終わったんだな」とすぐわかるので便利です。何より声で教えてもらえるのがちょっとうれしい。

仕組み自体はシンプルなので、Claude Code使っている人はぜひ試してみてください。地味に作業効率上がりますよ!

コメント

タイトルとURLをコピーしました