Search code examples
python-3.xffmpegdiscorddiscord.pyreplit

How to make the discord bot queue local mp3?


I'm new to python, so I wonder if there's a way to do so.

Here's my play mp3 command:

@bot.command()
async def play_song1(ctx):
  global voice
  channel = ctx.message.author.voice.channel
  voice = get(bot.voice_clients, guild=ctx.guild)

  if voice and voice.is_connected():
    await voice.move_to(channel)
  else:
    voice = await channel.connect()
    voice.play(discord.FFmpegPCMAudio('./mp3/song1.mp3'))
    voice.source = discord.PCMVolumeTransformer(voice.source)
    voice.source.volume = 0.1
    await ctx.send ('playing')
    while voice.is_playing():
      await asyncio.sleep(.1)  
    await voice.disconnect()

I made 2 more same commands but for song2 and song3, and now I want to queue the mp3 when someone calls them.


Solution

  • Seen as if you're not using cogs, you could try something like this:

    guild_queues = {}  # Multi-server support as a dict, just use a list for one server
    
    # EDIT: Map song names in a dict
    play_messages = {
        "song1": "Now playing something cool!",
        "song2": "And something even cooler just started playing!",
        "song3": "THE COOLEST!"
    }
    
    
    async def handle_queue(ctx, song):
        voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
        channel = ctx.author.voice.channel
        if voice and channel and voice.channel != channel:
            await voice.move_to(channel)
        elif not voice and channel:
            voice = await channel.connect()
        if not voice.is_playing():
            audio = discord.FFmpegPCMAudio(f"./{song}.mp3")
            source = discord.PCMVolumeTransformer(audio)
            source.volume = 0.1
            voice.play(audio)
            await ctx.send(play_messages[song])
            while voice.is_playing():
                await asyncio.sleep(.1)
            if len(guild_queues[ctx.guild.id]) > 0:
                next_song = guild_queues[ctx.guild.id].pop(0)
                await handle_queue(ctx, next_song)
            else:
                await voice.disconnect()
    
    
    @bot.command()
    async def play(ctx, *, song):  # I'd recommend adding the filenames as an arg, but it's up to you
        # Feel free to add a check if the filename exists
        try:
            # Get the current guild's queue
            queue = guild_queues[ctx.guild.id]
        except KeyError:
            # Create a queue if it doesn't already exist
            guild_queues[ctx.guild.id] = []
            queue = guild_queues[ctx.guild.id]
    
        voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
        queue.append(song)
        # The one song would be the one currently playing
        if voice and len(queue) > 0:
            await ctx.send("Added to queue!")
        else:
            current_song = queue.pop(0)
            await handle_queue(ctx, current_song)
    

    References: