Add Playlist function

This commit is contained in:
= 2025-09-20 08:18:15 +02:00
parent 91ce4aa22c
commit f488c67c3c

View file

@ -148,6 +148,68 @@ async def hallo(ctx):
"""Simple hello command."""
await ctx.send(f"Hello {ctx.author.mention}! 👋")
# =====================
# PLAYLIST QUEUE
# =====================
playlist_queue = [] # Liste from Dicts: { 'url':..., 'title':..., 'data':... }
is_playing = False
async def play_next(ctx):
global is_playing
if playlist_queue:
next_track = playlist_queue.pop(0)
player = await YTDLSource.from_url(next_track['url'], loop=bot.loop, stream=True)
ctx.voice_client.play(
player,
after=lambda e: asyncio.run_coroutine_threadsafe(play_next(ctx), bot.loop)
)
await ctx.send(f"🎶 Now playing: **{player.title}**")
is_playing = True
else:
is_playing = False
await ctx.send("✅ Playlist finished.")
@bot.command(name="add")
async def add(ctx, *, url):
"""
Fügt einen Song oder eine komplette YouTube-Playlist zur Warteschlange hinzu.
"""
# Playlist oder Einzelvideo abrufen
data = await asyncio.get_event_loop().run_in_executor(
None, lambda: ytdl.extract_info(url, download=False)
)
added_titles = []
if 'entries' in data:
for entry in data['entries']:
playlist_queue.append({'url': entry['url'], 'title': entry['title'], 'data': entry})
added_titles.append(entry['title'])
else:
playlist_queue.append({'url': data['url'], 'title': data['title'], 'data': data})
added_titles.append(data['title'])
await ctx.send(f"✅ Added {len(added_titles)} track(s) to the playlist:\n" +
"\n".join(f"- {t}" for t in added_titles[:10]) +
(f"\n… +{len(added_titles)-10} more" if len(added_titles) > 10 else ""))
if not ctx.voice_client and ctx.author.voice:
await ctx.author.voice.channel.connect()
if ctx.voice_client and not ctx.voice_client.is_playing():
await play_next(ctx)
@bot.command(name="playlist")
async def playlist_cmd(ctx):
"""
Zeigt die aktuelle Playlist/Warteschlange an.
"""
if not playlist_queue:
await ctx.send("🎵 Die Playlist ist leer.")
else:
text = "\n".join([f"{idx+1}. {track['title']}" for idx, track in enumerate(playlist_queue[:20])])
await ctx.send(f"🎵 **Aktuelle Playlist:**\n{text}")
# =====================
# YTDL / FFMPEG SETUP
# =====================
@ -165,10 +227,6 @@ ffmpeg_options = {
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
"""
Handles downloading and streaming audio from YouTube.
"""
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
@ -177,13 +235,19 @@ class YTDLSource(discord.PCMVolumeTransformer):
@classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(
None, lambda: ytdl.extract_info(url, download=not stream)
)
try:
data = await loop.run_in_executor(
None, lambda: ytdl.extract_info(url, download=not stream)
)
except Exception as e:
return None, e
if "entries" in data:
data = data["entries"][0]
filename = data["url"] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data), None
# =====================
# VOICE / MUSIC COMMANDS
@ -208,24 +272,23 @@ async def leave(ctx):
@bot.command(name="play")
async def play(ctx, *, url):
"""
Streams audio from a given YouTube URL to the connected voice channel.
Adds interactive buttons to control playback.
"""
# Connect to voice channel if not already connected
"""Streams Audio von einer YouTube URL"""
if not ctx.voice_client:
if ctx.author.voice:
await ctx.author.voice.channel.connect()
else:
await ctx.send("You are not in a voice channel!")
await ctx.send("Du bist in keinem Sprachkanal!")
return
# Start streaming
player = await YTDLSource.from_url(url, loop=bot.loop, stream=True)
player, error = await YTDLSource.from_url(url, loop=bot.loop, stream=True)
if error or not player:
await ctx.send("⚠️ Konnte den Titel nicht abspielen. "
"YouTube Restrictions blockieren möglicherweise den Zugriff.")
return
ctx.voice_client.stop()
ctx.voice_client.play(player)
# Create interactive buttons
stop_button = Button(label="Stop", style=discord.ButtonStyle.red)
pause_button = Button(label="Pause", style=discord.ButtonStyle.gray)
resume_button = Button(label="Resume", style=discord.ButtonStyle.green)
@ -245,12 +308,10 @@ async def play(ctx, *, url):
ctx.voice_client.resume()
await interaction.response.defer()
# Attach callbacks
stop_button.callback = stop_callback
pause_button.callback = pause_callback
resume_button.callback = resume_callback
# Build and send view
view = View()
view.add_item(stop_button)
view.add_item(pause_button)