[Python] Python Discord Music Bot: Playing next song while current song is playing

Discussão em 'Python' iniciado por Stack, Fevereiro 8, 2025.

  1. Stack

    Stack Membro Participativo

    I've been working on a Discord bot and got it working 90% of the time. On some occasions, the bot will be playing a song and it will stop playing and just move to the next song. My assumption is that it's because of how I am handling my play command and the play_next command as well.

    I've tried to re-arrange the code, change functionality, etc. without success.

    Here are the two commands:

    @client.command(name="p")
    async def play(ctx, *, search_query: str):
    global bot_disconnect
    try:
    # Only start a song if the user trying to play a song is in a voice channel
    if ctx.author.voice:
    voice_channel = ctx.author.voice.channel
    voice_client = await voice_channel.connect() # Find who played the song and have the bot enter that channel
    voice_clients[voice_client.guild.id] = voice_client
    else:
    await ctx.channel.send("Get in a voice channel")
    return
    except Exception as e:
    print(e)
    try:
    if is_youtube_url(search_query):
    loop = asyncio.get_event_loop() # Let's the bot multi-task (Similar behavior to interrupts in C/C++)
    data = await loop.run_in_executor(None, lambda: ytdl.extract_info(search_query, download = False))
    video_url = data["webpage_url"] # Save the youtube video URL to variable
    song_url = data["url"] # Save the extracted URL to a variable
    title = data["title"]
    else:
    url = f"ytsearch:{search_query}"
    loop = asyncio.get_event_loop() # Let's the bot multi-task (Similar behavior to interrupts in C/C++)
    data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download = False))
    entry = data['entries'][0]
    video_url = entry["webpage_url"] # Save the youtube video URL to variable
    song_url = entry["url"] # Save the extracted URL to a variable
    title = entry["title"]

    if ctx.guild.id in voice_clients and voice_clients[ctx.guild.id].is_playing():
    await queue(ctx, search_query = video_url, title = title)
    else:
    player = discord.FFmpegOpusAudio(song_url, **ffmpeg_options) # THIS IS WHAT PLAYS THE ACTUAL SONG!!!!!!
    await ctx.channel.send(f"Now Playing: {video_url} \n[DOWNLOAD LINK HERE]({song_url})") # Send the video URL to discord channel and include a download link as well
    bot_disconnect = False
    voice_clients[ctx.guild.id].play(player, after=lambda e: asyncio.run_coroutine_threadsafe(play_next(ctx), client.loop))
    except Exception as e:
    print(e)



    async def play_next(ctx):
    if len(queues) != 0 and queues.get(ctx.guild.id):
    search_query = queues[ctx.guild.id].pop(0)[0] # Pull the URL from the next index
    loop = asyncio.get_event_loop() # Let's the bot multi-task (Similar behavior to interrupts in C/C++)
    print(f"{search_query}")
    data = await loop.run_in_executor(None, lambda: ytdl.extract_info(search_query, download = False))
    player = discord.FFmpegOpusAudio(data["url"], **ffmpeg_options)
    voice_client = voice_clients[ctx.guild.id]
    voice_client.play(player, after=lambda e: asyncio.run_coroutine_threadsafe(play_next(ctx), client.loop))
    await ctx.channel.send(f"Now Playing: {data['webpage_url']} \n[DOWNLOAD LINK HERE]({data['url']})") # Send the video URL to discord channel and include a download link as well
    else:
    await ctx.send("No songs in queue")


    I can also link the full code, if required.

    Continue reading...

Compartilhe esta Página