not-lain commited on
Commit
6015e8f
·
1 Parent(s): ac89633
Files changed (3) hide show
  1. .gitignore +2 -1
  2. app.py +45 -101
  3. requirements.txt +3 -4
.gitignore CHANGED
@@ -2,4 +2,5 @@
2
  assets/
3
  .cache
4
  test*
5
- cookies.txt
 
 
2
  assets/
3
  .cache
4
  test*
5
+ cookies.txt
6
+ .gradio
app.py CHANGED
@@ -1,42 +1,31 @@
1
  import discord
2
  from discord.ext import commands
 
3
  import gradio as gr
4
  from dotenv import load_dotenv
5
  import os
6
  import threading
7
  import asyncio
8
- from huggingface_hub import hf_hub_download
9
- import yt_dlp
10
 
11
  # Load environment variables
12
  load_dotenv()
13
- if os.path.exists('cookies.txt') is False:
14
- hf_hub_download("not-lain/secrets", "cookies.txt", repo_type="dataset",local_dir=".")
 
 
 
15
 
16
- # Check if cookies.txt exists
17
- # if not os.path.exists('cookies.txt'):
18
- # txt = os.getenv('COOKIES')
19
- # with open('cookies.txt', 'w') as f:
20
- # f.write(txt)
21
 
22
  # Bot configuration
23
  intents = discord.Intents.default()
24
  intents.message_content = True
25
- bot = commands.Bot(command_prefix='!', intents=intents)
 
26
 
27
  class MusicBot:
28
  def __init__(self):
29
  self.is_playing = False
30
  self.voice_client = None
31
- self.queue = []
32
- self.ydl_opts = {
33
- 'format': 'bestaudio/best',
34
- 'cookiefile': 'cookies.txt',
35
- 'quiet': True,
36
- 'no_warnings': True,
37
- 'extract_flat': 'in_playlist'
38
- }
39
- self.currently_playing = None
40
 
41
  async def join_voice(self, ctx):
42
  if ctx.author.voice:
@@ -45,52 +34,35 @@ class MusicBot:
45
  self.voice_client = await channel.connect()
46
  else:
47
  await self.voice_client.move_to(channel)
48
- return True
49
- return False
50
 
51
  async def play_next(self, ctx):
52
- if self.queue and not self.is_playing:
53
  self.is_playing = True
54
- url = self.queue.pop(0)
55
-
56
  try:
57
- with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
58
- info = ydl.extract_info(url, download=False)
59
- audio_url = info['url']
60
- title = info.get('title', 'Unknown title')
61
- self.currently_playing = title
62
-
63
- # Create FFmpeg audio source
64
- ffmpeg_options = {
65
- 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
66
- 'options': '-vn -bufsize 64k'
67
- }
68
- audio_source = discord.FFmpegPCMAudio(audio_url, **ffmpeg_options)
69
-
70
- def after_playing(error):
71
  self.is_playing = False
72
- self.currently_playing = None
73
- if error:
74
- print(f"Playback error: {error}")
75
  asyncio.run_coroutine_threadsafe(self.play_next(ctx), bot.loop)
76
 
77
- # Apply volume transformation and play
78
- transformed_source = discord.PCMVolumeTransformer(audio_source, volume=0.5)
79
- self.voice_client.play(transformed_source, after=after_playing)
80
-
81
- await ctx.send(f"Now playing: {title}")
82
-
83
  except Exception as e:
84
- print(f"Error playing URL {url}: {e}")
 
85
  self.is_playing = False
86
- await ctx.send(f"Error playing the song: {str(e)}")
87
- await self.play_next(ctx)
88
 
89
  music_bot = MusicBot()
90
 
 
91
  @bot.event
92
  async def on_ready():
93
- print(f'Bot is ready! Logged in as {bot.user}')
94
  print("Syncing commands...")
95
  try:
96
  await bot.tree.sync(guild=None) # Set to None for global sync
@@ -100,36 +72,31 @@ async def on_ready():
100
  except Exception as e:
101
  print(f"An error occurred while syncing commands: {e}")
102
 
103
- @bot.tree.command(name="play", description="Play a YouTube URL")
104
- async def play(interaction: discord.Interaction, url: str):
 
