import os import json import discord import tempfile import logging from discord.ext import commands from gtts import gTTS import asyncio logger = logging.getLogger(__name__) class TTS(commands.Cog): def __init__(self, bot): self.bot = bot @commands.slash_command(name="tts", description="Generuje TTS dla danego tekstu") async def tts(self, ctx, text: str = discord.Option(str, "Tekst do przeczytania", required=True), output: str = discord.Option(str, "Wybierz sposób odtwarzania", choices=["file", "vc"], default="vc") ): await ctx.defer() # Create a temporary file for TTS output with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as temp_file: temp_path = temp_file.name try: # Generate and save TTS to temp file tts = gTTS(text=text, lang='pl') tts.save(temp_path) # Load settings if available volume = 1.0 # Default volume if os.path.exists('settings.json'): try: with open('settings.json') as f: data = json.load(f) volume = data.get('volume', 1.0) except (json.JSONDecodeError, KeyError) as e: logger.error(f"Error loading settings: {e}") if output == "file": try: await ctx.respond(file=discord.File(temp_path, filename='tts.mp3')) logger.info(f"Sent TTS for text: {text}") except Exception as e: logger.error(f"Error sending file: {e}") await ctx.respond("eror :c", ephemeral=True) elif output == "vc": await ctx.respond(content="\u200b", ephemeral=True) await ctx.interaction.delete_original_response() # Check if the user is in a voice channel if not (ctx.author.voice and ctx.author.voice.channel): logger.info("User is not in a voice channel") return channel = ctx.author.voice.channel try: # Connect to the voice channel if not already connected voice_client = discord.utils.get(self.bot.voice_clients, guild=channel.guild) if not voice_client or not voice_client.is_connected(): voice_client = await channel.connect() elif voice_client.channel != channel: await voice_client.move_to(channel) # Play the TTS audio with volume adjustment audio_source = discord.FFmpegPCMAudio( temp_path, options=f'-filter:a "volume={volume}"' ) voice_client.play(audio_source) logger.info(f"Playing TTS: {text}") # Wait for the audio to finish playing while voice_client.is_playing(): await asyncio.sleep(0.1) except Exception as e: logger.error(f"Error in voice channel handling: {e}") await ctx.respond("eror :c", ephemeral=True) finally: # Clean up the temporary file try: if temp_path and os.path.exists(temp_path): os.unlink(temp_path) except Exception as e: logger.error(f"Error cleaning up temp file {temp_path}: {e}") def setup(bot): bot.add_cog(TTS(bot))