/
diger
/
fb2tts
Обзор
Документация
Войти
/
diger
/
fb2tts
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
app.py
282 строки
9 KB
diger
fixed debug
03 июн 2026, 14:06
03 июн 2026, 14:06
3401eac
Код
Авторство
О чём код?
import gradio as gr import shutil import logging import argparse from pathlib import Path from config import config from libs.utils import get_data_list, now_dir, change_pitch from libs.accent import accentizer from libs.tts import synth from libs.tts_preprocessor import TextParse from gr_tabs.parse_tab import parse_tab from gr_tabs.tts_tab import tts_tab from gr_tabs.settings_tab import settings_tab from gr_tabs.cover_tab import cover_tab gr.set_static_paths(paths=[Path(config.data_path),]) txt_parser = TextParse(False) def refresh_data(ab_name): return {"value": ab_name, "choices": sorted(get_data_list()), "__type__": "update"} def remove_dataset(ab_name): ab_path = Path(config.data_path) / ab_name gr.Warning(f'Удаляем {ab_name}') try: if ab_path.exists(): shutil.rmtree(ab_path) except Exception as e: gr.Warning(f"Ошибка при удалении: {e}") return {"value": '', "choices": sorted(get_data_list()), "__type__": "update"}, \ {"visible": False, "__type__": "update"} def save_drop_dataset_audio(dropbox): dropbox_path = Path(dropbox) ab_file = dropbox_path.name ab_name = dropbox_path.stem ab_path = Path(config.data_path) / ab_name if not ab_path.exists(): ab_path.mkdir(parents=True, exist_ok=True) destination_path = ab_path / ab_file if destination_path.exists(): destination_path.unlink() try: content = dropbox_path.read_bytes() destination_path.write_bytes(content) gr.Info("Файл загружен", duration=4) except Exception as e: gr.Warning(f"Ошибка при копировании файла: {e}") return refresh_data('') return refresh_data(ab_name) def toggle_tab(ab_path): return gr.Tabs(visible=True, selected=0), ab_path def put_accents(string): string = accentizer.process_accent(string, r'\\+\\w+|\\w+\\+\\w+') return string def text_to_audio(string, spk, rate=1, noise=None, pitch=None, ref_audio=None, ref_text=''): if not synth: return gr.update(label = "Модель не загружена!") np_audio, sr = synth.synth_audio(txt_parser.garbage(string), spk, rate, noise, ref_audio, ref_text) if pitch != 50: np_audio = change_pitch(np_audio, sr, pitch) return (sr, np_audio) tts_models_list = [ ('Vosk 0.9 (5 голосов)', 1), ('Vosk 0.10 (dev. 56 голосов)', 2), ('Silero v5 (5 голосов)', 3), ('Silero v5_cis (60 голосов)', 4), ('Misha24-10 (F5-TTS)', 5), ('ESpeech-TTS (F5-TTS)', 6) ] accent_models_list = [ ('RuAccent', 1), ('Silero stress', 2), ] def tts_model_load(ver, progress=gr.Progress()): return synth.load(ver) def acc_model_load(ver, progress=gr.Progress()): return accentizer.load(ver) def change_tts_model(mver): sp_list = synth.speakers_list() speaker = sp_list[0] if isinstance(speaker, tuple): speaker = sp_list[0][1] if mver == 5 or mver ==6: ref_group = gr.update(visible=True) else: ref_group = gr.update(visible=False) return ( gr.update(value=speaker, choices=sp_list), gr.update(visible=True), gr.update(interactive=True), ref_group ) def change_acc_model(mver): return gr.update(interactive=True) custom_theme = gr.themes.ThemeClass.load("themes/argilla.json") with gr.Blocks(title="FB2 to speech 🇷🇺") as App: tts_state = gr.State() acc_state = gr.State() with gr.Sidebar(): tts_sel = gr.Dropdown( value='', allow_custom_value=True, label='Выбрать модель TTS', choices=tts_models_list, interactive=True, ) tts_status = gr.Textbox(show_label=False, visible=True) acc_sel = gr.Dropdown( value='', allow_custom_value=True, label='Расстановка ударений', choices=accent_models_list, interactive=True, ) acc_status = gr.Textbox(show_label=False, visible=True) tts_sel.select( tts_model_load, inputs=tts_sel, outputs=[tts_state, tts_status], show_progress_on=tts_status ) acc_sel.select( acc_model_load, inputs=acc_sel, outputs=[acc_state, acc_status], show_progress_on=acc_status ) with gr.Tabs(): with gr.Tab(label="Demo TTS"): with gr.Group(visible=False) as f5_gr: with gr.Row(): ref_audio = gr.Audio(label='Ваш образец голоса') with gr.Row(): ref_text = gr.Textbox( label='Текст в образце', lines=1, placeholder="Введите текст, который звучит в образце", interactive=True ) with gr.Row(): spk_sel = gr.Dropdown( value='', label='Выбрать голос', choices=[''], interactive=True, ) speech_rate = gr.Slider( 0, 3, 1, step=0.1, label="Задать скорость", interactive=True, ) noise_lvl = gr.Slider( 0, 64, 16, step=1, label="Уровень шума(выше-лучше)", interactive=True, ) pitch_sel = gr.Slider( 0, 100, 50, step=1, label="Тембр", interactive=True, ) with gr.Row(): text_input = gr.Textbox(label='Текст', lines=2, placeholder="Введите текст для озвучки", interactive=True, max_length=220) audio_output = gr.Audio(interactive=False, buttons=[]) with gr.Row(): accent_button = gr.Button("Проставить ударения", interactive=False) tts_button = gr.Button("Преобразовать в речь", interactive=False) accent_button.click( put_accents, inputs=text_input, outputs=text_input ) tts_button.click( text_to_audio, inputs=[text_input, spk_sel, speech_rate, noise_lvl, pitch_sel,ref_audio,ref_text], outputs=audio_output ) with gr.Tab("Fb2TTS", visible=False, id="fb2tts") as fb2tts_tab: ab_state = gr.State() with gr.Row(): ab_path = gr.Dropdown( value='', show_label=False, allow_custom_value=True, choices=get_data_list(), interactive=True, ) rm_dataset = gr.Button("❌ Удалить АК") upload_text_file = gr.UploadButton("Загрузить файл", file_count="single", file_types=[".fb2", ".txt"]) with gr.Tabs(visible=False) as tabs: cover_tab(ab_path, ab_state) parse_tab(ab_path, acc_state, tts_state) tts_tab(ab_path, tts_state) upload_text_file.upload( fn=save_drop_dataset_audio, inputs=upload_text_file, outputs=[ab_path], ).then( toggle_tab, inputs=ab_path, outputs=[tabs, ab_state] ) rm_dataset.click( remove_dataset, inputs=ab_path, outputs=[ab_path, tabs] ) ab_path.select( toggle_tab, inputs=ab_path, outputs=[tabs, ab_state] ) with gr.Tab("Настройки"): settings_tab(tts_state) tts_state.change( change_tts_model, inputs=tts_state, outputs=[spk_sel, fb2tts_tab, tts_button, f5_gr] ) acc_state.change( change_acc_model, inputs=acc_state, outputs=accent_button ) if __name__ == "__main__": sound_dir = now_dir / "sound" parser = argparse.ArgumentParser(description="Параметры запуска TTS-сервера") parser.add_argument("--port", type=int, default=None, help="Порт для запуска сервера") parser.add_argument("--share", action="store_true", default=None, help="Создать публичную ссылку") parser.add_argument("--debug", action="store_true", default=None, help="Режим отладки") parser.add_argument("--server-name", type=str, default=None, help="Адрес сервера") args = parser.parse_args() config.debug = args.debug App.launch( theme=custom_theme, server_name=args.server_name or config.server_name, server_port=args.port or config.port, share=args.share or config.share, debug=args.debug or config.debug, allowed_paths=[str(sound_dir)], favicon_path='libs/fb2tts.ico' )