Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import edge_tts
|
|
| 3 |
import asyncio
|
| 4 |
import tempfile
|
| 5 |
import os
|
| 6 |
-
from moviepy.editor import AudioFileClip
|
| 7 |
|
| 8 |
# 获取所有可用的语音
|
| 9 |
async def get_voices():
|
|
@@ -27,10 +27,8 @@ async def text_to_speech(text, voice, rate, pitch):
|
|
| 27 |
return tmp_path, None
|
| 28 |
|
| 29 |
# 生成SRT文件
|
| 30 |
-
def generate_srt(words, audio_duration, fps=24):
|
| 31 |
-
srt_path = os.path.join(tempfile.gettempdir(), "output_subtitles.srt")
|
| 32 |
with open(srt_path, 'w', encoding='utf-8') as srt_file:
|
| 33 |
-
# Split audio duration into segments for SRT
|
| 34 |
segment_duration = audio_duration / len(words) # Average duration per word
|
| 35 |
current_time = 0
|
| 36 |
|
|
@@ -38,7 +36,6 @@ def generate_srt(words, audio_duration, fps=24):
|
|
| 38 |
start_time = current_time
|
| 39 |
end_time = start_time + segment_duration
|
| 40 |
|
| 41 |
-
# Convert to SRT format
|
| 42 |
start_time_str = format_srt_time(start_time)
|
| 43 |
end_time_str = format_srt_time(end_time)
|
| 44 |
srt_file.write(f"{i + 1}\n{start_time_str} --> {end_time_str}\n{word}\n\n")
|
|
@@ -58,7 +55,6 @@ def format_srt_time(seconds):
|
|
| 58 |
|
| 59 |
# 文字转音频和SRT功能
|
| 60 |
async def text_to_audio_and_srt(text, voice, rate, pitch):
|
| 61 |
-
# Generate audio for the entire text
|
| 62 |
audio_path, warning = await text_to_speech(text, voice, rate, pitch)
|
| 63 |
if warning:
|
| 64 |
return None, None, warning
|
|
@@ -67,8 +63,10 @@ async def text_to_audio_and_srt(text, voice, rate, pitch):
|
|
| 67 |
audio_duration = audio_clip.duration
|
| 68 |
|
| 69 |
# Generate SRT file based on the entire text
|
|
|
|
|
|
|
| 70 |
words = text.split()
|
| 71 |
-
|
| 72 |
|
| 73 |
return audio_path, srt_path, None
|
| 74 |
|
|
@@ -81,24 +79,34 @@ def tts_interface(text, voice, rate, pitch):
|
|
| 81 |
async def create_demo():
|
| 82 |
voices = await get_voices()
|
| 83 |
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
gr.
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
| 103 |
return demo
|
| 104 |
|
|
|
|
| 3 |
import asyncio
|
| 4 |
import tempfile
|
| 5 |
import os
|
| 6 |
+
from moviepy.editor import AudioFileClip
|
| 7 |
|
| 8 |
# 获取所有可用的语音
|
| 9 |
async def get_voices():
|
|
|
|
| 27 |
return tmp_path, None
|
| 28 |
|
| 29 |
# 生成SRT文件
|
| 30 |
+
def generate_srt(words, audio_duration, srt_path, fps=24):
|
|
|
|
| 31 |
with open(srt_path, 'w', encoding='utf-8') as srt_file:
|
|
|
|
| 32 |
segment_duration = audio_duration / len(words) # Average duration per word
|
| 33 |
current_time = 0
|
| 34 |
|
|
|
|
| 36 |
start_time = current_time
|
| 37 |
end_time = start_time + segment_duration
|
| 38 |
|
|
|
|
| 39 |
start_time_str = format_srt_time(start_time)
|
| 40 |
end_time_str = format_srt_time(end_time)
|
| 41 |
srt_file.write(f"{i + 1}\n{start_time_str} --> {end_time_str}\n{word}\n\n")
|
|
|
|
| 55 |
|
| 56 |
# 文字转音频和SRT功能
|
| 57 |
async def text_to_audio_and_srt(text, voice, rate, pitch):
|
|
|
|
| 58 |
audio_path, warning = await text_to_speech(text, voice, rate, pitch)
|
| 59 |
if warning:
|
| 60 |
return None, None, warning
|
|
|
|
| 63 |
audio_duration = audio_clip.duration
|
| 64 |
|
| 65 |
# Generate SRT file based on the entire text
|
| 66 |
+
base_name = os.path.splitext(audio_path)[0]
|
| 67 |
+
srt_path = f"{base_name}_subtitle.srt"
|
| 68 |
words = text.split()
|
| 69 |
+
generate_srt(words, audio_duration, srt_path)
|
| 70 |
|
| 71 |
return audio_path, srt_path, None
|
| 72 |
|
|
|
|
| 79 |
async def create_demo():
|
| 80 |
voices = await get_voices()
|
| 81 |
|
| 82 |
+
with gr.Blocks() as demo:
|
| 83 |
+
gr.Markdown(
|
| 84 |
+
"""
|
| 85 |
+
<h1 style="text-align: center; color: #333;">Text to Speech with Subtitles</h1>
|
| 86 |
+
<p style="text-align: center; color: #555;">Convert your text to natural-sounding speech and generate subtitles (SRT) for your audio.</p>
|
| 87 |
+
""",
|
| 88 |
+
elem_id="header"
|
| 89 |
+
)
|
| 90 |
+
|
| 91 |
+
with gr.Row():
|
| 92 |
+
with gr.Column():
|
| 93 |
+
text_input = gr.Textbox(label="Input Text", lines=5, placeholder="Enter text here...")
|
| 94 |
+
voice_dropdown = gr.Dropdown(choices=[""] + list(voices.keys()), label="Select Voice", value="")
|
| 95 |
+
rate_slider = gr.Slider(minimum=-50, maximum=50, value=0, label="Rate Adjustment (%)", step=1)
|
| 96 |
+
pitch_slider = gr.Slider(minimum=-20, maximum=20, value=0, label="Pitch Adjustment (Hz)", step=1)
|
| 97 |
+
|
| 98 |
+
with gr.Column():
|
| 99 |
+
generate_button = gr.Button("Generate Audio and Subtitles", variant="primary")
|
| 100 |
+
|
| 101 |
+
output_audio = gr.Audio(label="Generated Audio", type="filepath")
|
| 102 |
+
output_srt = gr.File(label="Generated SRT", file_count="single")
|
| 103 |
+
warning_msg = gr.Markdown(label="Warning", visible=False)
|
| 104 |
+
|
| 105 |
+
generate_button.click(
|
| 106 |
+
fn=tts_interface,
|
| 107 |
+
inputs=[text_input, voice_dropdown, rate_slider, pitch_slider],
|
| 108 |
+
outputs=[output_audio, output_srt, warning_msg]
|
| 109 |
+
)
|
| 110 |
|
| 111 |
return demo
|
| 112 |
|