import discord from discord.ext import commands import asyncio import os from fuzzywuzzy import process from dotenv import load_dotenv load_dotenv() intents = discord.Intents.default() intents.message_content = True intents.voice_states = True bot = commands.Bot(command_prefix='!', intents=intents) queued_songs = [] voice_client = None # Global variable to track voice client def find_song(query, songs_dir): best_match = None best_confidence = 0 for root, dirs, files in os.walk(songs_dir): for file in files: if file.endswith(".mp3"): song_path = os.path.join(root, file) song_name = os.path.relpath(song_path, start=songs_dir) confidence = process.extractOne(query, [song_name.replace("_", " ")])[1] if confidence > best_confidence: best_match = song_path best_confidence = confidence return best_match, best_confidence @bot.command() async def play(ctx, *, query): global voice_client if voice_client and voice_client.is_connected(): await add_to_queue(ctx, query) else: await connect_and_play(ctx, query) @bot.command() async def skip(ctx): global voice_client if voice_client and voice_client.is_playing(): voice_client.stop() @bot.command() async def stop(ctx): global voice_client if voice_client and voice_client.is_connected(): queued_songs.clear() if voice_client.is_playing(): voice_client.stop() await voice_client.disconnect() voice_client = None await ctx.send("Stopped playback and cleared queue.") async def add_to_queue(ctx, query): global voice_client songs_dir = os.getenv("SONGS_DIR") # Find the closest match to the query song_path, confidence = find_song(query, songs_dir) if confidence >= 70 and song_path: # Adjust confidence threshold as needed song_name = os.path.relpath(song_path, start=songs_dir) # Get the song name relative to songs_dir queued_songs.append((song_path, song_name)) await ctx.send(f"**Added to queue:** `{song_name}`") else: await ctx.send("Can't find a match for that song.") async def connect_and_play(ctx, query): global voice_client voice_channel = ctx.author.voice.channel if voice_channel: songs_dir = os.getenv("SONGS_DIR") # Find the closest match to the query song_path, confidence = find_song(query, songs_dir) if confidence >= 70 and song_path: # Adjust confidence threshold as needed song_name = os.path.relpath(song_path, start=songs_dir) # Get the song name relative to songs_dir queued_songs.append((song_path, song_name)) voice_client = await play_queued_songs(ctx, voice_channel) else: await ctx.send("Can't find a match for that song.") async def play_queued_songs(ctx, voice_channel): global voice_client voice_client = await voice_channel.connect() while queued_songs: song_path, song_name = queued_songs.pop(0) # Get the first song in the queue await ctx.send(f"**Now playing:** `{song_name}`") voice_client.play(discord.FFmpegPCMAudio(song_path)) while voice_client and voice_client.is_playing(): # Check if voice_client is not None await asyncio.sleep(1) if voice_client: await voice_client.disconnect() bot.run(os.getenv("DISCORD_TOKEN"))