fixed queue skip error, implemented more /commands.

This commit is contained in:
2025-11-27 20:24:51 +00:00
parent a36977b000
commit 7f8f77fb76
4 changed files with 420 additions and 26 deletions

View File

@@ -68,7 +68,7 @@ class music(commands.Cog):
await util.join_vc(ctx)
await ctx.message.add_reaction('👍')
@commands.command(
help="Leaves the voice chat if the bot is present",
aliases=['disconnect'])
@@ -80,7 +80,8 @@ class music(commands.Cog):
# HYBRID COMMAND - works as both =play and /play
@commands.hybrid_command(
name="play",
description="Queue a song to play")
description="Queue a song to play",
aliases=['p'])
@app_commands.describe(query="YouTube URL, Spotify link, or search query")
async def play(self, ctx: Context, *, query: str):
"""Queues a song into the bot"""
@@ -95,13 +96,13 @@ class music(commands.Cog):
await ctx.defer()
await util.join_vc(ctx)
# Different responses for slash vs prefix
if not ctx.interaction:
await ctx.message.add_reaction('👍')
msg = await ctx.send("Fetching song(s)...")
#TODO potentially save requests before getting stream link
# Grab video details such as title thumbnail duration
audio = await translate.main(query, self.sp)
@@ -187,7 +188,8 @@ class music(commands.Cog):
@commands.hybrid_command(
name="queue",
description="Display the current music queue")
description="Display the current music queue",
aliases=['q', 'songs'])
async def queue_cmd(self, ctx: Context):
"""Display the current music queue"""
server = ctx.guild
@@ -208,10 +210,11 @@ class music(commands.Cog):
# Display songs
await util.display_server_queue(ctx, songs, n)
@commands.hybrid_command(
name="skip",
description="Skip the current song")
description="Skip the current song",
aliases=['s'])
@app_commands.describe(count="Number of songs to skip (default: 1)")
async def skip(self, ctx: Context, count: int = 1):
"""Skips the current song that is playing"""
@@ -231,7 +234,7 @@ class music(commands.Cog):
# Check loop mode
loop_mode = await queue.get_loop_mode(server.id)
if loop_mode == 'song' and count == 1:
# When looping song and skipping once, just restart it
ctx.voice_client.stop()
@@ -240,18 +243,19 @@ class music(commands.Cog):
# Skip specified number of songs
for _ in range(count-1):
await queue.pop(server.id, True, skip_mode=True)
# Last song gets skip_mode=True to handle loop properly
if loop_mode != 'song':
await queue.pop(server.id, True, skip_mode=True)
ctx.voice_client.stop()
await ctx.send(f"⏭️ Skipped {count} song(s)")
@commands.hybrid_command(
name="loop",
description="Toggle loop mode")
description="Toggle loop mode",
aliases=['l', 'repeat'])
@app_commands.describe(mode="Loop mode: off, song, or queue")
@app_commands.choices(mode=[
app_commands.Choice(name="Off", value="off"),
@@ -318,7 +322,8 @@ class music(commands.Cog):
@commands.hybrid_command(
name="volume",
description="Set playback volume")
description="Set playback volume",
aliases=['vol', 'v'])
@app_commands.describe(level="Volume level (0-200%, default shows current)")
async def volume(self, ctx: Context, level: int = None):
"""Set or display the current volume"""
@@ -360,7 +365,8 @@ class music(commands.Cog):
@commands.hybrid_command(
name="effect",
description="Apply audio effects to playback")
description="Apply audio effects to playback",
aliases=['fx', 'filter'])
@app_commands.describe(effect_name="The audio effect to apply (leave empty to see list)")
async def effect(self, ctx: Context, effect_name: str = None):
"""Apply or list audio effects"""
@@ -375,16 +381,16 @@ class music(commands.Cog):
current = await queue.get_effect(server.id)
emoji = queue.get_effect_emoji(current)
desc = queue.get_effect_description(current)
effects_list = '\n'.join([
f"`{e}` - {queue.get_effect_description(e)}"
f"`{e}` - {queue.get_effect_description(e)}"
for e in queue.list_all_effects()[:9] # Show first 9
])
more_effects = '\n'.join([
f"`{e}` - {queue.get_effect_description(e)}"
f"`{e}` - {queue.get_effect_description(e)}"
for e in queue.list_all_effects()[9:] # Show rest
])
await ctx.send(
f"{emoji} **Current effect:** {current} - {desc}\n\n"
f"**Available effects:**\n{effects_list}\n\n"
@@ -395,7 +401,7 @@ class music(commands.Cog):
# Set effect
effect_name = effect_name.lower()
if effect_name not in queue.list_all_effects():
await ctx.send(
f"❌ Unknown effect! Use `/effect` to see available effects.",
@@ -404,10 +410,10 @@ class music(commands.Cog):
return
await queue.set_effect(server.id, effect_name)
emoji = queue.get_effect_emoji(effect_name)
desc = queue.get_effect_description(effect_name)
# Special warning for earrape/deepfry
if effect_name in ['earrape', 'deepfry']:
await ctx.send(

View File

@@ -35,10 +35,20 @@ def get_effect_options(effect_name):
**BASE_FFMPEG_OPTS,
'options': '-vn -af "atempo=0.8,asetrate=48000*0.8,aecho=0.8:0.9:1000:0.3"'
},
'earrape': {
**BASE_FFMPEG_OPTS,
# Aggressive compression + hard clipping + bitcrushing for maximum distortion
'options': '-vn -af "volume=8,acompressor=threshold=0.001:ratio=30:attack=0.1:release=5,acrusher=bits=8:mix=0.7,volume=2,alimiter=limit=0.8"'
},
'deepfry': {
**BASE_FFMPEG_OPTS,
# Extreme bitcrushing + bass boost + compression (meme audio effect)
'options': '-vn -af "acrusher=bits=4:mode=log:aa=1,bass=g=15,acompressor=threshold=0.001:ratio=20,volume=3"'
},
'distortion': {
**BASE_FFMPEG_OPTS,
# Pure bitcrushing distortion
'options': '-vn -af "acrusher=bits=6:mix=0.9,acompressor=threshold=0.01:ratio=15"'
'options': '-vn -af "acrusher=bits=6:mix=0.9,acompressor=threshold=0.01:ratio=15,volume=2"'
},
'reverse': {
**BASE_FFMPEG_OPTS,
@@ -76,6 +86,16 @@ def get_effect_options(effect_name):
**BASE_FFMPEG_OPTS,
'options': '-vn -af "aecho=0.8:0.88:60:0.4"'
},
'phone': {
**BASE_FFMPEG_OPTS,
# Sounds like a phone call (bandpass filter)
'options': '-vn -af "bandpass=f=1500:width_type=h:w=1000,volume=2"'
},
'megaphone': {
**BASE_FFMPEG_OPTS,
# Megaphone/radio effect
'options': '-vn -af "highpass=f=300,lowpass=f=3000,volume=2,acompressor=threshold=0.1:ratio=8"'
}
}
return effects.get(effect_name, effects['none'])
@@ -202,7 +222,12 @@ async def add_song(server_id, details, queued_by):
# Pop song from server (respects loop mode)
async def pop(server_id, ignore=False):
async def pop(server_id, ignore=False, skip_mode=False):
"""
Pop next song from queue
ignore: Skip the song without returning URL
skip_mode: True when called from skip command (affects loop song behavior)
"""
# Connect to db
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
@@ -624,6 +649,8 @@ def get_effect_emoji(effect_name):
'bassboost': '🔉💥',
'nightcore': '⚡🎀',
'slowed': '🐌💤',
'earrape': '💀📢',
'deepfry': '🍟💥',
'distortion': '⚡🔊',
'reverse': '⏪🔄',
'chipmunk': '🐿️',
@@ -634,6 +661,8 @@ def get_effect_emoji(effect_name):
'vibrato': '〰️',
'tremolo': '📳',
'echo': '🗣️💭',
'phone': '📞',
'megaphone': '📢📣'
}
return emojis.get(effect_name, '🔊')
@@ -645,6 +674,8 @@ def get_effect_description(effect_name):
'bassboost': 'MAXIMUM BASS 🔊',
'nightcore': 'Speed + pitch up (anime vibes)',
'slowed': 'Slowed + reverb (TikTok aesthetic)',
'earrape': '⚠️ Aggressive compression + distortion + clipping ⚠️',
'deepfry': '🍟 EXTREME bitcrushing + bass (meme audio) 🍟',
'distortion': 'Heavy bitcrushing distortion',
'reverse': 'Plays audio BACKWARDS',
'chipmunk': 'High pitched and fast (Alvin mode)',
@@ -655,6 +686,8 @@ def get_effect_description(effect_name):
'vibrato': 'Warbling pitch effect',
'tremolo': 'Volume oscillation',
'echo': 'Echo/reverb effect',
'phone': 'Sounds like a phone call',
'megaphone': 'Megaphone/radio effect'
}
return descriptions.get(effect_name, 'Unknown effect')

View File

@@ -211,12 +211,14 @@ async def display_server_queue(ctx: Context, songs, n):
loop_emoji = loop_emojis.get(loop_mode, '')
effect_emoji = queue.get_effect_emoji(effect)
# Progress bar (━ for filled, ─ for empty)
# Progress bar - using Unicode block characters for smooth look
progress_bar = ""
if duration > 0:
bar_length = 15
bar_length = 20 # Increased from 15 for smoother display
filled = int((percentage / 100) * bar_length)
progress_bar = f"\n{'' * filled}{'' * (bar_length - filled)} `{format_time(elapsed)} / {format_time(duration)}`"
# Use block characters: █ for filled, ░ for empty
progress_bar = f"\n{'' * filled}{'' * (bar_length - filled)} `{format_time(elapsed)} / {format_time(duration)}`"
# Now playing section
now_playing = f"### 🔊 Now Playing\n**{current_song}** {loop_emoji}{progress_bar}\n"