Hi. I'm trying to make some basic voice functionality for bot. So this is my code (one extension) so far:
import discord
from discord.ext import commands
from gtts import gTTS as gtts
"""
Name: tts
Description: El Bot plugin for TTS on VC.
Author: Grzesiek11
Version: v1.0.0
"""
class TTSPlugin(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.group(name = 'tts')
async def _tts(self, ctx):
if ctx.invoked_subcommand is None:
return
@_tts.command(name = 'join', aliases = ['connect', 'c'])
async def _join(self, ctx, channel : discord.VoiceChannel):
await channel.connect()
@_tts.command(name = 'say')
async def _say(self, ctx, *, text):
message = gtts(text)
message.save('tts.mp3')
ctx.guild.voice_client.play(discord.FFmpegPCMAudio('tts.mp3'))
@_tts.command(name = 'disconnect', aliases = ['dc'])
async def _disconnect(self, ctx):
await ctx.guild.voice_client.disconnect()
def setup(bot):
bot.add_cog(TTSPlugin(bot))
The connect function works right. But disconnect and say are not working.
When I try to use disconnect command, it just doesn't disconnect. No error, no anything. When I try to join another channel, it unsupprisingly gives me discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ClientException: Already connected to a voice channel..
When I do say, the gTTS lib generates me a file that works and is playable via VLC. Bot turns into speaking state:

But nothing else happens. No one can hear anything and it doesn't turn off that state after few minutes or so even if generated file is 2s long. However, it gives me a warning, not from python but rather from FFmpeg:
[mp3 @ 0x55c98a746100] Estimating duration from bitrate, this may be inaccurate
Aaaand nothing more. Asked on Discord API server and on Python server. No one knows solution.
Some helpful things maybe:
apt, and it works well in shell.print(discord.opus.is_loaded()), it gave me True.File not found, so normally it's found.You're calling voice_client.play() and .disconnect() through ctx.guild. I'm not sure on the specific behavior of this , but try getting the voice_client object via the bot.voice_clients property like so :
@_tts.command(name="disconnect")
async def _disconnect(self, ctx):
await self.bot.voice_clients[0].disconnect()
Although you should be getting an AttributeError when trying to use a method on an empty object.
@ALobsterDog This isn't correct.
guild.voice_client gives you the voice client for that guild, and doing it by index, if it works at all, is... dubious.
I don't know what's wrong with the main issue, the code itself looks fine for the exception that it's using a blocking library. I'd try a different file, but it's probably best for this to be debugged in the discord.py server.
notice i am not calling guild.voice_client but bot.voice_clients which returns a list of VoiceClient that are active.
I've noticed it and it's still incorrect to use this, as guild.voice_client exists and gives you the exact voice client for that particular guild, whereas grabbing from index gives you at best a random guild.
Consider that bots can have voice clients on multiple guilds.
I was having a very similar issue, apparently I had glossed over the part where, in the installation instructions, it says:
"To get voice support, you should use discord.py[voice] instead of discord.py, e.g.
python3 -m pip install -U discord.py[voice]"
though the cryptic failures with no indication I hadn't installed the correct version seems like an oversight regardless.
It seems this still hasn't been solved... I am having the same issue
@Y4hL try updating discord.py