如何让 discord 机器人在 x 分钟不活动后离开语音频道?

How to make a discord bot leave the voice channel after being inactive for x minutes?

我正在尝试制作一个与 discord.py 不和谐的音乐机器人。但是,我希望机器人让语音通道在一段时间内处于非活动状态,例如 5 分钟。不活动是指机器人没有播放任何歌曲。

用于开始歌曲的命令是

voice.play(discord.FFmpegPCMAudio(audio))

voice.stop()停止歌曲

voice objectdiscord.VoiceClient

您可以使用 is_playing() 方法检测您是否没有在播放音频。所以如果我要这样做,我会使用 asyncio 模块做这样的事情。

while True:
    await asyncio.sleep(5)

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

我认为这应该可行。如果您共享代码,我可以检查这是否符合您的需求,但您可以试一试。

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

嘿,我知道这个帖子快一年了,但我认为我得到了一个代码,值得发布给仍然有这个问题的任何人。

@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

所以首先我发现将它放在 on_voice_state_update 事件中更好,因为将它放在播放命令的 after 语句中会导致它 运行 每次播放歌曲时循环结束。

(如果您了解此代码的工作原理,则无需阅读其余部分,我将对其进行解释。)

好的,首先我们检查我们的机器人是否是触发事件的机器人:

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

之后我们检查它是否是一个加入事件:

elif before.channel is None:

如果之前的频道是 none,这意味着机器人不在语音频道中,然后它加入了我们正在寻找的频道。

然后如果它首先进入 elif 语句,它会声明变量 voice。我发现获得它的最快方法是使用像这样的后声明 voice = after.channel.guild.voice_client 这应该可以让你访问公会语音客户端!

然后我们进入代码的主要部分!这是机器人将 运行 检查机器人是否在玩的循环:

    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

所以我们创建了一个名为 time 的变量,它会每秒加 1,它会检测到机器人没有在播放,并确认机器人实际上没有暂停...然后如果机器人再次开始播放它 returns 归零。但如果它达到 600,即 10 分钟,它会断开机器人与频道的连接,然后它会中断循环。

哦,不用担心 @commands.Cog.listener() 这只是因为我在齿轮中使用它。如果不是,则应将其更改为 @client.event 并将 self 从函数语句中删除。

抱歉,我在教程模式下玩得太累了,我只是想向大家解释一下我的代码,哈哈。