import os import gradio as gr import json from wrapper import GeminiTTSWrapper from dotenv import load_dotenv load_dotenv() # Константы # CONFIG_DIR = "config" # CONFIG_FILE = f"{CONFIG_DIR}/config.json" DEFAULT_OUTPUT_FILE = None # Позволяет обертке генерировать имя файла с временной меткой # os.makedirs(CONFIG_DIR, exist_ok=True) # Загрузка сохраненного API ключа, если существует def load_config(): api_key = os.getenv("GOOGLE_API_KEY", "") return {"api_key": api_key} # Сохранение API ключа # def save_config(api_key): # with open(CONFIG_FILE, 'w') as f: # json.dump({"api_key": api_key}, f) # Инициализация с сохраненной конфигурацией config = load_config() tts_wrapper = GeminiTTSWrapper(config.get("api_key", "")) def update_api_key(api_key): """Обновление API ключа и сохранение его в файл конфигурации.""" # save_config(api_key) tts_wrapper.set_api_key(api_key) return "API ключ обновлен и сохранен" def generate_speech(api_key, model, voice, instructions, text, mp3_format): """Генерация речи с помощью обертки.""" if not api_key: return None, "Требуется API ключ" if not text: return None, "Требуется текст" try: # Обновление API ключа, если он изменился if api_key != tts_wrapper.api_key: tts_wrapper.set_api_key(api_key) # save_config(api_key) # Генерация речи output_path = tts_wrapper.generate_speech( text=text, model=model, voice=voice, instructions=instructions, output_file=DEFAULT_OUTPUT_FILE, convert_to_mp3=mp3_format ) return output_path, f"Сгенерированная речь сохранена в {output_path}" except Exception as e: return None, f"Ошибка: {str(e)}" # Получение списка доступных голосов available_voices = tts_wrapper.list_available_voices() # Создание интерфейса Gradio with gr.Blocks(title="Google Gemini TTS") as app: # Ввод API ключа print(os.getenv("GOOGLE_API_KEY", "")) api_key_input = gr.Textbox( label="API ключ Gemini", value=os.getenv("GOOGLE_API_KEY", ""), type="password" ) gr.Markdown("# Преобразование текста в речь Google Gemini") with gr.Row(): with gr.Column(scale=1): # Ввод инструкций instructions_input = gr.TextArea( label="Инструкции для голоса (необязательно)", placeholder="например, 'Говорить спокойно и медленно', 'Говорить взволнованным тоном'" ) # Флажок MP3 формата mp3_checkbox = gr.Checkbox( label="Конвертировать в MP3 формат", value=True, visible=False ) text_input = gr.Textbox( label="Текст для преобразования в речь", placeholder="Введите ваш текст здесь...", lines=15 ) # Выбор голоса voice_dropdown = gr.Dropdown( label="Голос", choices=available_voices, value="Laomedeia" ) # Выбор модели model_dropdown = gr.Dropdown( label="Модель", choices=[ "gemini-2.5-pro-preview-tts", "gemini-2.5-flash-preview-tts" ], value="gemini-2.5-flash-preview-tts" ) with gr.Column(scale=1): # Вывод сгенерированного аудио audio_output = gr.Audio(label="Сгенерированная речь") generation_status = gr.Textbox(label="Статус генерации", interactive=False) # Кнопка генерации generate_btn = gr.Button("Сгенерировать речь", variant="primary") # Настройка обработчиков событий api_key_input.change( update_api_key, inputs=[api_key_input], outputs=[generation_status] ) generate_btn.click( generate_speech, inputs=[ api_key_input, model_dropdown, voice_dropdown, instructions_input, text_input, mp3_checkbox ], outputs=[ audio_output, generation_status ] ) if __name__ == "__main__": app.queue() app.launch(server_name="0.0.0.0", server_port=7567)