import discord from discord.ext import commands import asyncio import yt_dlp from youtubesearchpython import VideosSearch # Suppress noise about console usage from yt-dlp 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': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], 'noplaylist': True, 'quiet': True, 'no_warnings': True, 'default_search': 'auto', '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(error): 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, guild_id), 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, guild_id, after=after_playing) async def play_audio(self, ctx, vc, url, title, guild_id, after=None): try: with yt_dlp.YoutubeDL(self.ydl_opts) as ydl: info = await self.bot.loop.run_in_executor( None, lambda: ydl.extract_info(url, download=False) ) if 'entries' in info: info = info['entries'][0] url2 = info['url'] FFMPEG_OPTIONS = { 'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn' } source = discord.FFmpegPCMAudio(url2, **FFMPEG_OPTIONS) vc.play(source, after=after) 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 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): 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 vc = ctx.voice_client or await channel.connect() if vc.channel != channel: await vc.move_to(channel) # Search for the video videos_search = VideosSearch(search, limit=1) result = videos_search.result() if not result['result']: await ctx.followup.send("nie znaleziono wideo dla twojego wyszukiwania.", ephemeral=True) return video = result['result'][0] 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") def setup(bot): bot.add_cog(Play(bot))