2
votes

I am trying to make a music bot on discord with discord.py. However, I want the bot to leave the voice channel on being inactive for a certain time like 5 minutes. By inactive, I mean that the bot is not playing any songs.

The command used to start the song is

voice.play(discord.FFmpegPCMAudio(audio))

and voice.stop() to stop the song

The voice object is discord.VoiceClient.

3
and how do you play music? maybe you can use it to start function which time.sleep(...5 minutes..) and leave channel. Or maybe you will have to use thread to run code with loop which compare current time with time when music was stoped and disconnect or sleep 1 second to check again current time with time when music was stopedfuras
The only way you're going to get help for this is by specifying how you start and stop your music. Nobody is going to answer your question until you edit your question to be more focused.StarbuckBarista

3 Answers

1
votes

I think this should work. I can check it if you could share your code, but you can give it a try. Like @StarbuckBarista said we need to know more about your code.

while voice.is_playing(): #Checks if voice is playing
    await asyncio.sleep(1) #While it's playing it sleeps for 1 second
else:
    await asyncio.sleep(15) #If it's not playing it waits 15 seconds
    while voice.is_playing(): #and checks once again if the bot is not playing
        break #if it's playing it breaks
    else:
        await voice.disconnect() #if not it disconnects
1
votes

Hey I know this thread is almost an year old but I think I got a code that is worth posting for anyone that still has this question.

@commands.Cog.listener()
async def on_voice_state_update(self, member, before, after):
    
    if not member.id == self.bot.user.id:
        return

    elif before.channel is None:
        voice = after.channel.guild.voice_client
        time = 0
        while True:
            await asyncio.sleep(1)
            time = time + 1
            if voice.is_playing() and not voice.is_paused():
                time = 0
            if time == 600:
                await voice.disconnect()
            if not voice.is_connected():
                break

So first things first I found it better to put it in the on_voice_state_update event because putting it in the after statement of the play command would cause it to run that loop every time a song ends.

(If you understand how this code works you don't need to read the rest of this, I'm just gonna explain it.)

alright so first we check if our bot is the one triggering the event:

if not member.id == self.bot.user.id:
    return

after that we check if it was a join event:

elif before.channel is None:

if the before channel is none that means that the bot wasn't in a voice channel then it joined one which is what we are looking for.

then if it enters the elif statment first it declares the variable voice. the fastest way I found to get it, is by using the after statment like this voice = after.channel.guild.voice_client which should give you acess to the guilds voice client!

then we get to the main part of the code! Here is the loop that the bot will be running to check if the bot is playing or not:

    time = 0
    while True:
        await asyncio.sleep(1)
        time = time + 1
        if player.is_playing or player.is_paused:
            time = 0
        if time == 600:
            await voice.disconnect()
        if not player.is_connected:
            break

So we create a variable called time that will add 1 every second it detects the bot is not playing and it confirms that the bot isn't actually paused... then if the bot starts playing again it returns to zero. but if it reaches 600 which is 10 minutes it disconnects the bot from the channel and then it breakes the loop.

oh and don't worry about the @commands.Cog.listener() this is just cause I'm using it in a cog. If you aren't then you should change that to @client.event and remove self from the functions statments.

Sorry that I went full on tutorial mode I just like to explain my codes to people lol.

0
votes

You can detect if you’re not playing audio using the is_playing() method. So if I were to do it, I would do something like this using the asyncio module.

while True:
    await asyncio.sleep(5)

    if voice.is_playing() == False:
        await voice.disconnect()
        break