Fixed up the UI to include Pause, Skip, Stop, Repeat and Volume controls

This commit is contained in:
Dan 2025-01-22 20:20:11 -05:00
parent 4f38a1a89e
commit f53f6a1173

115
audio.py
View File

@ -65,19 +65,18 @@ async def join_voice(interaction: discord.Interaction):
async def play_audio(interaction: discord.Interaction, query: str):
guild_id = interaction.guild.id
# Defer the response if not already done
if not interaction.response.is_done():
await interaction.response.defer()
# Ensure Amber is connected to a voice channel
if guild_id not in voice_clients or not voice_clients[guild_id].is_connected():
await interaction.response.defer() # Defer the response early
voice_client = await join_voice(interaction)
if voice_client is None: # If join failed
return
else:
voice_client = voice_clients[guild_id]
# Defer response if not already done
if not interaction.response.is_done():
await interaction.response.defer()
# Search for the song on YouTube
ydl_opts = {
'format': 'bestaudio/best',
@ -87,7 +86,7 @@ async def play_audio(interaction: discord.Interaction, query: str):
try:
info = ydl.extract_info(f"ytsearch:{query}", download=False)['entries'][0]
except Exception as e:
await interaction.followup.send(f"Failed to find or play the requested audio. Error: {str(e)}")
await interaction.followup.send(f"❌ **Error:** Could not find or play the requested audio. {str(e)}")
return
song_url = info['url']
@ -108,6 +107,15 @@ async def play_audio(interaction: discord.Interaction, query: str):
if not voice_client.is_playing():
await play_next(interaction)
# Send "Now Playing" embed with controls
embed = discord.Embed(
title="🎵 Now Playing",
description=f"**{title}** by {artist}",
color=discord.Color.blue()
)
view = PlaybackControls(interaction, guild_id)
await interaction.followup.send(embed=embed, view=view)
async def play_next(interaction: discord.Interaction):
guild_id = interaction.guild.id
@ -232,6 +240,101 @@ async def leave_voice(interaction: discord.Interaction):
await interaction.response.send_message("❌ **I am not connected to any voice channel.**")
# ---------- Discord UI ----------
class PlaybackControls(discord.ui.View):
def __init__(self, interaction, guild_id):
super().__init__(timeout=None) # Persistent buttons
self.interaction = interaction
self.guild_id = guild_id
@discord.ui.button(label="⏸️ Pause", style=discord.ButtonStyle.primary)
async def pause_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
voice_clients[self.guild_id].pause()
button.label = "▶️ Resume"
await interaction.response.edit_message(content="⏸️ **Paused playback.**", view=self)
elif self.guild_id in voice_clients and voice_clients[self.guild_id].is_paused():
voice_clients[self.guild_id].resume()
button.label = "⏸️ Pause"
await interaction.response.edit_message(content="▶️ **Resumed playback.**", view=self)
@discord.ui.button(label="⏭️ Skip", style=discord.ButtonStyle.secondary)
async def skip_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
voice_clients[self.guild_id].stop() # Stop triggers `play_next`
await interaction.response.send_message("⏭️ **Skipped to the next song.**", ephemeral=True)
else:
await interaction.response.send_message("❌ **No song is currently playing to skip.**", ephemeral=True)
@discord.ui.button(label="🛑 Stop", style=discord.ButtonStyle.danger)
async def stop_button(self, interaction: discord.Interaction, button: discord.ui.Button):
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
voice_clients[self.guild_id].stop()
music_queues[self.guild_id] = [] # Clear the queue
await interaction.response.send_message("🛑 **Stopped playback and cleared the queue.**", ephemeral=True)
else:
await interaction.response.send_message("❌ **No song is currently playing to stop.**", ephemeral=True)
@discord.ui.button(label="🔄 Repeat: Off", style=discord.ButtonStyle.success)
async def repeat_button(self, interaction: discord.Interaction, button: discord.ui.Button):
current_mode = repeat_modes.get(self.guild_id, "off")
new_mode = "one" if current_mode == "off" else "all" if current_mode == "one" else "off"
repeat_modes[self.guild_id] = new_mode
button.label = f"🔄 Repeat: {new_mode.capitalize()}"
await interaction.response.edit_message(content=f"🔄 **Repeat mode set to:** {new_mode.capitalize()}", view=self)
@discord.ui.button(label="🔈 Volume Down", style=discord.ButtonStyle.secondary)
async def volume_down(self, interaction: discord.Interaction, button: discord.ui.Button):
current_volume = volumes.get(self.guild_id, default_volume)
new_volume = max(0.0, current_volume - 0.1) # Decrease volume by 10%
volumes[self.guild_id] = new_volume
# Apply volume to the current source
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
source = voice_clients[self.guild_id].source
if isinstance(source, discord.PCMVolumeTransformer):
source.volume = new_volume
await interaction.response.send_message(f"🔈 **Volume decreased to {int(new_volume * 100)}%.**", ephemeral=True)
@discord.ui.button(label="🔊 Volume Up", style=discord.ButtonStyle.primary)
async def volume_up(self, interaction: discord.Interaction, button: discord.ui.Button):
current_volume = volumes.get(self.guild_id, default_volume)
new_volume = min(1.0, current_volume + 0.1) # Increase volume by 10%
volumes[self.guild_id] = new_volume
# Apply volume to the current source
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
source = voice_clients[self.guild_id].source
if isinstance(source, discord.PCMVolumeTransformer):
source.volume = new_volume
await interaction.response.send_message(f"🔊 **Volume increased to {int(new_volume * 100)}%.**", ephemeral=True)
@discord.ui.button(label="🔇 Mute/Unmute", style=discord.ButtonStyle.danger)
async def mute_toggle(self, interaction: discord.Interaction, button: discord.ui.Button):
current_volume = volumes.get(self.guild_id, default_volume)
# Toggle mute
if current_volume > 0:
volumes[self.guild_id] = 0.0
button.label = "🔊 Unmute"
else:
volumes[self.guild_id] = default_volume
button.label = "🔇 Mute"
# Apply volume to the current source
if self.guild_id in voice_clients and voice_clients[self.guild_id].is_playing():
source = voice_clients[self.guild_id].source
if isinstance(source, discord.PCMVolumeTransformer):
source.volume = volumes[self.guild_id]
status = "muted" if volumes[self.guild_id] == 0.0 else "unmuted"
await interaction.response.edit_message(content=f"🔇 **Volume {status}.**", view=self)
# ---------- Recommendations ----------
def fetch_related_songs(song_title, artist):
"""