import asyncio import logging import os import subprocess import discord from discord.ext import commands from youtubesearchpython import VideosSearch logger = logging.getLogger(__name__) class GrajcujZkompresowane(commands.Cog): def __init__(self, bot): self.bot = bot @staticmethod def prepend_title_to_file(file_path, title): try: with open(file_path, 'rb') as original: data = original.read() with open(file_path, 'wb') as modified: modified.write(f"{title}\n".encode('utf-8')) modified.write(data) except Exception as e: logger.error(f"Failed to prepend title: {e}", exc_info=True) @staticmethod def compress_audio(input_path): base, ext = os.path.splitext(input_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 @commands.slash_command(name="grajcuj_zkompresowane", description="grajcuj zkompresowane melodyje") async def grajcuj_zkompresowane(self, ctx, *, search: str): await ctx.defer() if not (ctx.author.voice and ctx.author.voice.channel): await ctx.followup.send("nie jesteś w kanale głosowym") return channel = ctx.author.voice.channel if ctx.voice_client is not None: vc = ctx.voice_client await vc.move_to(channel) else: vc = await channel.connect() bot_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) music_dir = os.path.join(bot_dir, "temp", "music") if not os.path.exists(music_dir): os.makedirs(music_dir) videos_search = VideosSearch(search, limit=1) result = videos_search.result() if not result['result']: await ctx.followup.send("Could not find a video for your search.", ephemeral=True) return video = result['result'][0] video_id = video['id'] title = video['title'] 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.opus") if os.path.exists(compressed_file_path): found_file = compressed_file_path found_title = title else: if not os.path.exists(file_path): cmd = [ "yt-dlp", "-x", "--audio-format", "mp3", "-o", file_path, url ] process = await asyncio.create_subprocess_exec(*cmd) await process.communicate() self.prepend_title_to_file(file_path, title) if not os.path.exists(compressed_file_path): try: compressed_file_path = self.compress_audio(file_path) except subprocess.CalledProcessError as e: await ctx.followup.send(f"skompresowanie nie powiodło się: {str(e)}", ephemeral=True) return found_file = compressed_file_path found_title = title title = found_title def after_playing(error): if error: logger.error(f'Player error: {error}') coro = vc.disconnect() fut = asyncio.run_coroutine_threadsafe(coro, self.bot.loop) try: fut.result() except Exception as e: logger.error(f'Error disconnecting: {e}', exc_info=True) 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): bot.add_cog(GrajcujZkompresowane(bot))