File size: 5,188 Bytes
3a0832b
5188c65
 
3a0832b
 
5188c65
 
3a0832b
 
 
 
 
 
5188c65
3a0832b
 
 
5188c65
 
3a0832b
 
5188c65
 
 
 
 
 
 
 
 
 
 
3a0832b
5188c65
 
 
 
 
3a0832b
 
 
 
5188c65
3a0832b
 
 
5188c65
 
 
 
 
 
 
0da3599
3a0832b
 
 
0da3599
3a0832b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0da3599
3a0832b
 
 
 
 
 
 
 
 
 
0da3599
3a0832b
0da3599
3a0832b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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)