Discord.py command to play audio in a VC and command to leave VC using interactions/slash commands. NOT ctx or 'discord.ext commands'

Question:

I am wanting to make my own personal/private bot join the voice channel I am in and play audio files. I have it able to join the VC but I can’t figure out how to make the bot leave or play music/audio using slash commands/interactions. Everywhere I look it’s just old & outdated examples. Even the discord.py github examples don’t help and rely on using ctx and discord.ext commands. (same for what I can find here on stackoverflow).

It’s something that should be SO simple but is so obfuscated with garbage examples and outdated material. Nothing with what I am wanting to do. Not cogs/classes, no ctx., nothing to do with "self". Just interactions/slash commands. "app_commands"

I also don’t need to know how to use slash commands or how to work with them. I think I have that down.

I am trying to use interaction.voice_client.play() to play audio but I just get the following error. AttributeError: 'Interaction' object has no attribute 'voice_client' I have spent all day trying to understand the discord.py documentation with no way of finding up to date examples that use slash commands/interactions. I am not even sure what to look for or where to even look in that mess of a documentation. Searching up the error just gives me no help with the search results being completely different errors, etc.

Here’s some code that I am using for the play command..I have nothing for the leave command:
(From an example in the discord.py github examples directory but edited slightly to try and allow me to use slash commands instead of just sending "!play" in the chat.)

@muise.tree.command()
@app_commands.describe(url='Youtube URL')
async def play(interaction: discord.Interaction, url: str):
    """Streams audio from a url"""

    player = await YTDLSource.from_url(url, loop=muise.loop, stream=True) 
    #no idea if muise.loop will even work. used to be "self.bot.loop" But I am not in a cog or class.
    interaction.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)

    embed = discord.Embed(title='Muise', colour=main_embed_color, timestamp=datetime.datetime.now(datetime.timezone.utc))
    embed.add_field(name='Now Playing', value=f'{player.title}')
    embed.set_footer(text=Config["author"], icon_url='https://cdn.discordapp.com/attachments/1019374213037035530/1040294855315836998/Ori_the_cutie-1.png')
    await interaction.response.send_message(embed=embed)

The expected outcome should be audio being played in the VC.

My main issue is not having the proper knowledge of how to make this work..idk what to do, where to look. I am so tired and want this simple task to be over with. Any help would be very appreciated.

Feel free to ask questions and I’ll answer them to the best of my ability.

Asked By: Ori

||

Answers:

Try doing

guild = interaction.guild
guild.voice_client.play

instead of

interaction.voice_client.play
Answered By: MrHDumpty

you should use

voices = interaction.client.voice_clients
for i in voices:
    if i.channel == interaction.user.voice.channel:
        voice = i
        break
else:
    if interaction.user.voice is not None:
        vc = interaction.user.voice.channel
        voice = await vc.connect()
    else:
        await interaction.response.defer(ephemeral=True)
        await interaction.followup.send("You are not in a voice channel.")
        return

to find the voice client

Answered By: kytpbs1
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.