Spaces:
Sleeping
Sleeping
import streamlit as st | |
from streamlit.components.v1 import html | |
import requests | |
import os | |
import base64 | |
import tempfile | |
import io | |
from audiorecorder import audiorecorder | |
import streamlit.components.v1 as components | |
from PIL import Image | |
# Hugging Face API Keys | |
HF_API_KEY = os.getenv("HF_API_KEY") | |
HEADERS = {"Authorization": f"Bearer {HF_API_KEY}"} | |
# Hugging Face API Endpoints | |
HF_SPEECH_TO_TEXT_API = "https://api-inference.huggingface.co/models/openai/whisper-small" | |
HF_CHATBOT_API = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct" | |
HF_TEXT_TO_SPEECH_API = "https://api-inference.huggingface.co/models/facebook/mms-tts-eng" | |
# Avatars and their personalities | |
avatars = { | |
"rat": {"desc": "Clever and resourceful. Loves puzzles and word games.", "voice": "Hello! Let's solve some fun puzzles together!"}, | |
"ox": {"desc": "Steady and dependable. Encourages patience in learning.", "voice": "Consistency is key! Let's learn step by step."}, | |
"tiger": {"desc": "Bold and adventurous. Loves dynamic conversations.", "voice": "Let's jump into an exciting conversation!"}, | |
"rabbit": {"desc": "Gentle and kind. A patient and encouraging teacher.", "voice": "Take your time. Learning should be fun!"}, | |
"dragon": {"desc": "Wise and powerful. Inspires confidence in learning.", "voice": "Believe in yourself! You can do this!"}, | |
"snake": {"desc": "Calm and analytical. Gives insightful explanations.", "voice": "Let's explore the beauty of language together."}, | |
"horse": {"desc": "Energetic and friendly. Encourages active learning.", "voice": "Let's have fun while we learn!"}, | |
"goat": {"desc": "Gentle and artistic. Uses creativity to teach.", "voice": "Imagine and express yourself freely!"}, | |
"monkey": {"desc": "Playful and clever. Loves challenges and fun exercises.", "voice": "I love games! Let's play with words!"}, | |
"rooster": {"desc": "Confident and expressive. Loves discussions.", "voice": "Speak up! Let's share ideas together."}, | |
"dog": {"desc": "Loyal and friendly. Encourages persistence.", "voice": "I'll always be here to help you practice!"}, | |
"pig": {"desc": "Warm and cheerful. Creates a positive learning atmosphere.", "voice": "Learning is fun! Let's enjoy this together!"}, | |
} | |
# Load the Swiper component | |
swiper_code = """ | |
<script type="module"> | |
import React from "react"; | |
import ReactDOM from "react-dom"; | |
import SwiperComponent from "./Swipercomponent.js"; | |
function App() { | |
return <SwiperComponent />; | |
} | |
ReactDOM.render(<App />, document.getElementById("root")); | |
</script> | |
""" | |
st.components.v1.html(swiper_code, height=400) | |
# Function to process speech-to-text | |
def speech_to_text(audio_bytes): | |
files = {"file": ("audio.wav", audio_bytes, "audio/wav")} | |
response = requests.post(HF_SPEECH_TO_TEXT_API, headers=HEADERS, files=files) | |
text = response.json().get("text", "Sorry, could not transcribe audio.") | |
return text | |
# Function to get chatbot response | |
def chatbot_response(user_input): | |
payload = {"inputs": f"You are a friendly AI coach for English learners. Help them practice speaking naturally with supportive feedback.\nUser: {user_input}\nAI:"} | |
response = requests.post(HF_CHATBOT_API, headers=HEADERS, json=payload) | |
ai_reply = response.json().get("generated_text", "I'm here to help! Keep practicing.") | |
return ai_reply | |
# Function for text-to-speech | |
def text_to_speech(text): | |
payload = {"inputs": text} | |
response = requests.post(HF_TEXT_TO_SPEECH_API, headers=HEADERS, json=payload) | |
return response.content | |
# Streamlit UI | |
st.title("ποΈ AI Speaking Pal") | |
st.write("Press the button and chat with your pal!") | |
# Audio Recording Component | |
audio_input = st.audio_input("Let's talk!") | |
if audio_input is not None: | |
# Read audio data | |
audio_bytes = audio_input.read() | |
# Process speech-to-text | |
user_text = speech_to_text(audio_bytes) | |
st.write(f"**You:** {user_text}") | |
# Get AI response | |
ai_reply = chatbot_response(user_text) | |
st.write(f"**AI:** {ai_reply}") | |
# Convert AI response to speech | |
speech_audio = text_to_speech(ai_reply) | |
st.audio(speech_audio, format="audio/wav") | |
# Swiper Carousel Component | |
avatar_list = list(avatars.keys()) | |
selected_index = st.slider("Pick your pal:", 0, len(avatar_list) - 1, 0) | |
selected_avatar = avatar_list[selected_index] | |
avatar_info = avatars[selected_avatar] | |
# Display Avatar Image | |
avatar_img = Image.open(f"images/{selected_avatar}.png") | |
st.image(avatar_img, caption=f"{selected_avatar.capitalize()} - {avatar_info['desc']}", use_column_width=True) | |
# Play avatar's sample voice | |
if st.button("Hear Sample"): | |
audio_bytes = text_to_speech(avatar_info["voice"]) | |
st.audio(io.BytesIO(audio_bytes), format="audio/wav") | |
# Start/Stop Conversation Button | |
if "conversation_active" not in st.session_state: | |
st.session_state.conversation_active = False | |
def toggle_conversation(): | |
st.session_state.conversation_active = not st.session_state.conversation_active | |
st.button("π€ Start/Stop Conversation", on_click=toggle_conversation) | |
# Conversation Text Box | |
show_text = st.checkbox("Show conversation text") | |
if show_text: | |
conversation_box = st.text_area("Conversation:", height=200) | |
# Handle microphone input | |
if st.session_state.conversation_active: | |
audio = audiorecorder("Click to Speak", "Stop recording") | |
if len(audio) > 0: | |
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile: | |
tmpfile.write(audio) | |
user_text = speech_to_text(tmpfile.name) | |
st.write(f"**You:** {user_text}") | |
ai_reply = chatbot_response(user_text) | |
st.write(f"**{selected_avatar.capitalize()}:** {ai_reply}") | |
speech_audio = text_to_speech(ai_reply) | |
st.audio(io.BytesIO(speech_audio), format="audio/wav") | |
st.write("Have fun learning English with your AI pal!") | |