makhdoomnaeem's picture
Update app.py
b1f9f9d verified
import os
import streamlit as st
import sounddevice as sd
import vosk
from gtts import gTTS
import tempfile
import subprocess
import requests
import zipfile
from groq import Groq
# Initialize Groq client
GROQ_API_KEY = "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" # Replace with your Groq API key
os.environ["GROQ_API_KEY"] = GROQ_API_KEY
client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
# Function to download and extract the Vosk model
def download_and_extract_model(model_url, model_path):
try:
st.write("Downloading Vosk model. Please wait...")
response = requests.get(model_url, stream=True)
if response.status_code != 200:
raise Exception(f"Failed to download model: HTTP {response.status_code}")
with tempfile.TemporaryDirectory() as tmp_dir:
zip_path = os.path.join(tmp_dir, "model.zip")
with open(zip_path, "wb") as file:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
file.write(chunk)
st.write("Extracting Vosk model...")
with zipfile.ZipFile(zip_path, "r") as zip_ref:
zip_ref.extractall(model_path)
st.write("Vosk model setup completed.")
return True
except Exception as e:
st.error(f"Failed to download or extract the Vosk model: {e}")
return False
# Function to validate the Vosk model structure
def validate_model_files(model_path):
required_files = [
"am/final.mdl",
"graph/phones/align_lexicon.int"
]
missing_files = [f for f in required_files if not os.path.exists(os.path.join(model_path, f))]
if missing_files:
st.write(f"Missing required files: {', '.join(missing_files)}")
return False
return True
# Function to ensure the Vosk model is ready
def ensure_vosk_model(model_path, model_url):
for attempt in range(3): # Retry up to 3 times
st.write(f"Validating Vosk model (Attempt {attempt + 1}/3)...")
if validate_model_files(model_path):
return True
st.error("Validation failed. Re-downloading the model...")
if not download_and_extract_model(model_url, model_path):
return False
st.error("Failed to download or validate the Vosk model after multiple attempts.")
return False
# Function to capture audio and process speech
def capture_audio():
try:
model_path = "model"
model_url = "https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip"
# Ensure Vosk model is valid
if not os.path.exists(model_path):
os.makedirs(model_path, exist_ok=True)
if not ensure_vosk_model(model_path, model_url):
return "Error: Unable to download or validate the Vosk model."
# Initialize Vosk model
try:
model = vosk.Model(model_path)
except Exception as e:
return f"Error: Failed to initialize the Vosk model. Details: {e}"
# Record audio
samplerate = 16000
duration = 5 # seconds
st.write("Recording... Speak now!")
audio = sd.rec(int(samplerate * duration), samplerate=samplerate, channels=1, dtype="int16")
sd.wait()
# Speech-to-text using Vosk
rec = vosk.KaldiRecognizer(model, samplerate)
if rec.AcceptWaveform(audio.tobytes()):
result = eval(rec.Result())
return result.get("text", "Unable to recognize speech.")
else:
return "Unable to recognize speech."
except Exception as e:
return f"Error capturing audio: {str(e)}"
# Streamlit interface
st.title("Spoken English Practice")
if st.button("Speak Now"):
user_input = capture_audio()
if user_input.startswith("Error"):
st.error(user_input)
else:
st.write(f"You said: {user_input}")
corrected = client.chat.completions.create(
messages=[{"role": "user", "content": f"Correct the grammar: {user_input}"}],
model="llama-3.3-70b-versatile",
stream=False
).choices[0].message.content.strip()
st.write(f"Corrected: {corrected}")
# Speak the corrected text
speak_text(corrected)
st.write("Ready to practice? Click 'Speak Now'!")