Commit ·
cbf3f16
1
Parent(s): 1c552ae
更新用户前端
Browse files
app.py
CHANGED
|
@@ -97,6 +97,20 @@ APP_CSS = """
|
|
| 97 |
color: #475569;
|
| 98 |
font-size: 15px;
|
| 99 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
.voicegate-note {
|
| 101 |
color: #475569;
|
| 102 |
font-size: 13px;
|
|
@@ -823,53 +837,78 @@ def voicegate_user_run(audio_path: str | None, target_language: str, tts_trim_st
|
|
| 823 |
return None, "\n".join(lines), None, None, "", ""
|
| 824 |
|
| 825 |
|
| 826 |
-
with gr.Blocks(title="VoiceGate"
|
| 827 |
gr.HTML(
|
| 828 |
"""
|
| 829 |
<section class="voicegate-hero">
|
| 830 |
<h1>VoiceGate</h1>
|
| 831 |
-
<p>
|
| 832 |
</section>
|
| 833 |
"""
|
| 834 |
)
|
| 835 |
with gr.Tab("Translate"):
|
| 836 |
gr.Markdown(
|
| 837 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 838 |
1. Upload a short audio clip.
|
| 839 |
-
2.
|
| 840 |
-
3. Generate the
|
|
|
|
|
|
|
| 841 |
"""
|
| 842 |
)
|
| 843 |
with gr.Row():
|
| 844 |
with gr.Column(scale=5):
|
| 845 |
-
|
| 846 |
-
|
| 847 |
-
label="
|
| 848 |
-
|
| 849 |
-
|
| 850 |
-
|
| 851 |
-
|
| 852 |
-
user_tts_trim_start = gr.Slider(
|
| 853 |
-
label="TTS segment trim start",
|
| 854 |
-
minimum=0.0,
|
| 855 |
-
maximum=1.0,
|
| 856 |
-
value=0.0,
|
| 857 |
-
step=0.05,
|
| 858 |
-
info=(
|
| 859 |
-
"Skips the first n seconds of each generated TTS segment. "
|
| 860 |
-
"Increase this if the beginning of each generated speech segment has noise."
|
| 861 |
-
),
|
| 862 |
)
|
| 863 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 864 |
with gr.Column(scale=6):
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 873 |
user_run.click(
|
| 874 |
fn=voicegate_user_run,
|
| 875 |
inputs=[user_audio, user_target_language, user_tts_trim_start],
|
|
@@ -922,4 +961,4 @@ with gr.Blocks(title="VoiceGate", css=APP_CSS) as demo:
|
|
| 922 |
|
| 923 |
|
| 924 |
if __name__ == "__main__":
|
| 925 |
-
demo.launch()
|
|
|
|
| 97 |
color: #475569;
|
| 98 |
font-size: 15px;
|
| 99 |
}
|
| 100 |
+
.voicegate-links a {
|
| 101 |
+
display: inline-block;
|
| 102 |
+
margin: 4px 10px 4px 0;
|
| 103 |
+
}
|
| 104 |
+
.voicegate-section {
|
| 105 |
+
border: 1px solid #e5e7eb;
|
| 106 |
+
border-radius: 8px;
|
| 107 |
+
padding: 14px;
|
| 108 |
+
background: #ffffff;
|
| 109 |
+
}
|
| 110 |
+
.voicegate-section h3 {
|
| 111 |
+
margin: 0 0 8px;
|
| 112 |
+
font-size: 16px;
|
| 113 |
+
}
|
| 114 |
.voicegate-note {
|
| 115 |
color: #475569;
|
| 116 |
font-size: 13px;
|
|
|
|
| 837 |
return None, "\n".join(lines), None, None, "", ""
|
| 838 |
|
| 839 |
|
| 840 |
+
with gr.Blocks(title="VoiceGate") as demo:
|
| 841 |
gr.HTML(
|
| 842 |
"""
|
| 843 |
<section class="voicegate-hero">
|
| 844 |
<h1>VoiceGate</h1>
|
| 845 |
+
<p>Cross-language dubbing for audio and video. VoiceGate combines ASR, LLM translation, multilingual TTS, subtitle timing alignment, and vocal/background separation to generate translated speech while preserving the original ambience.</p>
|
| 846 |
</section>
|
| 847 |
"""
|
| 848 |
)
|
| 849 |
with gr.Tab("Translate"):
|
| 850 |
gr.Markdown(
|
| 851 |
"""
|
| 852 |
+
VoiceGate is built with VoxCPM2 and ComfyUI. It supports multilingual dubbing for content localization, video translation, education, narration, and creator workflows. The pipeline extracts timed subtitles, translates them, generates target-language speech, aligns each speech segment back to the subtitle timeline, and mixes it with the original background audio.
|
| 853 |
+
"""
|
| 854 |
+
)
|
| 855 |
+
gr.HTML(
|
| 856 |
+
"""
|
| 857 |
+
<div class="voicegate-links">
|
| 858 |
+
<a href="https://www.runninghub.ai/ai-detail/2062442306350964737?inviteCode=rh-v1455" target="_blank">Online app - audio</a>
|
| 859 |
+
<a href="https://www.runninghub.ai/ai-detail/2062446982618238978?inviteCode=rh-v1455" target="_blank">Online app - video</a>
|
| 860 |
+
<a href="https://www.runninghub.ai/post/2062432233125928961?inviteCode=rh-v1455" target="_blank">ComfyUI workflow - audio</a>
|
| 861 |
+
<a href="https://www.runninghub.ai/post/2062445363042283522?inviteCode=rh-v1455" target="_blank">ComfyUI workflow - video</a>
|
| 862 |
+
</div>
|
| 863 |
+
"""
|
| 864 |
+
)
|
| 865 |
+
gr.Markdown(
|
| 866 |
+
"""
|
| 867 |
+
**How to use**
|
| 868 |
+
|
| 869 |
1. Upload a short audio clip.
|
| 870 |
+
2. Choose the target language.
|
| 871 |
+
3. Generate the translated dubbing and review the original and translated subtitles.
|
| 872 |
+
|
| 873 |
+
The estimated processing time is roughly equal to the duration of the uploaded audio once the Space is warm. The first run after a rebuild can take longer while the environment and models are prepared.
|
| 874 |
"""
|
| 875 |
)
|
| 876 |
with gr.Row():
|
| 877 |
with gr.Column(scale=5):
|
| 878 |
+
with gr.Group(elem_classes=["voicegate-section"]):
|
| 879 |
+
gr.Markdown("### Input")
|
| 880 |
+
user_audio = gr.Audio(label="Upload audio", type="filepath")
|
| 881 |
+
user_target_language = gr.Dropdown(
|
| 882 |
+
label="Target language",
|
| 883 |
+
choices=TARGET_LANGUAGES,
|
| 884 |
+
value="English",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 885 |
)
|
| 886 |
+
with gr.Accordion("Advanced audio cleanup", open=False):
|
| 887 |
+
user_tts_trim_start = gr.Slider(
|
| 888 |
+
label="TTS segment trim start",
|
| 889 |
+
minimum=0.0,
|
| 890 |
+
maximum=1.0,
|
| 891 |
+
value=0.0,
|
| 892 |
+
step=0.05,
|
| 893 |
+
info=(
|
| 894 |
+
"Skips the first n seconds of each generated TTS segment. "
|
| 895 |
+
"Use this to remove short noises that may appear at the beginning of generated speech segments."
|
| 896 |
+
),
|
| 897 |
+
)
|
| 898 |
+
user_run = gr.Button("Generate translated dubbing", variant="primary")
|
| 899 |
with gr.Column(scale=6):
|
| 900 |
+
with gr.Group(elem_classes=["voicegate-section"]):
|
| 901 |
+
gr.Markdown("### Output")
|
| 902 |
+
user_output_audio = gr.Audio(label="Translated dubbing audio", type="filepath")
|
| 903 |
+
with gr.Row():
|
| 904 |
+
user_source_file = gr.File(label="Original subtitle file")
|
| 905 |
+
user_translated_file = gr.File(label="Translated subtitle file")
|
| 906 |
+
with gr.Row():
|
| 907 |
+
user_source_text = gr.Textbox(label="Original subtitles", lines=8)
|
| 908 |
+
user_translated_text = gr.Textbox(label="Translated subtitles", lines=8)
|
| 909 |
+
with gr.Group(elem_classes=["voicegate-section"]):
|
| 910 |
+
gr.Markdown("### Log")
|
| 911 |
+
user_status = gr.Textbox(label="Status", lines=14, elem_classes=["voicegate-status"])
|
| 912 |
user_run.click(
|
| 913 |
fn=voicegate_user_run,
|
| 914 |
inputs=[user_audio, user_target_language, user_tts_trim_start],
|
|
|
|
| 961 |
|
| 962 |
|
| 963 |
if __name__ == "__main__":
|
| 964 |
+
demo.launch(css=APP_CSS)
|