From 507f03e716478fce3ee9b9c3f3f5964c34b5b2dd Mon Sep 17 00:00:00 2001 From: Samlon Date: Fri, 25 Jul 2025 19:36:56 +0200 Subject: play.py fix --- cogs/downloader.py | 58 +++--------------------------- cogs/music/play.py | 84 +++++++++---------------------------------- cogs/music/play_compressed.py | 25 ++++++++----- 3 files changed, 38 insertions(+), 129 deletions(-) (limited to 'cogs') diff --git a/cogs/downloader.py b/cogs/downloader.py index c35373f..5fb3d1c 100644 --- a/cogs/downloader.py +++ b/cogs/downloader.py @@ -1,34 +1,19 @@ -import base64 import os -import os.path import tempfile +from pathlib import Path import discord -import requests import yt_dlp from discord.ext import commands from dotenv import load_dotenv # Load environment variables load_dotenv() -PIXELDRAIN_API_KEY = os.getenv('PIXELDRAIN_API_KEY') - - -def _get_auth_headers(): - """Generate authentication headers for Pixeldrain API""" - if not PIXELDRAIN_API_KEY: - raise Exception("Pixeldrain API key not found in environment variables") - - auth_string = f":{PIXELDRAIN_API_KEY}" - auth_bytes = auth_string.encode('ascii') - base64_auth = base64.b64encode(auth_bytes).decode('ascii') - return {"Authorization": f"Basic {base64_auth}"} class Downloader(commands.Cog): def __init__(self, bot): self.bot = bot - self.pixeldrain_url = "https://pixeldrain.com/api/file" @commands.slash_command( name="download", @@ -54,47 +39,14 @@ class Downloader(commands.Cog): info = ydl.extract_info(url, download=True) actual_filename = ydl.prepare_filename(info) - await ctx.followup.send("Video downloaded successfully, Uploading to pixeldrain...") - # upload to pixeldrain try: - with open(actual_filename, 'rb') as f: - files = {'file': f} - response = requests.post( - self.pixeldrain_url, - files=files, - headers={ - "Authorization": f"Basic {base64.b64encode((':' + PIXELDRAIN_API_KEY).encode()).decode()}"} - ) - - try: - response_data = response.json() - print("Pixeldrain response:", response_data) # Debug log - - if response.status_code == 201: # 201 means successful upload - file_id = response_data.get('id') - if file_id: - file_link = f"https://pixeldrain.com/u/{file_id}" - await ctx.followup.send(f"oto twoje videło\n {file_link}") - else: - await ctx.followup.send( - f"⚠️ Upload successful but no file ID returned. Response: {response_data}") - else: - error_msg = response_data.get('error', 'Unknown error') - if response.status_code == 401: - error_msg = "Invalid API key. Please check your PIXELDRAIN_API_KEY in .env file." - await ctx.followup.send(f"❌ Upload failed (Status {response.status_code}): {error_msg}") - except ValueError as e: - # If the response is not JSON - error_msg = f"Failed to parse server response: {str(e)}" - if response.text: - error_msg += f"\nResponse: {response.text[:200]}" - await ctx.followup.send(f"❌ {error_msg}") + file = discord.File(actual_filename) + await ctx.followup.send("Pobran", file=file) except Exception as e: - await ctx.followup.send(f"Error: {str(e)}") - # No need for explicit cleanup as a tempfile.TemporaryDirectory handles it automatically + await ctx.followup.send(f":(\n{str(e)}") except Exception as e: - await ctx.followup.send(f"Error: {str(e)}") + await ctx.followup.send(f":(\n{str(e)}") def setup(bot): diff --git a/cogs/music/play.py b/cogs/music/play.py index b47de03..5d82127 100644 --- a/cogs/music/play.py +++ b/cogs/music/play.py @@ -12,7 +12,6 @@ yt_dlp.utils.bug_reports_message = lambda: '' class Play(commands.Cog): def __init__(self, bot): self.bot = bot - self.queues = {} self.ydl_opts = { 'format': 'bestaudio/best', 'postprocessors': [{ @@ -27,34 +26,7 @@ class Play(commands.Cog): 'source_address': '0.0.0.0', } - def get_queue(self, guild_id): - return self.queues.setdefault(guild_id, []) - - async def play_next(self, ctx, vc, guild_id): - queue = self.get_queue(guild_id) - if queue: - title, url = queue[0] - - def after_playing(): - if queue: - queue.pop(0) - if queue: - next_title, next_url = queue[0] - if not vc.is_playing() and not vc.is_paused(): - asyncio.run_coroutine_threadsafe( - self.play_audio(ctx, vc, next_url, next_title), - self.bot.loop - ) - else: - asyncio.run_coroutine_threadsafe( - vc.disconnect(), - self.bot.loop - ) - - if not vc.is_playing() and not vc.is_paused(): - await self.play_audio(ctx, vc, url, title, after=after_playing) - - async def play_audio(self, ctx, vc, url, title, after=None): + async def play_audio(self, ctx, vc, url, title): try: with yt_dlp.YoutubeDL(self.ydl_opts) as ydl: info = await self.bot.loop.run_in_executor( @@ -71,14 +43,21 @@ class Play(commands.Cog): 'options': '-vn' } + def after_playing(error): + if error: + print(f'Player error: {error}') + coro = vc.disconnect() + fut = asyncio.run_coroutine_threadsafe(coro, self.bot.loop) + try: + fut.result() + except Exception as e: + print(f'Error disconnecting: {e}') + source = discord.FFmpegPCMAudio(url2, **ffmpeg_options) - vc.play(source, after=after) + vc.play(source, after=after_playing) await ctx.followup.send(f"gra: {title}") except Exception as e: await ctx.followup.send(f"Wystąpił błąd podczas odtwarzania: {str(e)}") - # Try to play next in the queue if there's an error - if after: - after(None) @commands.slash_command(name="grajcuj", description="grajcuj melodyje") async def play(self, ctx, *, search: str): @@ -106,41 +85,10 @@ class Play(commands.Cog): title = video['title'] url = video['link'] - # Add to queue - queue = self.get_queue(ctx.guild.id) - queue.append((title, url)) - - # If nothing is playing, start playing - if not vc.is_playing() and not vc.is_paused(): - await self.play_next(ctx, vc, ctx.guild.id) - else: - await ctx.followup.send(f"dodano do kolejki: {title}") - - @commands.slash_command(name="stop", description="zatrzymaj odtwarzanie i wyczyść kolejkę") - async def stop(self, ctx): - if ctx.voice_client: - queue = self.get_queue(ctx.guild.id) - queue.clear() - await ctx.voice_client.disconnect() - await ctx.respond("Zatrzymano odtwarzanie i wyczyszczono kolejkę") - else: - await ctx.respond("Nie jestem połączony z kanałem głosowym") - - @commands.slash_command(name="pauza", description="wstrzymaj odtwarzanie") - async def pause(self, ctx): - if ctx.voice_client and ctx.voice_client.is_playing(): - ctx.voice_client.pause() - await ctx.respond("Wstrzymano odtwarzanie") - else: - await ctx.respond("Nic nie jest teraz odtwarzane") - - @commands.slash_command(name="wznow", description="wznów odtwarzanie") - async def resume(self, ctx): - if ctx.voice_client and ctx.voice_client.is_paused(): - ctx.voice_client.resume() - await ctx.respond("Wznowiono odtwarzanie") - else: - await ctx.respond("Nic nie jest teraz wstrzymane") + # Play the audio directly + if vc.is_playing() or vc.is_paused(): + vc.stop() + await self.play_audio(ctx, vc, url, title) def setup(bot): diff --git a/cogs/music/play_compressed.py b/cogs/music/play_compressed.py index f14d75b..0d4901c 100644 --- a/cogs/music/play_compressed.py +++ b/cogs/music/play_compressed.py @@ -25,8 +25,8 @@ class GrajcujZkompresowane(commands.Cog): @staticmethod def compress_audio(input_path): base, ext = os.path.splitext(input_path) - output_path = f"{base}_compressed{ext}" - ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 500 -acodec libmp3lame -q:a 9 {output_path}" + output_path = f"{base}_compressed.opus" + ffmpeg_command = f"ffmpeg -i {input_path} -ac 1 -b:a 500 -acodec libopus {output_path}" subprocess.run(ffmpeg_command, check=True, shell=True) return output_path @@ -57,7 +57,7 @@ class GrajcujZkompresowane(commands.Cog): url = video['link'] filename = f"{video_id}.mp3" file_path = os.path.join(music_dir, filename) - compressed_file_path = os.path.join(music_dir, f"{video_id}_compressed.mp3") + compressed_file_path = os.path.join(music_dir, f"{video_id}_compressed.opus") if os.path.exists(compressed_file_path): found_file = compressed_file_path found_title = title @@ -82,11 +82,20 @@ class GrajcujZkompresowane(commands.Cog): found_file = compressed_file_path found_title = title title = found_title - if not vc.is_playing(): - vc.play(discord.FFmpegPCMAudio(found_file)) - await ctx.followup.send(f"gra (zkompresowane): {title}") - else: - await ctx.followup.send(f"dodano do koleyjki (zkompresowane): {title}") + def after_playing(error): + if error: + print(f'Player error: {error}') + coro = vc.disconnect() + fut = asyncio.run_coroutine_threadsafe(coro, self.bot.loop) + try: + fut.result() + except Exception as e: + print(f'Error disconnecting: {e}') + + if vc.is_playing() or vc.is_paused(): + vc.stop() + vc.play(discord.FFmpegPCMAudio(found_file), after=after_playing) + await ctx.followup.send(f"gra (zkompresowane): {title}") def setup(bot): -- cgit v1.2.3