105
  await interaction.response.defer()
106
  ctx = await commands.Context.from_interaction(interaction)
107
-
108
- if not await music_bot.join_voice(ctx):
109
- await interaction.followup.send("You need to be in a voice channel!")
110
- return
111
 
112
- try:
113
- with yt_dlp.YoutubeDL(music_bot.ydl_opts) as ydl:
114
- info = ydl.extract_info(url, download=False)
115
- title = info.get('title', 'Unknown title')
116
-
117
- music_bot.queue.append(url)
118
- await interaction.followup.send(f'Added to queue: {title}')
119
-
120
- if not music_bot.is_playing:
121
- await music_bot.play_next(ctx)
122
- except Exception as e:
123
- await interaction.followup.send(f'Error: {str(e)}')
124
 
 
 
125
  @bot.tree.command(name="skip", description="Skip the current song")
126
  async def skip(interaction: discord.Interaction):
127
  if music_bot.voice_client:
128
  music_bot.voice_client.stop()
129
- await interaction.response.send_message('Skipped current song!')
130
  else:
131
- await interaction.response.send_message('No song is currently playing!')
 
132
 
 
133
  @bot.tree.command(name="leave", description="Disconnect bot from voice channel")
134
  async def leave(interaction: discord.Interaction):
135
  if music_bot.voice_client:
@@ -137,47 +104,24 @@ async def leave(interaction: discord.Interaction):
137
  music_bot.voice_client = None
138
  music_bot.queue = []
139
  music_bot.is_playing = False
140
- await interaction.response.send_message('Bot disconnected!')
141
  else:
142
- await interaction.response.send_message('Bot is not in a voice channel!')
143
 
144
- @bot.tree.command(name="queue", description="Show the current music queue")
145
- async def queue(interaction: discord.Interaction):
146
- await interaction.response.defer()
147
-
148
- if not music_bot.is_playing and not music_bot.queue:
149
- await interaction.followup.send("No songs in the queue!")
150
- return
151
-
152
- queue_list = []
153
- if music_bot.currently_playing:
154
- queue_list.append(f"Currently playing: {music_bot.currently_playing}")
155
-
156
- if music_bot.queue:
157
- with yt_dlp.YoutubeDL(music_bot.ydl_opts) as ydl:
158
- for i, url in enumerate(music_bot.queue, 1):
159
- try:
160
- info = ydl.extract_info(url, download=False)
161
- title = info.get('title', 'Unknown title')
162
- queue_list.append(f"{i}. {title}")
163
- except:
164
- queue_list.append(f"{i}. {url}")
165
-
166
- queue_text = "\n".join(queue_list)
167
- await interaction.followup.send(f"**Music Queue:**\n{queue_text}")
168
 
169
  def run_discord_bot():
170
- bot.run(os.getenv('DISCORD_TOKEN'))
 
171
 
172
  # Create the Gradio interface
173
  with gr.Blocks() as iface:
174
  gr.Markdown("# Discord Music Bot Control Panel")
175
  gr.Markdown("Bot is running in background")
176
-
177
  if __name__ == "__main__":
178
  # Start the Discord bot in a separate thread
179
  bot_thread = threading.Thread(target=run_discord_bot, daemon=True)
180
  bot_thread.start()
181
-
182
  # Run Gradio interface in the main thread
183
- iface.launch(debug=True)
 
1
  import discord
2
  from discord.ext import commands
3
+ from huggingface_hub import hf_hub_download
4
  import gradio as gr
5
  from dotenv import load_dotenv
6
  import os
7
  import threading
8
  import asyncio
 
 
9
 
10
  # Load environment variables
11
  load_dotenv()
12
+ if os.path.exists("assets") is False:
13
+ os.makedirs("assets", exist_ok=True)
14
+ hf_hub_download(
15
+ "not-lain/assets", "lofi.mp3", repo_type="dataset", local_dir="assets"
16
+ )
17
 
 
 
 
 
 
18
 
19
  # Bot configuration
20
  intents = discord.Intents.default()
21
  intents.message_content = True
22
+ bot = commands.Bot(command_prefix="!", intents=intents)
23
+
24
 
