2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

discordの読み上げbot作成 (Mac Intel上で作成)

Last updated at Posted at 2025-03-16

1. Discordボットの作成

  1. Discord Developer Portal にアクセス
  2. 「New Application」を作成
  3. 「Bot」タブで「Add Bot」を押す
  4. 「ResetTOKEN」でトークンをリセットして「TOKEN」をコピー&メモ
    (このトークンは絶対に公開しないでください!)
  5. 「Privileged Gateway Intents」の「MESSAGE CONTENT INTENT」を有効化
  6. 「OAuth2」>「URL Generator」で「bot」と「applications.commands」を選択
  7. 「Voice」権限を付与し、生成されたURLからサーバーに招待
    私はテキトーに以下の権限を選択しました。
    image.png

Python環境のセットアップを進めましょう!

2.Pythonのインストール

🔹 手順

  1. 公式サイト から Python 3.10以上 をダウンロード
  2. インストーラーを実行し、「Add Python to PATH」 にチェックを入れる
  3. 「Install Now」を選択してインストール

✅ 確認

インストール後、ターミナル(コマンドプロンプト)で次のコマンドを実行してください。

python --version

または

python3 --version

Python 3.x.x と表示されれば成功です!


3.仮想環境の作成(推奨)

プロジェクトごとに環境を管理しやすくするため、仮想環境を作成します。

python -m venv venv

✅ 仮想環境の有効化

  • Windows:

    venv\Scripts\activate
    
  • Mac/Linux:

    source venv/bin/activate
    

    仮想環境が有効になると、ターミナルの先頭に (venv) が表示されるはずです。
    確認できたら以下で非アクティブに戻しておきます。

    deactivate
    

4.VOICEVOXエンジン(CLI版)を導入

Mac(Intel)向けのCLI版VOICEVOXエンジンを手動で導入し、APIとして利用できます。

🔹 手順

  1. VOICEVOXエンジン(Mac版)をダウンロード

  2. ZIPを解凍し、適当なフォルダに配置
    The Unarchiverで解凍しました。
    配置は以下にしました。

    /Users/user/voicevox_engine/macos-x64
    
  3. 実行権限を付与

    cd /Users/user/voicevox_engine/macos-x64
    chmod +x run
    
  4. エンジンを起動

    ./run
    
    • 正常に動作すると、ターミナルに http://127.0.0.1:50021 のようにアドレスが表示される

    以下のエラーがある場合:

    “run”が悪質なソフトウェアかどうかをAppleでは確認できないため、このソフトウェアは開けません。
    

    以下を実行して許可(パスは環境に合わせて変更)

    sudo xattr -rd com.apple.quarantine /Users/uƒser/voicevox_engine/macos-x64
    

    再度./runする

これでAPIが動作するようになります!

5. PythonでVOICEVOXエンジンAPIを呼び出す(動作確認)

まず、エンジンが正常に動作するか Pythonでテスト してみましょう。
ターミナルで source venv/bin/activate してvenvをアクティブにし、以下のコードを実行してください。

1️⃣ 依存ライブラリのインストール

ターミナルで以下を実行:

pip install requests soundfile numpy

wav->mp3変換用

brew install ffmpeg
pip install pydub

2️⃣ Pythonコードを用意(ローカルテストy)

Pythonスクリプトを作成し、VOICEVOXエンジンが正しく動作するか確認します。

test_voicevox.py

import requests
from pathlib import Path
from pydub import AudioSegment

# VOICEVOXエンジンのURL
VOICEVOX_URL = "http://localhost:50021"
url_audio_query = VOICEVOX_URL + "/audio_query"
url_synthesis = VOICEVOX_URL + "/synthesis"

# テキストを指定
text = "こんにちは、MP3での音声合成テストです。"

# 音声合成のクエリを作成
query_payload = {"text": text, "speaker": 1}
query_response = requests.post(url_audio_query, params=query_payload)

if query_response.status_code == 200:
    query_data = query_response.json()

    # 音声合成のリクエスト
    synthesis_response = requests.post(
        f"{url_synthesis}",
        json=query_data,
        params={"speaker": 1}
    )

    if synthesis_response.status_code == 200:
        # WAVデータを保存
        wav_path = "test_voice.wav"
        with open(wav_path, "wb") as f:
            f.write(synthesis_response.content)

        # WAV → MP3 変換
        mp3_path = "test_voice.mp3"
        audio = AudioSegment.from_wav(wav_path)
        audio.export(mp3_path, format="mp3")

        print(f"✅ MP3ファイルが作成されました! → {mp3_path}")
    else:
        print("❌ 音声合成に失敗しました:", synthesis_response.text)
else:
    print("❌ クエリ作成に失敗しました:", query_response.text)



3️⃣ 実行

ターミナルで以下のコマンドを実行:

python3 test_voicevox.py

確認すること

  • test_voice.wav が生成されること
  • 再生して音声が出ることopen test_voice.wav コマンドで開けます)

6. Discordでbotを動作させる

1️⃣ discord.py をインストール

まず discord.py をインストールします。
venv仮想環境をアクティブにした状態で、以下を実行してください:

