not-lain commited on
Commit
60d2967
1 Parent(s): cdbefc6

Add Discord music bot implementation with Gradio interface

Browse files
Files changed (4) hide show
  1. .gitignore +1 -0
  2. app.py +116 -0
  3. packages.txt +1 -0
  4. requirements.txt +5 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .env
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import discord
2
+ from discord.ext import commands
3
+ import yt_dlp # Changed from youtube_dl
4
+ import asyncio
5
+ import gradio as gr
6
+ from dotenv import load_dotenv
7
+ import os
8
+ import threading
9
+
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ # Bot configuration
14
+ intents = discord.Intents.default()
15
+ intents.message_content = True
16
+ bot = commands.Bot(command_prefix='!', intents=intents)
17
+
18
+ # YouTube DL options
19
+ ydl_opts = {
20
+ 'format': 'bestaudio/best',
21
+ 'postprocessors': [{
22
+ 'key': 'FFmpegExtractAudio',
23
+ 'preferredcodec': 'mp3',
24
+ 'preferredquality': '192',
25
+ }],
26
+ 'noplaylist': True,
27
+ 'nocheckcertificate': True,
28
+ 'ignoreerrors': False,
29
+ 'logtostderr': False,
30
+ 'quiet': True,
31
+ 'no_warnings': True,
32
+ 'default_search': 'auto',
33
+ 'source_address': '0.0.0.0'
34
+ }
35
+
36
+ # Music bot class
37
+ class MusicBot:
38
+ def __init__(self):
39
+ self.queue = []
40
+ self.is_playing = False
41
+ self.voice_client = None
42
+
43
+ async def join_voice(self, ctx):
44
+ if ctx.author.voice:
45
+ channel = ctx.author.voice.channel
46
+ if self.voice_client is None:
47
+ self.voice_client = await channel.connect()
48
+ else:
49
+ await self.voice_client.move_to(channel)
50
+ else:
51
+ await ctx.send("You need to be in a voice channel!")
52
+
53
+ async def play_next(self, ctx):
54
+ if len(self.queue) > 0:
55
+ self.is_playing = True
56
+ url = self.queue.pop(0)
57
+
58
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl: # Changed from youtube_dl
59
+ info = ydl.extract_info(url, download=False)
60
+ if 'entries' in info:
61
+ url2 = info['entries'][0]['url']
62
+ else:
63
+ url2 = info['url']
64
+
65
+ self.voice_client.play(discord.FFmpegPCMAudio(url2, **{'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5'}),
66
+ after=lambda e: asyncio.run_coroutine_threadsafe(self.play_next(ctx), bot.loop))
67
+ else:
68
+ self.is_playing = False
69
+
70
+ music_bot = MusicBot()
71
+
72
+ @bot.event
73
+ async def on_ready():
74
+ print(f'Bot is ready! Logged in as {bot.user}')
75
+
76
+ @bot.command()
77
+ async def play(ctx, url):
78
+ await music_bot.join_voice(ctx)
79
+ music_bot.queue.append(url)
80
+
81
+ if not music_bot.is_playing:
82
+ await music_bot.play_next(ctx)
83
+ await ctx.send('Playing music!')
84
+ else:
85
+ await ctx.send('Added to queue!')
86
+
87
+ @bot.command()
88
+ async def skip(ctx):
89
+ if music_bot.voice_client:
90
+ music_bot.voice_client.stop()
91
+ await ctx.send('Skipped current song!')
92
+
93
+ @bot.command()
94
+ async def leave(ctx):
95
+ if music_bot.voice_client:
96
+ await music_bot.voice_client.disconnect()
97
+ music_bot.voice_client = None
98
+ music_bot.queue = []
99
+ music_bot.is_playing = False
100
+ await ctx.send('Bot disconnected!')
101
+
102
+ def run_discord_bot():
103
+ bot.run(os.getenv('DISCORD_TOKEN'))
104
+
105
+ # Create the Gradio interface
106
+ with gr.Blocks() as iface:
107
+ gr.Markdown("# Discord Music Bot Control Panel")
108
+ gr.Markdown("Bot is running in background")
109
+
110
+ if __name__ == "__main__":
111
+ # Start the Discord bot in a separate thread
112
+ bot_thread = threading.Thread(target=run_discord_bot, daemon=True)
113
+ bot_thread.start()
114
+
115
+ # Run Gradio interface in the main thread
116
+ iface.launch(debug=True)
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ discord.py
2
+ youtube_dl
3
+ PyNaCl
4
+ ffmpeg-python
5
+ yt-dlp