25
  class MusicBot:
26
  def __init__(self):
27
  self.is_playing = False
28
  self.voice_client = None
 
 
 
 
 
 
 
 
 
29
 
30
  async def join_voice(self, ctx):
31
  if ctx.author.voice:
 
34
  self.voice_client = await channel.connect()
35
  else:
36
  await self.voice_client.move_to(channel)
37
+ else:
38
+ await ctx.send("You need to be in a voice channel!")
39
 
40
  async def play_next(self, ctx):
41
+ if not self.is_playing:
42
  self.is_playing = True
 
 
43
  try:
44
+ audio_source = discord.FFmpegPCMAudio("assets/lofi.mp3")
45
+
46
+ def after_playing(e):
 
 
 
 
 
 
 
 
 
 
 
47
  self.is_playing = False
48
+ # test loop by default
49
+ if e:
50
+ print(f"Playback error: {e}")
51
  asyncio.run_coroutine_threadsafe(self.play_next(ctx), bot.loop)
52
 
53
+ self.voice_client.play(audio_source, after=after_playing)
 
 
 
 
 
54
  except Exception as e:
55
+ print(f"Error playing file: {e}")
56
+ await ctx.send("Error playing the song.")
57
  self.is_playing = False
58
+
 
59
 
60
  music_bot = MusicBot()
61
 
62
+
63
  @bot.event
64
  async def on_ready():
65
+ print(f"Bot is ready! Logged in as {bot.user}")
66
  print("Syncing commands...")
67
  try:
68
  await bot.tree.sync(guild=None) # Set to None for global sync
 
72
  except Exception as e:
73
  print(f"An error occurred while syncing commands: {e}")
74
 
75
+
76
+ @bot.tree.command(name="play", description="Play the sample music")
77
+ async def play(interaction: discord.Interaction):
78
  await interaction.response.defer()
79
  ctx = await commands.Context.from_interaction(interaction)
80
+ await music_bot.join_voice(ctx)
 
 
 
81
 
82
+ if not music_bot.is_playing:
83
+ await music_bot.play_next(ctx)
84
+ await interaction.followup.send("Playing sample music!")
85
+ else:
86
+ await interaction.followup.send("Already playing!")
 
 
 
 
 
 
 
87
 
88
+
89
+ # Replace the existing skip command with this version
90
  @bot.tree.command(name="skip", description="Skip the current song")
91
  async def skip(interaction: discord.Interaction):
92
  if music_bot.voice_client:
93
  music_bot.voice_client.stop()
94
+ await interaction.response.send_message("Skipped current song!")
95
  else:
96
+ await interaction.response.send_message("No song is currently playing!")
97
+
98
 
99
+ # Replace the existing leave command with this version
100
  @bot.tree.command(name="leave", description="Disconnect bot from voice channel")
101
  async def leave(interaction: discord.Interaction):
102
  if music_bot.voice_client:
 
104
  music_bot.voice_client = None
105
  music_bot.queue = []
106
  music_bot.is_playing = False
107
+ await interaction.response.send_message("Bot disconnected!")
108
  else:
109
+ await interaction.response.send_message("Bot is not in a voice channel!")
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  def run_discord_bot():
113
+ bot.run(os.getenv("DISCORD_TOKEN"))
114
+
115
 
116
  # Create the Gradio interface
117
  with gr.Blocks() as iface:
118
  gr.Markdown("# Discord Music Bot Control Panel")
119
  gr.Markdown("Bot is running in background")
120
+
121
  if __name__ == "__main__":
122
  # Start the Discord bot in a separate thread
123
  bot_thread = threading.Thread(target=run_discord_bot, daemon=True)
124
  bot_thread.start()
125
+
126
  # Run Gradio interface in the main thread
127
+ iface.launch(debug=True)
requirements.txt CHANGED
@@ -1,7 +1,6 @@
1
  discord.py
 
2
  PyNaCl
3
  ffmpeg-python
4
- python-dotenv
5
- spotipy
6
- gradio
7
- yt-dlp
 
1
  discord.py
2
+ youtube_dl
3
  PyNaCl
4
  ffmpeg-python
5
+ yt-dlp
6
+ python-dotenv