Projects

Music Bot Code

Music Bot Code

Projects — written by by Genevieve Torkornoo

Projects — written by by Genevieve Torkornoo

import discord
from discord.ext import commands
from discord.ext import tasks
import yt_dlp
import asyncio
from dotenv import load_dotenv
import os
import time
from collections import deque
from spotipy import Spotify
from spotipy.oauth2 import SpotifyClientCredentials

from imageio_ffmpeg import get_ffmpeg_exe

ffmpeg_path = get_ffmpeg_exe()

ffmpeg_options = {
    'executable': ffmpeg_path,
    'options': '-vn'
}

# Load environment variables
load_dotenv()
TOKEN = os.getenv("MTM3NTYzOTU1MTQ1MTg2MDk5Mg.GAAlil.XDbRE4iYEdgLCqK8QmLpKS2VoyKr2JqYPGXiDE")  # Ensure you add DISCORD_TOKEN in your .env file
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!", intents=intents)

# Spotify API Setup
SPOTIFY_CLIENT_ID = "35fa18c25bd24041af97e3f8f0b27d84"
SPOTIFY_CLIENT_SECRET = "3ca1783aac3c4f87ade7faab25ce6373"

spotify = Spotify(client_credentials_manager=SpotifyClientCredentials(
    client_id=SPOTIFY_CLIENT_ID,
    client_secret=SPOTIFY_CLIENT_SECRET
))

voice_clients = {}
yt_dl_options = {"format": "bestaudio/best"}
ytdl = yt_dlp.YoutubeDL(yt_dl_options)

ffmpeg_options = {'options': '-vn'}

# Dictionary to store queues for each guild
queues = {}

# Dictionary to store the last played time for inactivity check
last_played_time = {}

# This function will check every minute if a bot has been idle for 5 minutes
@tasks.loop(minutes=1)
async def check_inactivity():
    current_time = time.time()
    for guild_id, last_time in list(last_played_time.items()):
        if current_time - last_time > 300:  # 300 seconds = 5 minutes
            if guild_id in voice_clients:
                voice_clients[guild_id].stop()  # Stop the music
                await voice_clients[guild_id].disconnect()  # Disconnect the bot
                del voice_clients[guild_id]
                del queues[guild_id]
                del last_played_time[guild_id]
                print(f"Disconnected from guild {guild_id} due to inactivity.")

# Start the inactivity check loop
@bot.event
async def on_ready():
    print(f'{bot.user} is now online and ready!')
    check_inactivity.start()

# Function to play the next song in the queue
async def play_next(ctx):
    if ctx.guild.id in queues and queues[ctx.guild.id]:
        # Get the next song from the queue
        next_song = queues[ctx.guild.id].popleft()
        song_url = next_song["url"]
        title = next_song["title"]

        # Play the song
        player = discord.FFmpegPCMAudio(song_url, **ffmpeg_options)
        voice_clients[ctx.guild.id].play(player, after=lambda e: bot.loop.create_task(play_next(ctx)))
        await ctx.send(f"Now playing: {title}")

        # Update last played time
        last_played_time[ctx.guild.id] = time.time()
    else:
        # If the queue is empty, disconnect after 10 minutes
        last_played_time[ctx.guild.id] = time.time()

        
@bot.command(name="play", help="Plays audio from a YouTube or Spotify URL")
async def play(ctx, url: str):
    try:
        # Check if the user is in a voice channel
        if not ctx.author.voice:
            await ctx.send("You must be connected to a voice channel to play music.")
            return

        # Connect to the voice channel if not already connected
        if ctx.guild.id not in voice_clients or not voice_clients[ctx.guild.id].is_connected():
            voice_client = await ctx.author.voice.channel.connect()
            voice_clients[ctx.guild.id] = voice_client

        # Determine if the URL is from Spotify or YouTube
        if "spotify.com" in url:
            # Spotify track or playlist
            if "track" in url:
                track = spotify.track(url)
                query = f"{track['name']} {track['artists'][0]['name']}"
            elif "playlist" in url:
                playlist = spotify.playlist(url)
                for item in playlist["tracks"]["items"]:
                    track = item["track"]
                    query = f"{track['name']} {track['artists'][0]['name']}"
                    await add_to_queue(ctx, query)
                await ctx.send("All songs in the playlist have been added to the queue.")
                return
            else:
                await ctx.send("Unsupported Spotify URL.")
                return
        else:
            query = url  # Assume it's a YouTube URL or search query

        # Add the song to the queue and play it if nothing is currently playing
        await add_to_queue(ctx, query)

    except Exception as e:
        print(e)
        await ctx.send("An error occurred while trying to play the song.")
        
async def add_to_queue(ctx, query):
    try:
        # Search and download metadata from YouTube
        loop = asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(f"ytsearch:{query}", download=False))
        if "entries" in data:
            data = data["entries"][0]

        song_url = data["url"]
        title = data["title"]

        # Initialize the queue if it doesn't exist for the guild
        if ctx.guild.id not in queues:
            queues[ctx.guild.id] = deque()

        # Add the song to the queue
        queues[ctx.guild.id].append({"url": song_url, "title": title})
        await ctx.send(f"Added to queue: {title}")

        # If not already playing, start playback
        if not voice_clients[ctx.guild.id].is_playing():
            await play_next(ctx)

    except Exception as e:
        print(e)
        await ctx.send("An error occurred while trying to add the song to the queue.")

# Skip command
@bot.command(name="skip", help="Skips the current song")
async def skip(ctx):
    if ctx.guild.id in voice_clients and voice_clients[ctx.guild.id].is_playing():
        voice_clients[ctx.guild.id].stop()
        await play_next(ctx)
        await ctx.send("Skipped to the next song!")
    else:
        await ctx.send("No song is currently playing.")

#loop a songs
is_looping = False

async def loop(ctx):
   global is_looping
   await ctx.send(f" Now looping{ 'enable' if is_looping else 'disabled'})

# Stop command
@bot.command(name="stop", help="Stops the audio and disconnects from the voice channel")
async def stop(ctx):
    try:
        if ctx.guild.id in voice_clients:
            voice_clients[ctx.guild.id].stop()
            await voice_clients[ctx.guild.id].disconnect()
            del voice_clients[ctx.guild.id]
            del queues[ctx.guild.id]
            del last_played_time[ctx.guild.id]  # Remove from tracking
            await ctx.send("Disconnected from the voice channel.")
        else:
            await ctx.send("I am not connected to any voice channel.")
    except Exception as e:
        print(e)
        await ctx.send("An error occurred while trying to stop the audio.")
# Run the bot
bot.run("MTM3NTYzOTU1MTQ1MTg2MDk5Mg.GAAlil.XDbRE4iYEdgLCqK8QmLpKS2VoyKr2JqYPGXiDE")

Create a free website with Framer, the website builder loved by startups, designers and agencies.

import Music from "https://framer.com/m/Music-inOxEC.js@YzcvEqwfIUYj7c7EIjb2" import Music_2 from "https://framer.com/m/Music-2-e1wWG8.js@HEQOnp805UN6C35qC49m"