|
import streamlit as st |
|
import requests |
|
import io |
|
import base64 |
|
|
|
|
|
st.set_page_config(page_title="Sai Vahini AI Assistant", layout="centered") |
|
|
|
|
|
RENDER_API_URL = "https://saivahini.onrender.com/process_audio" |
|
|
|
|
|
st.markdown("<h1 style='text-align: center; color: #ff5733;'>Sai Vahini AI Voice Assistant ποΈ</h1>", unsafe_allow_html=True) |
|
|
|
|
|
audio_recorder_html = """ |
|
<script> |
|
let mediaRecorder; |
|
let audioChunks = []; |
|
|
|
function startRecording() { |
|
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => { |
|
mediaRecorder = new MediaRecorder(stream); |
|
mediaRecorder.start(); |
|
|
|
mediaRecorder.ondataavailable = event => { |
|
audioChunks.push(event.data); |
|
}; |
|
|
|
mediaRecorder.onstop = () => { |
|
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' }); |
|
const reader = new FileReader(); |
|
reader.readAsDataURL(audioBlob); |
|
reader.onloadend = () => { |
|
const base64Audio = reader.result.split(',')[1]; |
|
fetch("/upload_audio", { |
|
method: "POST", |
|
headers: { "Content-Type": "application/json" }, |
|
body: JSON.stringify({ audio: base64Audio }) |
|
}).then(response => response.json()).then(data => { |
|
document.getElementById("audio_url").value = data.audio_url; |
|
}); |
|
}; |
|
}; |
|
}); |
|
} |
|
|
|
function stopRecording() { |
|
mediaRecorder.stop(); |
|
} |
|
</script> |
|
<button onclick="startRecording()">π€ Start Recording</button> |
|
<button onclick="stopRecording()">βΉ Stop Recording</button> |
|
<input type="hidden" id="audio_url"> |
|
""" |
|
|
|
|
|
st.components.v1.html(audio_recorder_html, height=150) |
|
|
|
|
|
if st.button("β
Process Recorded Audio"): |
|
with st.spinner("π Sending audio to AI model..."): |
|
audio_url = st.session_state.get("audio_url", None) |
|
if audio_url: |
|
|
|
audio_data = base64.b64decode(audio_url) |
|
audio_bytes = io.BytesIO(audio_data) |
|
|
|
|
|
response = requests.post(RENDER_API_URL, files={"file": ("audio.wav", audio_bytes, "audio/wav")}) |
|
|
|
|
|
if response.status_code == 200: |
|
result = response.json() |
|
st.success("β
AI Response:") |
|
st.write("π **Transcription:**", result.get("transcription", "No transcription")) |
|
st.write("π€ **Answer:**", result.get("response", "No response found.")) |
|
|
|
|
|
audio_response_url = result.get("audio") |
|
if audio_response_url: |
|
st.write("π **AI-generated voice response:**") |
|
audio_response = requests.get(audio_response_url) |
|
if audio_response.status_code == 200: |
|
st.audio(audio_response.content, format="audio/wav") |
|
else: |
|
st.error(f"β Failed to load AI audio ({audio_response.status_code})") |
|
else: |
|
st.warning("β οΈ No audio response received from API.") |
|
else: |
|
st.error(f"β API Error: {response.status_code} - {response.text}") |
|
else: |
|
st.error("β οΈ No audio recorded. Please record first!") |
|
|