Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import edge_tts | |
| import asyncio | |
| import os | |
| import uuid | |
| from pydub import AudioSegment | |
| # Fetch available voices | |
| async def get_voices(): | |
| voices = await edge_tts.VoicesManager.create() | |
| voice_list = voices.find(Language="en") | |
| return {f"{v['FriendlyName']}": v['ShortName'] for v in voice_list} | |
| # The core TTS function with Progression | |
| async def text_to_speech_progress(text, voice_name, voice_dict, progress=gr.Progress()): | |
| if not text.strip(): | |
| return None | |
| short_name = voice_dict[voice_name] | |
| # Split text into sentences or chunks for the progress bar to have "steps" | |
| chunks = [c.strip() for c in text.split('.') if c.strip()] | |
| if not chunks: chunks = [text] # Fallback for single short sentences | |
| combined_audio = AudioSegment.empty() | |
| session_id = str(uuid.uuid4()) | |
| os.makedirs(session_id, exist_ok=True) | |
| progress(0, desc="Starting AI Voice Synthesis...") | |
| for i, chunk in enumerate(chunks): | |
| # Update the progress bar | |
| percent = (i + 1) / len(chunks) | |
| progress(percent, desc=f"Processing sentence {i+1} of {len(chunks)}...") | |
| chunk_path = os.path.join(session_id, f"chunk_{i}.mp3") | |
| communicate = edge_tts.Communicate(chunk, short_name) | |
| await communicate.save(chunk_path) | |
| # Merge audio | |
| segment = AudioSegment.from_mp3(chunk_path) | |
| combined_audio += segment | |
| # Clean up the small chunk immediately to save space | |
| os.remove(chunk_path) | |
| final_path = f"tts_{session_id}.mp3" | |
| combined_audio.export(final_path, format="mp3") | |
| os.rmdir(session_id) | |
| return final_path | |
| # Gradio Setup | |
| async def main(): | |
| voice_dict = await get_voices() | |
| voice_choices = list(voice_dict.keys()) | |
| def process(text, voice, progress=gr.Progress()): | |
| # Running the async function inside the synchronous Gradio wrapper | |
| return asyncio.run(text_to_speech_progress(text, voice, voice_dict, progress)) | |
| with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo: | |
| gr.Markdown("# 🎙️ AI Voice Generator with Progress Tracker") | |
| gr.Markdown("Type your text below. The progress bar will track each sentence being processed.") | |
| with gr.Row(): | |
| with gr.Column(): | |
| input_text = gr.Textbox( | |
| label="Input Text", | |
| placeholder="Enter long text here to see the progress bar in action...", | |
| lines=8 | |
| ) | |
| voice_dropdown = gr.Dropdown( | |
| choices=voice_choices, | |
| label="Select AI Voice", | |
| value=voice_choices[0] | |
| ) | |
| submit_btn = gr.Button("Generate Voice", variant="primary") | |
| with gr.Column(): | |
| audio_output = gr.Audio(label="Resulting Audio") | |
| # Connect the button to the function and pass the progress object | |
| submit_btn.click( | |
| fn=process, | |
| inputs=[input_text, voice_dropdown], | |
| outputs=audio_output | |
| ) | |
| demo.launch() | |
| if __name__ == "__main__": | |
| asyncio.run(main()) |