Rapptz / discord.py

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

Bot randomly eixting stage channel and making it stop #7034

Open codinginpython123 opened 3 years ago

codinginpython123 commented 3 years ago

Summary

I have a discord bot that plays music in a stage channel. But after one hour or so it disconnects and stops the stage.

Reproduction Steps

  1. Install python 3.8.3
  2. Install discord.py and discord.py[voice]
  3. Run the bot
  4. Use the !music start command
  5. Wait an hour

Minimal Reproducible Code

from discord.ext import commands
from discord.utils import get,find
import discord
import os
import threading
from os import listdir
from os.path import isfile, join
import random

prefix = "??"

TOKEN = os.environ['TOKEN']

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

client = commands.Bot(command_prefix=prefix, help_command=None,intents=intents)

path = os.path.abspath(__file__).split("/")
path.pop(0)
path.pop()
path = "/"+"/".join(path)+"/"

music_playing = False

@client.event
async def on_ready():
    print("Ready")

@client.command(name="music")
async def _music(ctx: commands.Context, command):
    global music_playing
    stage: discord.StageChannel = get(ctx.guild.stage_channels,name="|--๐Ÿ”Š๐Ÿ”Šsad-music๐Ÿ”Š๐Ÿ”Š--|")
    global conn

    files = [f for f in listdir(f"{path}sad")
             if isfile(join(f"{path}sad", f))]
    random.shuffle(files)

    try:
        conn = await stage.connect()
    except discord.ClientException:
        for i in client.voice_clients:
            if i.channel.guild == ctx.guild:
                conn = i

    def _play():
        global counter
        counter = 0

        def after(e):
            if e is None:
                global counter
                if counter < len(files):
                  counter += 1
                else:
                  counter = 0
        while True:
            if music_playing:
                if not conn.is_playing():
                    audio = discord.FFmpegPCMAudio(
                        f'{path}sad/{files[counter]}', executable=f"ffmpeg")
                    try:
                        conn.play(audio, after=after)
                    except discord.ClientException:
                        pass

            else:
                break

    t = threading.Thread(target=_play, daemon=True)
    if command == "start":
        if music_playing:
            await ctx.send('Music is already playing')
        else:
            music_playing = True
            t.start()

    elif command == "stop":
        if not music_playing:
            await ctx.send('There is nothing to stop')
        else:
            music_playing = False
            conn.stop()
    elif command == "status":
        if music_playing:
            await ctx.send('Music is playing!')
        else:
            await ctx.send('Music is NOT playing!')
    elif command == 'playing':
        if music_playing:
            embed = discord.Embed(title="Now Playing",description="The song that is playing now")
            embed.add_field(name='The song that is playing right now is...',value=files[counter])
            await ctx.send(embed=embed)
        else:
            await ctx.send("Music isn't playing")
    elif command == 'disconnect':
        conn.stop()
        await conn.disconnect()

client.run(TOKEN)

Expected Results

I expected the bot to stay forever in the stage.

Actual Results

After an hour it exits and the stage closes.

Intents

default,members

System Information

Checklist

Additional Context

Bot is a stage moderator and speaker according to discord a stage shouldn't end if there is a speaker that is a stage moderator . NOTE for the code snippet: The TOKEN constant is an enviroment variable that I have set.

NCPlayz commented 3 years ago

When this occurs, is there anyone other than the bot in the stage channel?

codinginpython123 commented 3 years ago

When this occurs, is there anyone other than the bot in the stage channel?

When it occurs there is noone else in the stage

The-Bow-Hunter commented 3 years ago

Since your Code has no option to close the stage instance I assume that your bot does not keep the stage instance alive as described in the API docs. It would be interesting if this behaves the same if there is an member listening to the music and if the music is actually still playing in this moment. I can't quite figure out what the docs mean by saying a surpressed user is not counted. This might be a problem as well for your bot.

imayhaveborkedit commented 1 year ago

This issue is a bit old, but the voice connection code for the library has been rewritten. If you're still having this issue, do you mind seeing if it still happens on the latest commit?