discord.py icon indicating copy to clipboard operation
discord.py copied to clipboard

Trouble playing audio after connecting to voice

Open codeofdusk opened this issue 2 years ago • 11 comments

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

  • Python v3.11.5-final
  • discord.py v2.4.0-alpha
    • discord.py metadata: v2.4.0a4955+ga5d03d4a
  • aiohttp v3.8.4
  • system info: Linux 6.5.0-1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.5.3-1 (2023-09-13)

Checklist

  • [X] I have searched the open issues for duplicates.
  • [X] I have shown the entire traceback, if possible.
  • [X] I have removed my token from display, if visible.

Additional Context

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

codeofdusk avatar Oct 29 '23 01:10 codeofdusk

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 <function DiscordVoiceWebSocket.discover_ip.<locals>.get_ip_packet at 0x0000014D0BBBCFE0>
[DEBUG   ] discord.voice_state: Unregistering socket listener callback <function DiscordVoiceWebSocket.discover_ip.<locals>.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.

imayhaveborkedit avatar Oct 29 '23 04:10 imayhaveborkedit

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

@imayhaveborkedit Yes, it does.

codeofdusk avatar Oct 29 '23 06:10 codeofdusk

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?

EvieePy avatar Oct 29 '23 07:10 EvieePy

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.

codeofdusk avatar Oct 29 '23 07:10 codeofdusk

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.

EvieePy avatar Oct 29 '23 07:10 EvieePy

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?

imayhaveborkedit avatar Oct 29 '23 07:10 imayhaveborkedit

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

@imayhaveborkedit Yes, it is.

codeofdusk avatar Oct 29 '23 08:10 codeofdusk

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

codeofdusk avatar Mar 23 '24 22:03 codeofdusk

I am having this issue as well.

pxrrot avatar Apr 26 '24 23:04 pxrrot

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

jboby93 avatar May 30 '24 02:05 jboby93