Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.72k stars 3.74k forks source link

Trouble playing audio after connecting to voice #9634

Open codeofdusk opened 10 months ago

codeofdusk commented 10 months ago

Summary

As of latest master, my bot can't connect to a voice channel and play audio. This works fine on 2.3.2.

Reproduction Steps

  1. Start the bot, with the attached Commands.Cog added.
  2. Connect to voice.

Minimal Reproducible Code

class MinimalExample(commands.Cog):
    @commands.Cog.listener()
    async def on_voice_state_update(self, member, before, after):
        vc = member.guild.voice_client
        if member.id == self.bot.user.id:
            return  # Don't trigger on our own actions
        elif before.channel == after.channel:
            return  # Channel didn't change, so not a join or leave event
        elif not vc and after.channel:
            await self._connect(after.channel)

    async def _connect(self, channel):
        if channel.guild.voice_client is None:
            vc = await channel.connect()
            print(vc)

Expected Results

connect returns a voice_client with which I'm able to play audio.

Actual Results

connect never returns, and I get this debug log.

Intents

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

System Information

Checklist

Additional Context

Discussion started at https://github.com/Rapptz/discord.py/issues/9460#issuecomment-1783643755.

imayhaveborkedit commented 10 months ago

I'm not entirely sure why discord is sending a second VOICE_SERVER_UPDATE event but it seems that's what's getting the code into a bad state. It doesn't seem to be related to joining from the event or from an automatic voice region channel. Does connecting work if it's simply called from a command, like so?

@commands.command()
async def join(self, ctx):
    if not ctx.voice:
        await ctx.author.voice.channel.join()

For reference, this is what my logs of connecting to voice look like.

``` [DEBUG ] discord.gateway: For Shard ID None: WebSocket Event: {'t': 'VOICE_STATE_UPDATE', 's': 25, 'op': 0, 'd': {'member': { [me] }, 'user_id': '103675685343612928', 'suppress': False, 'session_id': '5b90fe909d1c48ff97182339558564aa', 'self_video': False, 'self_mute': False, 'self_deaf': False, 'request_to_speak_timestamp': None, 'mute': False, 'guild_id': '...', 'deaf': False, 'channel_id': '[channel id]'}} [INFO ] discord.voice_state: Connecting to voice... [INFO ] discord.voice_state: Starting voice handshake... (connection attempt 1) [DEBUG ] discord.gateway: Updating our voice state to {'op': 4, 'd': {'guild_id': ..., 'channel_id': [channel id], 'self_mute': False, 'self_deaf': False}}. [DEBUG ] discord.voice_state: Connection state changed to set_guild_voice_state [DEBUG ] discord.gateway: For Shard ID None: WebSocket Event: {'t': 'VOICE_STATE_UPDATE', 's': 26, 'op': 0, 'd': {'member': { [my bot] }, 'user_id': '...', 'suppress': False, 'session_id': '6a3537aba1634e200e414390c74d2c2d', 'self_video': False, 'self_mute': False, 'self_deaf': False, 'request_to_speak_timestamp': None, 'mute': False, 'guild_id': '...', 'deaf': False, 'channel_id': '[channel id]'}} [DEBUG ] discord.gateway: For Shard ID None: WebSocket Event: {'t': 'VOICE_SERVER_UPDATE', 's': 27, 'op': 0, 'd': {'token': '8a5760ac9ee8eb13', 'guild_id': '...', 'endpoint': 'us-central5033.discord.media:443'}} [DEBUG ] discord.voice_state: Connection state changed to got_voice_state_update [DEBUG ] discord.voice_state: Connection state changed to got_both_voice_updates [INFO ] discord.voice_state: Voice handshake complete. Endpoint found: us-central5033.discord.media [DEBUG ] discord.voice_state: Connection state changed to websocket_connected [DEBUG ] discord.gateway: Connecting to voice socket [DEBUG ] discord.gateway: Sending ip discovery packet [DEBUG ] discord.voice_state: Registering socket listener callback .get_ip_packet at 0x0000014D0BBBCFE0> [DEBUG ] discord.voice_state: Unregistering socket listener callback .get_ip_packet at 0x0000014D0BBBCFE0> [DEBUG ] discord.gateway: Received ip discovery packet: b'\x00\x02\x00F\x00\x0c\xe5,[my ip]\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\x97' [DEBUG ] discord.gateway: detected ip: [my ip] port: 58775 [DEBUG ] discord.gateway: received supported encryption modes: xsalsa20_poly1305_lite, xsalsa20_poly1305_suffix, xsalsa20_poly1305 [DEBUG ] discord.gateway: selected the voice protocol for use (xsalsa20_poly1305_lite) [DEBUG ] discord.voice_state: Connection state changed to got_ip_discovery [DEBUG ] discord.gateway: received secret key for voice connection [DEBUG ] discord.voice_state: Connection state changed to connected [INFO ] discord.voice_state: Voice connection complete. ```
codeofdusk commented 10 months ago

Does connecting work if it's simply called from a command

@imayhaveborkedit Yes, it does.

EvieePy commented 10 months ago

I believe this is occuring because you have 2 instances of your bot running with this same on_voice_state_update listener. Can you double check you don't have 2 instances of your bot running?

codeofdusk commented 10 months ago

Can you double check you don't have 2 instances of your bot running?

@EvieePy I'm certain that I only have one instance running.

EvieePy commented 10 months ago

That was the only way I was able to reproduce this issue so far. I will keep trying, but in the mean time, you could reset your bots tokens just to be certain, as this should disconnect any stray instances running.

imayhaveborkedit commented 10 months ago

I think I can fix this specific issue for you but it's not much more than a band-aid fix unless I can figure out why you get two voice_server_update events. Regardless if multiple instances cause this issue for you or not, this wasn't something I tested when I wrote this code.

One other question, is the token value in both of those voice_server_update payloads the same?

codeofdusk commented 10 months ago

is the token value in both of those voice_server_update payloads the same?

@imayhaveborkedit Yes, it is.

codeofdusk commented 5 months ago

Any updates on this issue? I'm still able to reproduce it as of 425edd2e10b9be3d7799c0df0cd1d43a1a34654e.

pxrrot commented 4 months ago

I am having this issue as well.

jboby93 commented 3 months ago

I am also having this issue (Python 3.9.0, discord.py 2.0.1). Never seems to return from await channel.connect()

edit: ignore me, forcing discord.py to update to 2.3.2 via pip install -U discord.py[voice] fixed it