Ein Discord-TTS-Bot in Python, der den Chat im Sprachkanal vorliest
Das eingebaute /tts von Discord liest eine Nachricht auf dem Gerät jedes Zuhörers mit dessen Systemstimme vor und spricht nie in einem Sprachkanal. Damit stumme Freunde tippen und alle im Anruf sie hören, brauchen Sie einen Bot, der dem Sprachkanal beitritt und die Nachrichten dort abspielt.
Diese Anleitung baut einen solchen Bot in Python mit discord.py. Er liest einen gewählten Textkanal mit jeder SuperClonica-Stimme vor: mit der kostenlosen Engine auf Ihrem Rechner, offline und ohne Limit, oder über die Sprach-API von SuperClonica, wenn Sie das Modell nicht selbst betreiben möchten.
Was Sie brauchen
Legen Sie im Discord Developer Portal eine Anwendung an, fügen Sie einen Bot hinzu, aktivieren Sie auf der Bot-Seite den Message-Content-Intent und laden Sie den Bot mit den Rechten Verbinden und Sprechen ein. Installieren Sie FFmpeg so, dass es im PATH liegt, dann die Bibliotheken:
python -m pip install "discord.py[voice]" superclonica-cpu
Das voice-Extra von discord.py 2.7 bringt die Verschlüsselungsbibliotheken mit, die Discord-Sprache braucht. Die SuperClonica-Engine lädt beim ersten Start das Supertonic-3-Modell, etwa 400 MB, und läuft danach offline auf einer normalen CPU.
Der Bot mit der kostenlosen Engine
Setzen Sie DISCORD_TOKEN und TTS_CHANNEL_ID, die ID des vorzulesenden Textkanals, und starten Sie die Datei. Schreibt jemand aus einem Sprachkanal in diesen Textkanal, tritt der Bot dessen Sprachkanal bei und liest die Nachricht mit der gewählten Stimme vor; Zeilen warten in einer Warteschlange und reden nie übereinander.
import asyncio, os, re, tempfile
import discord
from superclonica import Superclonica
TOKEN = os.environ["DISCORD_TOKEN"]
TEXT_CHANNEL = int(os.environ["TTS_CHANNEL_ID"]) # the text channel the bot reads
VOICE = "announcer.json" # a voice file from the catalog, or M1..M5, F1..F5
LINK = re.compile(r"https?://\S+")
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
tts = Superclonica()
queue = asyncio.Queue()
def voice_line(text):
audio, _ = tts.synthesize(text, voice=VOICE, lang="en")
path = tempfile.NamedTemporaryFile(suffix=".wav", delete=False).name
tts.save(path, audio)
return path
async def speaker():
while True:
voice_client, text = await queue.get()
path = await asyncio.to_thread(voice_line, text)
done = asyncio.Event()
voice_client.play(discord.FFmpegPCMAudio(path), after=lambda error: client.loop.call_soon_threadsafe(done.set))
await done.wait()
os.remove(path)
@client.event
async def on_ready():
client.loop.create_task(speaker())
@client.event
async def on_message(message):
if message.author.bot or message.channel.id != TEXT_CHANNEL or not message.author.voice:
return
voice_client = message.guild.voice_client or await message.author.voice.channel.connect()
text = LINK.sub("link", message.clean_content)[:300]
await queue.put((voice_client, f"{message.author.display_name} says: {text}"))
client.run(TOKEN)VOICE ist eine der eingebauten Stimmen M1 bis M5 und F1 bis F5 oder eine Stimmdatei aus dem SuperClonica-Katalog: kostenlose Stimmen gibt es ohne Konto, bezahlte nach dem Kauf. Die Synthese läuft in einem eigenen Thread, der Bot bleibt also reaktionsfähig.
Derselbe Bot über die API
Läuft der Bot auf einem kleinen Server ohne Platz für das Modell, vertonen Sie die Zeilen über die Sprach-API von SuperClonica: Ersetzen Sie voice_line durch diese Funktion und setzen Sie SUPERCLONICA_KEY. Jede Katalogstimme funktioniert mit der ID von ihrer Seite, ohne Kauf.
import os, tempfile
import requests
API = "https://superclonica.com/api/v1/speech"
KEY = os.environ["SUPERCLONICA_KEY"]
VOICE_ID = "49cd4d119695528694fac0a1b9fb58a8" # any catalog voice: the ID on its page
def voice_line(text):
answer = requests.post(API, headers={"Authorization": "Bearer " + KEY}, timeout=120,
json={"text": text, "voice": VOICE_ID, "language": "en", "format": "mp3"})
answer.raise_for_status()
path = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False).name
with open(path, "wb") as file:
file.write(answer.content)
return pathEin kostenloser Schlüssel gibt eine Minute Audio pro Tag, genug zum Testen; Start für 5 $ im Monat gibt bis zu 3 Minuten Sprache in jedem 10-Minuten-Fenster, reichlich für einen lebhaften Server.
Damit es angenehm bleibt
Lesen Sie nur einen Kanal, kürzen Sie lange Nachrichten, sagen Sie „Link“ statt einer Webadresse und lassen Sie Moderatoren den Bot verschieben oder entfernen. Die Engine liest gängigen Chat-Slang auf Deutsch, Englisch und einigen weiteren Sprachen als Wörter. Figurenstimmen im Katalog sind von Fans gemacht und nicht von den Rechteinhabern gebilligt: Nutzen Sie sie zum Spaß auf Ihrem Server, nie um sich als jemand auszugeben.