Spaces:
Running
Running
import threading | |
import asyncio | |
import uuid | |
import gradio as gr | |
import edge_tts | |
from deep_translator import GoogleTranslator | |
from transformers import BlenderbotTokenizer, BlenderbotForConditionalGeneration | |
import torch | |
# ===== TTS PART ===== | |
voice_characters = { | |
"English - US": { | |
"Aria": "en-US-AriaNeural", | |
"Jenny": "en-US-JennyNeural", | |
"Guy": "en-US-GuyNeural", | |
}, | |
"Hindi": { | |
"Swara": "hi-IN-SwaraNeural", | |
"Madhur": "hi-IN-MadhurNeural" | |
} | |
} | |
async def generate_tts(text, voice): | |
if not text.strip(): | |
raise ValueError("Input text is empty") | |
filename = f"output_{uuid.uuid4()}.mp3" | |
communicate = edge_tts.Communicate(text, voice=voice) | |
await communicate.save(filename) | |
return filename | |
def tts_wrapper(text, language, character, translation_direction): | |
try: | |
original_text = text.strip() | |
if not original_text: | |
return "Input text is empty", None | |
if translation_direction == "English to Hindi": | |
text = GoogleTranslator(source='en', target='hi').translate(original_text) | |
elif translation_direction == "Hindi to English": | |
text = GoogleTranslator(source='hi', target='en').translate(original_text) | |
voice = voice_characters.get(language, {}).get(character) | |
if not voice: | |
return f"Voice '{character}' not found for language '{language}'", None | |
filename = asyncio.run(generate_tts(text, voice)) | |
return text, filename | |
except Exception as e: | |
return f"Error: {str(e)}", None | |
# β FIXED: Voice character list updates properly now | |
def get_characters(language): | |
chars = list(voice_characters.get(language, {}).keys()) | |
default_char = chars[0] if chars else None | |
return gr.update(choices=chars, value=default_char) | |
# ===== CHATBOT PART USING BLENDERBOT ===== | |
model_name = "facebook/blenderbot-400M-distill" | |
tokenizer = BlenderbotTokenizer.from_pretrained(model_name) | |
model = BlenderbotForConditionalGeneration.from_pretrained(model_name) | |
device = torch.device("cpu") | |
model.to(device) | |
async def generate_bot_tts(text): | |
voice = voice_characters["English - US"]["Aria"] | |
filename = await generate_tts(text, voice) | |
return filename | |
def chatbot_response(history, user_message): | |
if history is None: | |
history = [] | |
history.append(("User", user_message)) | |
conversation_text = " ".join([msg for _, msg in history]) + " " + user_message | |
inputs = tokenizer([conversation_text], return_tensors="pt").to(device) | |
reply_ids = model.generate(**inputs, max_length=200) | |
response = tokenizer.decode(reply_ids[0], skip_special_tokens=True) | |
history.append(("Bot", response)) | |
chat_str = "" | |
for speaker, msg in history: | |
chat_str += f"{speaker}: {msg}\n" | |
try: | |
audio_path = asyncio.run(generate_bot_tts(response)) | |
except Exception as e: | |
audio_path = None | |
print(f"TTS generation failed: {e}") | |
return history, chat_str, audio_path | |
# ===== GRADIO UI ===== | |
def create_app(): | |
with gr.Blocks() as app: | |
gr.Markdown("## ποΈ Multi-Voice AI TTS with Translation + π€ BlenderBot Chatbot") | |
with gr.Tab("TTS"): | |
text_input = gr.Textbox(label="Enter Text", placeholder="Type something...", lines=4) | |
language_dropdown = gr.Dropdown(choices=list(voice_characters.keys()), value="English - US", label="Language") | |
character_dropdown = gr.Dropdown(choices=list(voice_characters["English - US"].keys()), value="Aria", label="Voice Character") | |
translation_dropdown = gr.Dropdown(choices=["None", "English to Hindi", "Hindi to English"], value="None", label="Translation Direction") | |
tts_button = gr.Button("π Generate Voice") | |
output_text = gr.Textbox(label="Translated Text or Error") | |
output_audio = gr.Audio(label="Generated Voice") | |
# β This updates the character dropdown dynamically based on selected language | |
language_dropdown.change(fn=get_characters, inputs=language_dropdown, outputs=character_dropdown) | |
tts_button.click(fn=tts_wrapper, | |
inputs=[text_input, language_dropdown, character_dropdown, translation_dropdown], | |
outputs=[output_text, output_audio]) | |
with gr.Tab("Chatbot"): | |
chat_history = gr.State([]) | |
user_input = gr.Textbox(label="Enter your message", lines=2, placeholder="Say something...") | |
chat_display = gr.Textbox(label="Chat History", interactive=False, lines=15) | |
audio_output = gr.Audio(label="Bot Voice Reply") | |
send_button = gr.Button("Send") | |
def respond(user_message, history): | |
return chatbot_response(history, user_message) | |
send_button.click(fn=respond, inputs=[user_input, chat_history], outputs=[chat_history, chat_display, audio_output]) | |
user_input.submit(fn=respond, inputs=[user_input, chat_history], outputs=[chat_history, chat_display, audio_output]) | |
return app | |
if __name__ == "__main__": | |
app = create_app() | |
app.launch(share=True) | |