diff --git a/requirements.txt b/requirements.txt index bf2e28a8..2e2218fc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,4 +25,5 @@ jieba_fast jieba LangSegment>=0.2.0 Faster_Whisper -wordsegment \ No newline at end of file +wordsegment +srt \ No newline at end of file diff --git a/tools/i18n/i18n.py b/tools/i18n/i18n.py index 00e91bf3..1861a034 100644 --- a/tools/i18n/i18n.py +++ b/tools/i18n/i18n.py @@ -3,22 +3,22 @@ import locale import os -def load_language_list(language): - with open(f"./i18n/locale/{language}.json", "r", encoding="utf-8") as f: +def load_language_list(language, locale_path="./i18n/locale"): + with open(os.path.join(locale_path, f"{language}.json"), "r", encoding="utf-8") as f: language_list = json.load(f) return language_list class I18nAuto: - def __init__(self, language=None): + def __init__(self, language=None, locale_path="./i18n/locale"): if language in ["Auto", None]: language = locale.getdefaultlocale()[ 0 ] # getlocale can't identify the system's language ((None, None)) - if not os.path.exists(f"./i18n/locale/{language}.json"): + if not os.path.exists(os.path.join(locale_path, f"{language}.json")): language = "en_US" self.language = language - self.language_map = load_language_list(language) + self.language_map = load_language_list(language, locale_path) def __call__(self, key): return self.language_map.get(key, key) diff --git a/tools/i18n/locale_diff.py b/tools/i18n/locale_diff.py index 674f7dd2..e5527be3 100644 --- a/tools/i18n/locale_diff.py +++ b/tools/i18n/locale_diff.py @@ -2,11 +2,12 @@ import json import os from collections import OrderedDict +dir_path = "./i18n/locale" # The path to the i18n locale directory, you can change it to your own path + # Define the standard file name -standard_file = "locale/zh_CN.json" +standard_file = os.path.join(dir_path, "zh_CN.json") # Find all JSON files in the directory -dir_path = "locale/" languages = [ os.path.join(dir_path, f) for f in os.listdir(dir_path) @@ -30,7 +31,7 @@ for lang_file in languages: # Add any missing keys to the language file for key in diff: - lang_data[key] = key + lang_data[key] = standard_data[key] # Del any extra keys to the language file for key in miss: diff --git a/tools/i18n/scan_i18n.py b/tools/i18n/scan_i18n.py index f3e52cf4..0db41df0 100644 --- a/tools/i18n/scan_i18n.py +++ b/tools/i18n/scan_i18n.py @@ -1,7 +1,20 @@ import ast -import glob import json from collections import OrderedDict +import os + +locale_path = "./i18n/locale" # The path to the i18n locale directory, you can change it to your own path +scan_list = ["./", + "GPT_SoVITS/", + "tools/" + ] # The path to the directory you want to scan, you can change it to your own path +scan_subfolders = False # Whether to scan subfolders + + +# 你想要保留的特殊词汇 +special_words_to_keep = { + +} def extract_i18n_strings(node): @@ -21,20 +34,32 @@ def extract_i18n_strings(node): return i18n_strings +strings = [] -# scan the directory for all .py files (recursively) # for each file, parse the code into an AST # for each AST, extract the i18n strings - -strings = [] -for filename in glob.iglob("**/*.py", recursive=True): - with open(filename, "r") as f: +def scan_i18n_strings(filename): + with open(filename, "r", encoding="utf-8") as f: code = f.read() if "I18nAuto" in code: tree = ast.parse(code) i18n_strings = extract_i18n_strings(tree) print(filename, len(i18n_strings)) strings.extend(i18n_strings) + + +# scan the directory for all .py files (recursively) +if scan_subfolders: + for folder in scan_list: + for dirpath, dirnames, filenames in os.walk(folder): + for filename in [f for f in filenames if f.endswith(".py")]: + scan_i18n_strings(os.path.join(dirpath, filename)) +else: + for folder in scan_list: + for filename in os.listdir(folder): + if filename.endswith(".py"): + scan_i18n_strings(os.path.join(folder, filename)) + code_keys = set(strings) """ n_i18n.py @@ -49,11 +74,13 @@ print() print("Total unique:", len(code_keys)) -standard_file = "i18n/locale/zh_CN.json" -with open(standard_file, "r", encoding="utf-8") as f: - standard_data = json.load(f, object_pairs_hook=OrderedDict) -standard_keys = set(standard_data.keys()) - +standard_file = os.path.join(locale_path, "zh_CN.json") +try: + with open(standard_file, "r", encoding="utf-8") as f: + standard_data = json.load(f, object_pairs_hook=OrderedDict) + standard_keys = set(standard_data.keys()) +except FileNotFoundError: + standard_keys = set() # Define the standard file name unused_keys = standard_keys - code_keys print("Unused keys:", len(unused_keys)) @@ -64,12 +91,18 @@ missing_keys = code_keys - standard_keys print("Missing keys:", len(missing_keys)) for missing_key in missing_keys: print("\t", missing_key) + + code_keys_dict = OrderedDict() for s in strings: - code_keys_dict[s] = s + if s in special_words_to_keep: + code_keys_dict[s] = special_words_to_keep[s] + else: + code_keys_dict[s] = s # write back +os.makedirs(locale_path, exist_ok=True) with open(standard_file, "w", encoding="utf-8") as f: json.dump(code_keys_dict, f, ensure_ascii=False, indent=4, sort_keys=True) f.write("\n") diff --git a/tools/srt_slicer/i18n/locale/en_US.json b/tools/srt_slicer/i18n/locale/en_US.json new file mode 100644 index 00000000..415d36d2 --- /dev/null +++ b/tools/srt_slicer/i18n/locale/en_US.json @@ -0,0 +1,60 @@ +{ + "List 合并小工具": "List Merge Tool", + "SRT合并切分插件": "SRT Merge and Split Plugin", + "SRT文件": "SRT File", + "SRT编辑界面": "SRT Edit Interface", + "srt文件内容": "SRT File Content", + "上传SRT文件": "Upload SRT File", + "上传文件": "Upload Files", + "两个文件夹不能相同!!!": "The two folders cannot be the same!!!", + "主文件夹": "Main Folder", + "作者: ": "Author: ", + "使用方法": "How to Use", + "保存合并后字幕": "Save Merged Subtitles", + "保存子文件夹名称": "Save Subfolder Name", + "保存文件夹": "Save Folder", + "允许最短长度": "Minimum Allowed Length", + "内容预览": "Content Preview", + "切分与保存": "Split and Save", + "切分完成": "Split Completed", + "切分并保存音频、list": "Split and Save Audio, List", + "切分预览": "Split Preview", + "判定为短间隔时长": "Judged as Short Interval Duration", + "到": " to ", + "前置保留时间": "Preceding Retention Time", + "前置添加静音时间": "Prepend Silence Time", + "句末加句号": "Add Period at the End of Sentence", + "合并后srt文本": "Merged SRT Text", + "合并后的List": "Merged List", + "合并字幕": "Merge Subtitles", + "合并字幕设置": "Subtitle Merge Settings", + "合并文件夹与List": "Merge Folder and List", + "后置保留时间": "Following Retention Time", + "后置添加静音时间": "Append Silence Time", + "扫描文件夹": "Scan Folder", + "找不到字幕!!!": "Subtitles Not Found!!!", + "找不到音频!!!": "Audio Not Found!!!", + "提供SRT文件(可使用剪映或者ASR工具获得)与原始音频文件。": "Provide SRT File (can be obtained via Clip or ASR tools) and Original Audio File.", + "提前合并时间间隔很短的字幕": "Merge Subtitles with Short Intervals in Advance", + "提示": "Tips", + "文件夹路径": "Folder Path", + "最大间隔时间": "Maximum Interval Time", + "最长允许单句长度": "Maximum Allowed Sentence Length", + "根据面板合并短句并过滤你不希望出现的句子。": "Merge short sentences according to the panel and filter out sentences you do not want to appear.", + "次文件夹": "Second Folder", + "正在切分音频": "Splitting Audio", + "正在建设,敬请期待": "Under Construction, Stay Tuned", + "注意:该文件夹已存在": "Warning: The folder already exists", + "角色名称,留空使用主文件夹的": "Role Name, Leave Blank to Use Main Folder's", + "语言": "Language", + "读取文件": "Read File", + "读取本地文件": "Read Local File", + "过滤字幕": "Filter Subtitles", + "过滤带有英文的": "Filter Out English", + "过滤设置": "Filter Settings", + "过滤词语,一行一个": "Filter Words, One Per Line", + "这是一个插件,用于依靠SRT文件得到切分与打标好的音频。": "This is a plugin for obtaining split and tagged audio based on SRT files.", + "随后保存成切分好的音频与list文件。": "Then save as split audio and list files.", + "音频文件": "Audio File", + "音频格式": "Audio Format" +} diff --git a/tools/srt_slicer/i18n/locale/zh_CN.json b/tools/srt_slicer/i18n/locale/zh_CN.json new file mode 100644 index 00000000..27567f00 --- /dev/null +++ b/tools/srt_slicer/i18n/locale/zh_CN.json @@ -0,0 +1,60 @@ +{ + "List 合并小工具": "List 合并小工具", + "SRT合并切分插件": "SRT合并切分插件", + "SRT文件": "SRT文件", + "SRT编辑界面": "SRT编辑界面", + "srt文件内容": "srt文件内容", + "上传SRT文件": "上传SRT文件", + "上传文件": "上传文件", + "两个文件夹不能相同!!!": "两个文件夹不能相同!!!", + "主文件夹": "主文件夹", + "作者: ": "作者: ", + "使用方法": "使用方法", + "保存合并后字幕": "保存合并后字幕", + "保存子文件夹名称": "保存子文件夹名称", + "保存文件夹": "保存文件夹", + "允许最短长度": "允许最短长度", + "内容预览": "内容预览", + "切分与保存": "切分与保存", + "切分完成": "切分完成", + "切分并保存音频、list": "切分并保存音频、list", + "切分预览": "切分预览", + "判定为短间隔时长": "判定为短间隔时长", + "到": "到", + "前置保留时间": "前置保留时间", + "前置添加静音时间": "前置添加静音时间", + "句末加句号": "句末加句号", + "合并后srt文本": "合并后srt文本", + "合并后的List": "合并后的List", + "合并字幕": "合并字幕", + "合并字幕设置": "合并字幕设置", + "合并文件夹与List": "合并文件夹与List", + "后置保留时间": "后置保留时间", + "后置添加静音时间": "后置添加静音时间", + "扫描文件夹": "扫描文件夹", + "找不到字幕!!!": "找不到字幕!!!", + "找不到音频!!!": "找不到音频!!!", + "提供SRT文件(可使用剪映或者ASR工具获得)与原始音频文件。": "提供SRT文件(可使用剪映或者ASR工具获得)与原始音频文件。", + "提前合并时间间隔很短的字幕": "提前合并时间间隔很短的字幕", + "提示": "提示", + "文件夹路径": "文件夹路径", + "最大间隔时间": "最大间隔时间", + "最长允许单句长度": "最长允许单句长度", + "根据面板合并短句并过滤你不希望出现的句子。": "根据面板合并短句并过滤你不希望出现的句子。", + "次文件夹": "次文件夹", + "正在切分音频": "正在切分音频", + "正在建设,敬请期待": "正在建设,敬请期待", + "注意:该文件夹已存在": "注意:该文件夹已存在", + "角色名称,留空使用主文件夹的": "角色名称,留空使用主文件夹的", + "语言": "语言", + "读取文件": "读取文件", + "读取本地文件": "读取本地文件", + "过滤字幕": "过滤字幕", + "过滤带有英文的": "过滤带有英文的", + "过滤设置": "过滤设置", + "过滤词语,一行一个": "过滤词语,一行一个", + "这是一个插件,用于依靠SRT文件得到切分与打标好的音频。": "这是一个插件,用于依靠SRT文件得到切分与打标好的音频。", + "随后保存成切分好的音频与list文件。": "随后保存成切分好的音频与list文件。", + "音频文件": "音频文件", + "音频格式": "音频格式" +} diff --git a/tools/srt_slicer/srt_utils.py b/tools/srt_slicer/srt_utils.py new file mode 100644 index 00000000..9c80fc54 --- /dev/null +++ b/tools/srt_slicer/srt_utils.py @@ -0,0 +1,139 @@ +import srt +import shutil + +def parse_srt_with_lib(content): + + subtitles = list(srt.parse(content)) + return subtitles + +def generate_srt_with_lib(subtitles): + content = srt.compose(subtitles) + return content + +def merge_subtitles_with_lib(subtitles, short_interval, max_interval, max_text_length=30, add_period=True, merge_zero_interval=True): + # 标点符号 + punctuations = ["。","!", "!", "?", "?", ";", ";", "…"] + punctuations_extanded = punctuations + punctuations_extanded.extend([ ":", ":", ",", ",", "—",]) + + # 直接合并间隔特别短的字幕 + if merge_zero_interval: + eps = short_interval + for i in range(len(subtitles) - 1, 0, -1): + if subtitles[i-1].content[-1] in punctuations_extanded: + continue + if abs(subtitles[i].start.total_seconds() - subtitles[i-1].end.total_seconds()) < eps: + subtitles[i - 1].end = subtitles[i].end + subtitles[i - 1].content += subtitles[i].content + subtitles.pop(i) + + merged_subtitles = [] + current_subtitle = None + for subtitle in subtitles: + if current_subtitle is None: + current_subtitle = subtitle + else: + current_end = current_subtitle.end.total_seconds() + next_start = subtitle.start.total_seconds() + if current_subtitle.content[-1] not in punctuations and (next_start - current_end <= max_interval and count_words_multilang(current_subtitle.content + subtitle.content) < max_text_length): + current_subtitle.end = subtitle.end + comma = ',' if current_subtitle.content[-1] not in punctuations_extanded else '' + current_subtitle.content += comma + subtitle.content + + else: + if add_period and current_subtitle.content[-1] not in punctuations_extanded: + current_subtitle.content += '。' + merged_subtitles.append(current_subtitle) + current_subtitle = subtitle + if current_subtitle is not None: + merged_subtitles.append(current_subtitle) + # 重新分配id,因为srt.compose需要id连续 + for i, subtitle in enumerate(merged_subtitles, start=1): + subtitle.index = i + return merged_subtitles + + + +def count_words_multilang(text): + # 初始化计数器 + word_count = 0 + in_word = False + + for char in text: + if char.isspace(): # 如果当前字符是空格 + in_word = False + elif char.isascii() and not in_word: # 如果是ASCII字符(英文)并且不在单词内 + word_count += 1 # 新的英文单词 + in_word = True + elif not char.isascii(): # 如果字符非英文 + word_count += 1 # 每个非英文字符单独计为一个字 + + return word_count + +import pydub, os + +def slice_audio_with_lib(audio_path, save_folder, format, subtitles, pre_preserve_time, post_preserve_time, pre_silence_time, post_silence_time, language='ZH', character='character'): + list_file = os.path.join(save_folder, 'datamapping.list') + try: + audio = pydub.AudioSegment.from_file(audio_path) + except Exception as e: + raise e + with open(list_file, 'w', encoding="utf-8") as f: + for i in range(len(subtitles)): + subtitle = subtitles[i] + start = subtitle.start.total_seconds() - pre_preserve_time + end = subtitle.end.total_seconds() + post_preserve_time + + if i < len(subtitles) - 1: + next_subtitle = subtitles[i + 1] + end = min(end, 1.0/2*(subtitle.end.total_seconds()+next_subtitle.start.total_seconds())) + if i > 0: + prev_subtitle = subtitles[i - 1] + start = max(start, 1.0/2*(prev_subtitle.end.total_seconds()+subtitle.start.total_seconds())) + try: + sliced_audio = audio[int(start * 1000):int(end * 1000)] + file_name = f'{character}_{i + 1:03d}.{format}' + save_path = os.path.join(save_folder, file_name) + sliced_audio.export(save_path, format=format) + f.write(f"{file_name}|{character}|{language}|{subtitle.content}\n") + print(f"Slice {file_name} from {start} to {end}") + except Exception as e: + raise e + +def merge_list_folders(first_list_file, second_list_file, character, first_folder, second_folder): + merged_lines = [] + character1 = "" + filenames = set() + with open(first_list_file, 'r', encoding="utf-8") as f: + first_list = f.readlines() + for line in first_list: + filename, character1, language, content = line.split('|') + filenames.add(filename) + if character=="" or character is None: + character = character1 + new_line = f"{filename}|{character}|{language}|{content}" + merged_lines.append(new_line) + with open(second_list_file, 'r', encoding="utf-8") as f: + second_list = f.readlines() + for line in second_list: + filename, _, language, content = line.split('|') + orig_filename = filename + num = 1 + while filename in filenames: + filename = f"{filename.rsplit('.', 1)[0]}_{num}.{filename.rsplit('.', 1)[1]}" + num += 1 + try: + os.rename(os.path.join(second_folder, orig_filename), os.path.join(first_folder, filename)) + except Exception as e: + raise e + new_line = f"{filename}|{character}|{language}|{content}" + merged_lines.append(new_line) + os.remove(second_list_file) + if not os.listdir(second_folder): + os.rmdir(second_folder) + with open(first_list_file, 'w', encoding="utf-8") as f: + f.writelines(merged_lines) + return "\n".join(merged_lines) + + + \ No newline at end of file diff --git a/tools/srt_slicer/webui.py b/tools/srt_slicer/webui.py new file mode 100644 index 00000000..2dd6719d --- /dev/null +++ b/tools/srt_slicer/webui.py @@ -0,0 +1,396 @@ +import gradio as gr + +import sys +import os +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) +sys.path.append(os.path.abspath(os.path.dirname(__file__))) +sys.path.append('.') +from srt_utils import ( + merge_subtitles_with_lib, + parse_srt_with_lib, + generate_srt_with_lib, + slice_audio_with_lib, + count_words_multilang, + merge_list_folders +) + +port = 8991 +is_share = True + +if len(sys.argv) > 2: + port = int(sys.argv[1]) + is_share = eval(sys.argv[2]) + + +from i18n.i18n import I18nAuto + +import os + +i18n = I18nAuto(language=None, locale_path="./tools/srt_slicer/i18n/locale") + +def merge_srt(input_text, output_text, short_interval=0.1, max_interval=1, max_text_length=30, add_period=True, merge_zero_interval=True): + original_subtitles = parse_srt_with_lib(input_text) + merged_subtitles = merge_subtitles_with_lib(original_subtitles, short_interval, max_interval, max_text_length, add_period, merge_zero_interval) + output_text = generate_srt_with_lib(merged_subtitles) + return output_text + + +def slice_audio( + input_audio, + save_folder, + audio_format, + output_text, + pre_preserve_time, + post_preserve_time, + pre_silence_time, + post_silence_time, + language, + character, + +): + if isinstance(input_audio, str) and input_audio != "": + pass + else: + gr.Warning(i18n("找不到音频!!!")) + return + if output_text == "": + gr.Warning(i18n("找不到字幕!!!")) + return + + character_folder = os.path.join(save_folder, character) + os.makedirs(character_folder, exist_ok=True) + subtitles = parse_srt_with_lib(output_text) + try: + gr.Info(f"{i18n('正在切分音频')} {input_audio} {i18n('到')} {character_folder}") + slice_audio_with_lib( + input_audio, + character_folder, + audio_format, + subtitles, + pre_preserve_time, + post_preserve_time, + pre_silence_time, + post_silence_time, + language, + character, + ) + gr.Info(f"{i18n('切分完成')} ") + except Exception as e: + gr.Warning(f"Can't Slice, Error: {e}") + +def get_relative_path(path, base): + return os.path.relpath(path, base) + +def get_srt_and_audio_files(folder): + if not os.path.exists(folder): + os.makedirs(folder, exist_ok=True) + srt_files = [] + audio_files = [] + audio_file_formats = ["mp3", "wav", "ogg", "flac"] + for root, dirs, files in os.walk(folder): + for file in files: + if file.lower().endswith(".srt"): + srt_files.append(get_relative_path(os.path.join(root, file), folder)) + for audio_file_format in audio_file_formats: + if file.lower().endswith(audio_file_format): + audio_files.append(get_relative_path(os.path.join(root, file), folder)) + srt_file = "" + audio_file = "" + if len(srt_files) > 0: + srt_file = srt_files[0] + if len(audio_files) > 0: + audio_file = audio_files[0] + return gr.Dropdown(srt_files,value=srt_file), gr.Dropdown(audio_files,value=audio_file) + +def change_srt_file(folder,srt_file): + srt_folder = os.path.dirname(os.path.join(folder, srt_file)) + basename = os.path.basename(srt_file).rsplit(".", 1)[0] + audio_file_formats = ["mp3", "wav", "ogg", "flac"] + for file in os.listdir(srt_folder): + print(f"basename: {basename}, file: {file}") + if basename.lower() in file.lower(): + for audio_file_format in audio_file_formats: + if file.lower().endswith(audio_file_format): + return gr.Dropdown(value=get_relative_path(os.path.join(srt_folder, file), folder)) + return gr.Dropdown(interactive=True) + +def filter_srt(input_text, min_length, filter_english, filter_words): + subtitles = parse_srt_with_lib(input_text) + filtered_subtitles = [] + for subtitle in subtitles: + if count_words_multilang(subtitle.content) >= min_length: + flag = False + if filter_english: + for i in subtitle.content: + if i in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": + flag = True + break + if not flag and filter_words: + filter_words.replace("\r", "\n") + for word in filter_words.split("\n"): + if word in subtitle.content: + flag = True + break + if not flag: + filtered_subtitles.append(subtitle) + return generate_srt_with_lib(filtered_subtitles) + +def load_srt_from_file(srt_file): + try: + with open(srt_file, "r", encoding="utf-8") as f: + return f.read() + except: + return "" + +def load_audio_from_file(audio_file): + try: + return gr.Audio(audio_file) + except: + return gr.Audio(value=None) + +def load_from_dropdown(input_folder, srt_files_list, audio_files_list): + if isinstance(srt_files_list, str) and isinstance(audio_files_list, str): + srt_file= os.path.join(input_folder, srt_files_list) + audio_file = os.path.join(input_folder, audio_files_list) + return load_srt_from_file(srt_file), load_audio_from_file(audio_file) + else: + return "", gr.Audio(value=None) + +def enable_gr_elements(*args): + return [gr.update(interactive=True) for _ in args] + +def disable_gr_elements(*args): + return [gr.update(interactive=False) for _ in args] + +def save_srt_to_file(srt_text, save_folder, character): + character_folder = os.path.join(save_folder, character) + os.makedirs(character_folder, exist_ok=True) + srt_file = os.path.join(character_folder, "merged.srt") + with open(srt_file, "w", encoding="utf-8") as f: + f.write(srt_text) + +def scan_list_folders(folder): + if not os.path.exists(folder): + os.makedirs(folder, exist_ok=True) + list_folders = [] + for list_folder in os.listdir(folder): + if os.path.isdir(os.path.join(folder, list_folder)): + list_folders.append(get_relative_path(os.path.join(folder, list_folder), folder)) + first_list_folder = "" + second_list_folder = "" + if len(list_folders) > 0: + first_list_folder = second_list_folder = list_folders[0] + if len(list_folders) > 1: + second_list_folder = list_folders[1] + return gr.Dropdown(list_folders, value=first_list_folder), gr.Dropdown(list_folders, value=second_list_folder) + +def preview_merged_list(first_list_folder, second_list_folder, merge_list_character_name, save_folder): + if first_list_folder == "" or second_list_folder == "": + return "" + if first_list_folder == second_list_folder: + gr.Warning(i18n("两个文件夹不能相同!!!")) + return "" + first_list_folder = os.path.join(save_folder, first_list_folder) + second_list_folder = os.path.join(save_folder, second_list_folder) + print(f"first_list_folder: {first_list_folder}, second_list_folder: {second_list_folder}") + first_list = os.path.join(first_list_folder, [file for file in os.listdir(first_list_folder) if file.lower().endswith(".list")][0]) + second_list = os.path.join(second_list_folder, [file for file in os.listdir(second_list_folder) if file.lower().endswith(".list")][0]) + try: + return merge_list_folders(first_list, second_list, merge_list_character_name, first_list_folder, second_list_folder) + except Exception as e: + gr.Warning(f"Can't Merge, Error: {e}") + return "" + + +from datetime import datetime + +def change_character_name(input_audio): + try: + input_audio_name = os.path.basename(input_audio).rsplit(".", 1)[0] + character = input_audio_name[:20] + except: + character = datetime.now().strftime("%m%d%H%M") + return gr.Textbox(value=character) + +def check_character_foldfer(folder, character): + character_folder = os.path.join(folder, character) + if os.path.exists(character_folder): + return gr.Textbox(visible=True) + return gr.Textbox(visible=False) + +with gr.Blocks() as app: + with gr.Row(): + gr.HTML(f"""
{i18n("这是一个插件,用于依靠SRT文件得到切分与打标好的音频。")}
{i18n("作者: ")}XTer
+