Dzisiaj pokażę jak zrobić wejście na kanał głosowy przez bota i puszczenie przez niego jakiegoś pliku dźwiękowego.
Do obsługi kanałów głosowych przez discord.py musimy zainstalować bibliotekę PyNaCl. Standardowo wpisujemy po prostu
pip3 install PyNaCl
Teraz musimy pobrać plik wykonywalny ffmpeg do odgrywania dźwięku. Dla ułatwienia wrzuciłem go po prostu na dysk google. Możecie go pobrać z tego linku: https://drive.google.com/file/d/13-wutJmFWznmatnnkMgyHPz9H4jeFuvm.
Plik przenosimy do tego samego miejsca, gdzie znajduje się nasz plik, w którym będzie napisana logika dotycząca kanałów głosowych obsługiwanych przez bota .
Okej, zacznijmy pisać bota. Na początku importujemy utilsy z discord.py oraz FFmpegPCMAudio.
from discord import utils
from discord import FFmpegPCMAudio
Teraz tworzymy komendę, po użyciu której bot wejdzie na kanał głosowy i zacznie odtwarzać plik dźwiękowy. Ja nazwałem tą komendę play.
@bot.command()
async def play(ctx):
Na początku musimy sprwadzić, czy użytkownik, który wywołuje komendę jest w ogóle na kanale głosowym. W tym celu użyjemy po prostu instrukcji warunkowej. ctx.author.voice jest prawdą, tylko gdy użytkownik znajduje się na kanale głosowym.
if ctx.author.voice:
Teraz musimy dowiedzieć się jaki to kanał. W końcu bot musi wiedzieć na jaki kanał wejść. Użyjemy do tego atrybutu channel (jest to instancja klasy VoiceChannel), który jest atrybutem instancji klasy VoiceState, który natomiast jest atrybutem ctx.author (czyli po prostu atrybutem użytkownika, który wywołuje komendę).
channel = ctx.author.voice.channel
Okej, mamy już kanał głosowy, na którym przesiaduje nasz użytkownik. Pora na podłączenie się do tego kanału przez bota. Użyjemy do tego metodę connect() naszej zmiennej, channel, którą zdefiniowaliśmy wcześniej.
await channel.connect()
Pamiętajmy, że to wszystko jest w instrukcji warunkowej, dlatego teraz musimy zrobić else, ponieważ użytkownik może nie być na kanale głosowym. Wtedy po prostu nic nie robimy, zwracamy None i wykonywanie naszej komendy się kończy.
if ctx.author.voice:
channel = ctx.author.voice.channel
await channel.connect()
else:
return
Teraz po wpisaniu komendy play nasz bot dołączy do kanału głosowego. Pora na puszczenie jakiegoś dźwięku. Musimy uzyskać listę aktywnych połączeń do kanałów głosowych.
guild = ctx.guild
voice_client = utils.get(bot.voice_clients, guild=guild)
W powyższym kodzie otrzymujemy aktywną instancję VoiceClient dla naszego serwera. Teraz pora na zdefiniowanie zmiennej z plikiem dźwiękowym.
audio_source = FFmpegPCMAudio('muzyka.mp3')
muzyka.mp3 to po prostu nazwa naszego pliku dźwiękowego. Do tej linijki kodu potrzebujemy pliku wykonywalnego ffmpeg, o który wspominałem już wyżej.
Czas na puszczenie dźwięku. Sprawdzamy na początku, czy może nasz bot już nie gra jakiegoś pliku dźwiękowego, jeśli gra to nie puszczamy nic innego. Jeżeli jednak nie gra to puszczamy nasz plik dźwiękowy używając metody play() zmiennej voice_client, którą zdefiniowaliśmy wcześniej.
if not voice_client.is_playing():
voice_client.play(audio_source, after=None)
Argument after oznacza, co chcemy zrobić po tym jak skończy się odtwarzanie aktualnego pliku dźwiękowego.
A tak prezentuje się skończony bot.
from discord.ext import commands
from discord import utils
from discord import FFmpegPCMAudio
bot = commands.Bot(command_prefix='$')
@bot.command()
async def play(ctx):
if ctx.author.voice:
channel = ctx.author.voice.channel
await channel.connect()
else:
return
guild = ctx.guild
voice_client = utils.get(bot.voice_clients, guild=guild)
audio_source = FFmpegPCMAudio('muzyka.mp3')
if not voice_client.is_playing():
voice_client.play(audio_source, after=None)
bot.run('token')
Poniżej można zobaczyć, że bot działa poprawnie.