tai / voice_handler.py
shamimjony1000's picture
Update voice_handler.py
42892f4 verified
raw
history blame
4.38 kB
import speech_recognition as sr
import streamlit as st
from typing import Optional, Tuple
import platform
import sys
class VoiceHandler:
def __init__(self):
self.recognizer = sr.Recognizer()
self.recognizer.energy_threshold = 4000
self.recognizer.dynamic_energy_threshold = True
self.recognizer.pause_threshold = 0.8
self.permission_granted = False
# Initialize microphone without device selection
self.mic = sr.Microphone()
def check_microphone_access(self) -> Tuple[bool, str]:
"""Check if microphone is accessible and return status with message"""
try:
with self.mic as source:
# Quick test to verify microphone access
self.recognizer.adjust_for_ambient_noise(source, duration=0.1)
return True, "Microphone access granted"
except (OSError, AttributeError) as e:
return False, """
Could not access microphone. Please:
1. Click the lock icon in your browser's address bar
2. Allow microphone access for this site
3. Refresh the page after granting access
4. Ensure your microphone is properly connected
"""
except sr.RequestError as e:
return False, f"Speech recognition service error: {str(e)}"
except Exception as e:
return False, f"Unexpected error: {str(e)}"
def request_permissions(self) -> Tuple[bool, str]:
"""Request microphone permissions from the browser"""
success, message = self.check_microphone_access()
if success:
self.permission_granted = True
return True, "Microphone access granted successfully"
return False, message
def listen_for_voice(self, language: str = "mixed") -> str:
"""
Listen for voice input in specified language.
language can be:
- "ar-SA" for Arabic
- "en-US" for English
- "mixed" for both Arabic and English
"""
if not self.permission_granted:
success, message = self.request_permissions()
if not success:
st.error(message)
st.markdown("""
### 🎀 Troubleshooting Steps:
1. Check browser compatibility (Chrome/Firefox/Edge recommended)
2. Verify microphone connection
3. Check system sound settings
4. Try a different microphone if available
5. Restart browser if needed
""")
return message
try:
with self.mic as source:
st.info("Adjusting for ambient noise... Please wait.")
self.recognizer.adjust_for_ambient_noise(source, duration=1)
st.info("🎀 Listening... Speak now!")
audio = self.recognizer.listen(source, timeout=5, phrase_time_limit=10)
st.info("Processing speech...")
return self._process_audio(audio, language)
except sr.RequestError as e:
error_msg = f"Could not request results from speech service: {str(e)}"
st.error(error_msg)
return error_msg
except sr.UnknownValueError:
error_msg = "Could not understand audio. Please speak clearly and try again."
st.warning(error_msg)
return error_msg
except sr.WaitTimeoutError:
error_msg = "Listening timed out. Please try again."
st.warning(error_msg)
return error_msg
except Exception as e:
error_msg = f"Error: {str(e)}"
st.error(error_msg)
return error_msg
def _process_audio(self, audio, language: str) -> str:
"""Process audio input and convert to text"""
if language in ["ar-SA", "mixed"]:
try:
return self.recognizer.recognize_google(audio, language="ar-SA")
except sr.UnknownValueError:
if language == "mixed":
return self.recognizer.recognize_google(audio, language="en-US")
raise
return self.recognizer.recognize_google(audio, language="en-US")