pip install "discord.py[voice]"
pip install ffmpeg

discord.py[voice] をインストールすると、ボイス関連の機能が使えます。


2️⃣ pythonコードを用意

以下のコードを作成します。

bot.py

import discord
import requests
from discord import app_commands
from discord.ext import commands
from pydub import AudioSegment

TOKEN = "YOUR_BOT_TOKEN"  # 🔴 自分のBotトークンを入れてください
VOICEVOX_URL = "http://localhost:50021"

intents = discord.Intents.default()
intents.message_content = True  # メッセージの取得を許可
bot = commands.Bot(command_prefix="/", intents=intents)

# ボットが接続しているVCのテキストチャンネルを記録
vc_text_channels = {}

@bot.event
async def on_ready():
    print(f"{bot.user} が起動しました!")
    try:
        synced = await bot.tree.sync()  # スラッシュコマンドを同期
        print(f"✅ スラッシュコマンド {len(synced)} 個を同期しました!")
    except Exception as e:
        print(f"❌ スラッシュコマンドの同期に失敗: {e}")

@bot.tree.command(name="join", description="ボイスチャットに参加します")
async def join(interaction: discord.Interaction):
    """ボットをVCに参加させる"""
    if interaction.user.voice:
        channel = interaction.user.voice.channel
        await channel.connect()
        vc_text_channels[interaction.guild.id] = interaction.channel.id  # ボットが接続したVCのテキストチャンネルを記録
        await interaction.response.send_message("✅ ボイスチャンネルに参加しました!")
    else:
        await interaction.response.send_message("❌ 先にボイスチャンネルに参加してください!", ephemeral=True)

@bot.tree.command(name="play", description="VCで音声ファイルを再生")
async def play(interaction: discord.Interaction):
    """VCで音声ファイルを再生"""
    if interaction.guild.voice_client:
        source = discord.FFmpegPCMAudio("test_voice.wav")
        interaction.guild.voice_client.play(source)
        await interaction.response.send_message("🎵 音声を再生します!")
    else:
        await interaction.response.send_message("❌ 先に `/join` でVCに参加させてください!", ephemeral=True)

@bot.tree.command(name="disconnect", description="ボイスチャットから退出")
async def disconnect(interaction: discord.Interaction):
    """ボットをVCから切断"""
    if interaction.guild.voice_client:
        await interaction.guild.voice_client.disconnect()
        vc_text_channels.pop(interaction.guild.id, None)  # 記録していたテキストチャンネルIDを削除
        await interaction.response.send_message("✅ ボイスチャンネルから切断しました!")
    else:
        await interaction.response.send_message("❌ ボットはVCにいません!", ephemeral=True)

@bot.event
async def on_message(message):
    """ボットが接続しているVCのテキストチャンネルのメッセージのみを読み上げ"""

    if message.author == bot.user or message.author.bot:
        return  # ボット自身や他のBotのメッセージは無視

    # ボットがVCに接続していなければ無視
    if not message.guild or not message.guild.voice_client:
        return

    # 読み上げるメッセージ内容
    text = message.content

    # ボットが接続しているVCのテキストチャンネルか確認
    if message.guild.id not in vc_text_channels or message.channel.id != vc_text_channels[message.guild.id]:
        print(f"対象外のメッセージを無視: {text}")
        return  # VCのテキストチャンネル以外は無視


    # VOICEVOXで音声合成
    query_payload = {"text": text, "speaker": 1}
    query_response = requests.post(f"{VOICEVOX_URL}/audio_query", params=query_payload)

    if query_response.status_code != 200:
        return  # エラーなら無視

    query_data = query_response.json()
    synthesis_response = requests.post(f"{VOICEVOX_URL}/synthesis", json=query_data, params={"speaker": 1})

    if synthesis_response.status_code != 200:
        return  # エラーなら無視

    # 音声を保存(WAV形式のまま)
    wav_path = "voice.wav"
    with open(wav_path, "wb") as f:
        f.write(synthesis_response.content)

    # VCで再生(WAVをそのまま)
    source = discord.FFmpegPCMAudio(wav_path)
    message.guild.voice_client.play(source)

    await bot.process_commands(message)  # 他のコマンドも処理

bot.run(TOKEN)



3️⃣python実行

ターミナルからbot.pyのあるディレクトリで以下を実行してbotを起動します

python3 bot.py

ssl.SSLCertVerificationError のエラーがある場合は次の手順で証明書を取得しましょう。

3️⃣-2 証明書インストール

macOSでは、Pythonに付属するSSL証明書を手動でインストールする必要がある場合があるそうで、次のコマンドを実行してください。

4️⃣ discordで呼び出す

Discordでテスト

  1. ボットをVCに呼ぶ /join
  2. テキストを読み上げさせる(例:ボイスチャット内で)こんにちは!
  3. 保管済みの音声を再生/play
  4. ボットをVCから切断/disconnect

🎯 次のステップ

  • /voicechange で話者変更
  • VCに誰もいなくなったら自動切断
  • 音声のキュー管理(複数のメッセージを順番に再生)

今後また更新予定です 🚀

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?