2024-03-20 23:49:41 +08:00

299 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import gradio as gr
import sys
sys.path.append('.')
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
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:
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,
)
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)
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)
with gr.Blocks() as app:
with gr.Row():
gr.HTML(f"""<h1>{i18n("SRT合并切分插件")}</h1>
<p>{i18n("这是一个插件用于依靠SRT文件得到切分与打标好的音频。")}</p><p>{i18n("作者: ")}<a href="https://github.com/X-T-E-R">XTer</a></p>
<h2>{i18n("使用方法")}</h2>
<ol>
<li>{i18n("提供SRT文件可使用剪映或者ASR工具获得与原始音频文件。")}</li>
<li>{i18n("根据面板合并短句并过滤你不希望出现的句子。")}</li>
<li>{i18n("随后保存成切分好的音频与list文件。")}</li>
</ol>""")
with gr.Row():
with gr.Column(scale=2) as input_col:
with gr.Tabs():
with gr.Tab(i18n("读取本地文件")):
input_folder = gr.Textbox("input/srt_and_audios", label=i18n("文件夹路径"),interactive=True)
scan_button = gr.Button(i18n("扫描文件夹"), variant="secondary",interactive=True)
srt_files_list = gr.Dropdown([], label=i18n("SRT文件"),interactive=True)
audio_files_list = gr.Dropdown([], label=i18n("音频文件"),interactive=True)
srt_read_button = gr.Button(i18n("读取文件"), variant="secondary",interactive=True)
with gr.Tab(i18n("上传SRT文件")):
input_srt_file = gr.File(label=i18n("上传SRT文件"), type="filepath", file_types=["srt"])
# input_audio_file = gr.File(label=i18n("上传音频文件"), type="audio", file_types=["mp3", "wav", "ogg"])
with gr.Tabs():
with gr.Tab(i18n("内容预览")):
input_audio = gr.Audio(type="filepath",label=i18n("音频文件"))
input_text = gr.Textbox("", lines=20, max_lines=30, label=i18n("srt文件内容"))
input_srt_file.change(load_srt_from_file, [input_srt_file], [input_text])
with gr.Column(scale=1) as control_col:
with gr.Tabs():
with gr.Tab(i18n("合并字幕设置")):
merge_zero_interval = gr.Checkbox(label=i18n("提前合并时间间隔很短的字幕"),interactive=True, value=True)
short_interval = gr.Slider(value=0.05, minimum=0, maximum=0.5, step=0.005, label=i18n("判定为短间隔时长"),interactive=True,visible=True)
max_interval = gr.Slider(value=0.8, minimum=0.1, maximum=10, step=0.1, label=i18n("最大间隔时间"),interactive=True)
max_text_length = gr.Slider(value=50,minimum=5,maximum=200,step=1, label=i18n("最长允许单句长度"),interactive=True)
add_period = gr.Checkbox(label=i18n("句末加句号"),interactive=True, value=True)
merge_button = gr.Button(i18n("合并字幕"), variant="primary")
with gr.Tab(i18n("过滤设置")):
min_length = gr.Slider(value=5, minimum=0, maximum=20, step=1, label=i18n("允许最短长度"),interactive=True)
filter_english = gr.Checkbox(label=i18n("过滤带有英文的"),interactive=True)
filter_words = gr.Textbox("", label=i18n("过滤词语,一行一个"),lines=5,max_lines=10,interactive=True)
filter_button = gr.Button(i18n("过滤字幕"), variant="primary",interactive=False)
with gr.Tab(i18n("切分与保存")):
pre_preserve_time = gr.Slider(value=0.1, minimum=0, maximum=1, step=0.01, label=i18n("前置保留时间"),interactive=True)
post_preserve_time = gr.Slider(value=0.1, minimum=0, maximum=1, step=0.01, label=i18n("后置保留时间"),interactive=True)
pre_silence_time = gr.Slider(value=0.05, minimum=0, maximum=1, step=0.01, label=i18n("前置添加静音时间"),interactive=True,visible=False)
post_silence_time = gr.Slider(value=0.1, minimum=0, maximum=1, step=0.01, label=i18n("后置添加静音时间"),interactive=True,visible=False)
language = gr.Dropdown([i18n(i) for i in ["auto", "zh", "en", "ja", "all_zh", "all_ja"]], value="auto", label=i18n("语言"),interactive=True)
audio_format = gr.Dropdown(["mp3", "wav", "ogg"], value="wav", label=i18n("音频格式"),interactive=True)
save_folder = gr.Textbox("output/sliced_audio", label=i18n("保存文件夹"),interactive=True)
character = gr.Textbox("character", label=i18n("保存子文件夹名称"),interactive=True)
save_srt_button = gr.Button(i18n("保存合并后字幕"),variant="secondary",interactive=True)
slice_audio_button = gr.Button(i18n("切分并保存音频、list"), variant="primary",interactive=False)
with gr.Column(scale=2) as output_col:
with gr.Tabs():
with gr.Tab(i18n("合并后srt文本")):
output_text = gr.Textbox("", lines=20, max_lines=30, label="Sliced SRT")
with gr.Tab(i18n("切分预览")):
gr.Textbox(i18n("正在建设,敬请期待"), label=i18n("提示"),interactive=False)
scan_button.click(get_srt_and_audio_files, [input_folder], [srt_files_list, audio_files_list])
merge_zero_interval.change(lambda x: gr.update(visible=x), [merge_zero_interval],[short_interval])
srt_files_list.change(change_srt_file, [input_folder, srt_files_list], [audio_files_list])
srt_read_button.click(
load_from_dropdown,
[input_folder, srt_files_list, audio_files_list],
[input_text, input_audio],
)
input_text.change(
disable_gr_elements,
[slice_audio_button, filter_button],
[slice_audio_button, filter_button],
).then(
change_character_name,
[input_audio],
[character],
)
input_audio.change(
change_character_name,
[input_audio],
[character],
)
merge_button.click(
merge_srt,
[
input_text,
output_text,
short_interval,
max_interval,
max_text_length,
add_period,
merge_zero_interval
],
[output_text],
).then(
enable_gr_elements,
[slice_audio_button, filter_button],
[slice_audio_button, filter_button],
)
slice_audio_button.click(
slice_audio,
[
input_audio,
save_folder,
audio_format,
output_text,
pre_preserve_time,
post_preserve_time,
pre_silence_time,
post_silence_time,
language,
character
],
)
save_srt_button.click(
save_srt_to_file,
[output_text, save_folder, character],
)
filter_button.click(
filter_srt,
[output_text, min_length, filter_english, filter_words],
[output_text],
)
save_srt_button.click
app.launch(inbrowser=True, server_port=8991, debug=True)