From 18ea01dc33cf5ef8402f4ef9193801bf7288e106 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sat, 28 Mar 2026 00:17:18 +0100 Subject: make it work + visual changes --- cogs/music/audio_playback.py | 14 +++++-- cogs/music/play_commands.py | 91 ++++++++++++++++---------------------------- 2 files changed, 43 insertions(+), 62 deletions(-) (limited to 'cogs/music') diff --git a/cogs/music/audio_playback.py b/cogs/music/audio_playback.py index 3d4f453..d23809a 100644 --- a/cogs/music/audio_playback.py +++ b/cogs/music/audio_playback.py @@ -5,8 +5,7 @@ import os import logging -from pathlib import Path - +import urllib.parse import discord import mutagen @@ -74,13 +73,17 @@ class AudioPlaybackManager: async def prepare_audio_source(source, is_url, display_name): """Prepare audio source for playback. Returns (source, final_display_name).""" if is_url: - # For URLs, use FFmpeg with the direct URL + # For URLs, use FFmpeg with the direct URL and extract clean filename ffmpeg_options = { 'options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5' } audio_source = discord.FFmpegPCMAudio(source, **ffmpeg_options) - return audio_source, display_name + # Extract clean filename for URL (remove extension and decode URL encoding) + filename = os.path.basename(source.split('?')[0]) # Remove query parameters + filename = urllib.parse.unquote(filename) # Decode URL encoding + clean_filename = os.path.splitext(filename)[0] # Remove file extension + return audio_source, clean_filename else: # For local files, use default options audio_source = discord.FFmpegPCMAudio(source=source) @@ -93,8 +96,11 @@ class AudioPlaybackManager: if title: display_name = title logger.debug(f"Read metadata - title: {title}") + else: + display_name = os.path.splitext(os.path.basename(source))[0] except Exception as e: logger.warning(f"Could not read metadata from {source}: {str(e)}") + display_name = os.path.splitext(os.path.basename(source))[0] return audio_source, display_name diff --git a/cogs/music/play_commands.py b/cogs/music/play_commands.py index 23808d3..a06c636 100644 --- a/cogs/music/play_commands.py +++ b/cogs/music/play_commands.py @@ -78,7 +78,7 @@ class PlayCommands(commands.Cog): """Autocomplete handler for search queries.""" query = ctx.value.lower() try: - results = await search_utils.UniversalSearcher.search_copyparty_autocomplete(query, max_results=25) + results = await search_utils.UniversalSearcher.search_copyparty_autocomplete_audio(query, max_results=25) choices = [] self.path_mapping = {} # Reset the mapping for each new query @@ -123,65 +123,40 @@ class PlayCommands(commands.Cog): await audio_playback.AudioPlaybackManager.play(ctx, stream) async def _handle_compressed_file_play(self, ctx: discord.ApplicationContext, url: str) -> None: - """Handle compressed file playback with cleanup.""" - is_url = url.startswith(('http://', 'https://')) - - if is_url: - import aiohttp - local_path = None - try: - async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - if response.status != 200: - await ctx.respond("Nie udało się pobrać pliku.", ephemeral=True) - return - - filename = url.split('/')[-1].split('?')[0] - local_path = os.path.join(self.temp_dir, filename) - os.makedirs(self.temp_dir, exist_ok=True) - - with open(local_path, 'wb') as f: - async for chunk in response.content.iter_chunked(8192): - f.write(chunk) - - compressed_path = await media_processing.AudioCompressor.compress(ctx, local_path) - if not compressed_path: - await ctx.respond("Nie udało się skompresować pliku.", ephemeral=True) - return + """Download from copyparty, compress, then play locally.""" + import aiohttp + local_path = None + compressed_path = None + try: + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status != 200: + await ctx.respond("Nie udało się pobrać pliku.", ephemeral=True) + return - try: - await audio_playback.AudioPlaybackManager.play(ctx, compressed_path, delete_after_play=True) - except Exception as e: - if os.path.exists(compressed_path): - try: - os.remove(compressed_path) - except Exception: - pass - raise e - finally: - if os.path.exists(local_path): - try: - os.remove(local_path) - except Exception: - pass - except Exception as e: - logger.error(f"Error downloading file from URL: {str(e)}", exc_info=True) - await ctx.respond(f"Błąd pobierania pliku: {str(e)}", ephemeral=True) - else: - compressed_path = await media_processing.AudioCompressor.compress(ctx, url) + filename = url.split('/')[-1].split('?')[0] + filename = urllib.parse.unquote(filename) + local_path = os.path.join(self.temp_dir, filename) + os.makedirs(self.temp_dir, exist_ok=True) + + with open(local_path, 'wb') as f: + async for chunk in response.content.iter_chunked(8192): + f.write(chunk) + + compressed_path = await media_processing.AudioCompressor.compress(ctx, local_path) if not compressed_path: - await ctx.respond("Nie udało się skompresować pliku.", ephemeral=True) return - try: - await audio_playback.AudioPlaybackManager.play(ctx, compressed_path, delete_after_play=True) - except Exception as e: - if os.path.exists(compressed_path): - try: - os.remove(compressed_path) - except Exception: - pass - raise e + await audio_playback.AudioPlaybackManager.play(ctx, compressed_path, delete_after_play=True) + except Exception as e: + logger.error(f"Error in compressed playback: {str(e)}", exc_info=True) + await ctx.respond(f"Błąd: {str(e)}", ephemeral=True) + finally: + if local_path and os.path.exists(local_path): + try: + os.remove(local_path) + except Exception: + pass async def _handle_local_file_play(self, ctx: discord.ApplicationContext, file: str, compressed: bool) -> None: """Handle file playback from copyparty URL.""" @@ -209,14 +184,14 @@ class PlayCommands(commands.Cog): ), compressed: bool = discord.Option( bool, - "Czy skompresować dźwięk? (tylko dla plików lokalnych)", + "Czy skompresować dźwięk?", default=False ) ): """Odtwarza wybrany plik dźwiękowy lub stream internetowy.""" await ctx.defer() - if not self._validate_play_inputs(file, stream, ctx): + if not await self._validate_play_inputs(file, stream, ctx): return try: -- cgit v1.2.3