TeluguBOT / templates /index.html
Deepti-AI's picture
Upload 5 files
4187281 verified
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Ortho Buddy — Voice</title>
<style>
html,body { height:100%; margin:0; font-family: "Segoe UI", Roboto, Arial; background: radial-gradient(circle at 50% 10%, #5ca4b0, #062219); color:#bfe6c9; }
.container { width:360px; margin:40px auto; text-align:center; }
h1 { letter-spacing:4px; font-size:36px; color:#2de08b; text-shadow:0 6px 30px rgba(0,0,0,0.7); margin:20px 0; }
.subtitle { color:#d6f3de; margin-bottom:10px; font-size:24px; }
.robot { width:270px; height:270px; background: url('/static/robot.gif') center/contain no-repeat; margin: 40px auto; border-radius:8px; }
.control { margin-top:20px; }
.record-btn { width:50px; height:50px; border-radius:60px; border:none; background:linear-gradient(rgb(248, 245, 248), rgb(248, 245, 248)); box-shadow: 0 10px 30px rgba(0,0,0,0.6); color:white; font-size:18px; cursor:pointer; }
.record-btn.recording { background: linear-gradient(#ff6666, #cc2222); box-shadow: 0 10px 30px rgba(0,0,0,0.7); }
.heading {
text-align: center;
}
.reset-btn {
position: fixed;
top: 20px;
right: 20px;
padding: 10px 20px;
background: linear-gradient(#2de08b, #0a8f5c);
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: bold;
color: #062219;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
z-index: 1000;
transition: background 0.3s ease;
}
.reset-btn:hover {
background: linear-gradient(#1bc47a, #07734f);
}
</style>
<h1 class = "heading">Summit Clinics</h1>
</head>
<body>
<div class="container">
<div class="subtitle"><b>KAMMI</b></div>
<div class="robot" id="robotImg"></div>
<div class="control">
<button id="recBtn" class="record-btn">🎤</button>
</div>
<button id="resetBtn" class="reset-btn">New User</button>
<div class="text-stream" id="textStream"></div>
<!-- Hidden audio player for streamed voice -->
<audio id="player" controls autoplay hidden></audio>
</div>
<script>
let mediaRecorder;
let audioChunks = [];
let recBtn = document.getElementById("recBtn");
let textStream = document.getElementById("textStream");
let recording = false;
let player = document.getElementById("player");
document.getElementById("resetBtn").addEventListener("click", async () => {
try {
const response = await fetch("/reset_chat", {
method: "POST"
});
if (response.ok) {
showTempMessage("Please proceed.", "lightgreen");
} else {
const errorText = await response.text();
showTempMessage("Reset failed: " + errorText, "#ffb3b3");
}
} catch (error) {
showTempMessage("Reset error: " + error.message, "#ffb3b3");
}
});
// Utility function to show a message for 2 seconds
function showTempMessage(msg, color) {
const msgDiv = document.createElement("div");
msgDiv.style.color = color;
msgDiv.textContent = msg;
textStream.appendChild(msgDiv);
setTimeout(() => {
msgDiv.remove();
}, 2000);
}
recBtn.addEventListener("click", async () => {
if (!recording) {
await startRecording();
} else {
stopRecordingAndSend();
}
recording = !recording;
recBtn.textContent = recording ? "Stop" : "🎤";
recBtn.classList.toggle("recording", recording);
});
async function startRecording() {
textStream.innerHTML = ""; // clear previous
audioChunks = [];
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
alert("Your browser does not support microphone capture.");
return;
}
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = e => {
if (e.data && e.data.size > 0) audioChunks.push(e.data);
};
mediaRecorder.start();
}
function stopRecordingAndSend() {
if (!mediaRecorder) return;
mediaRecorder.stop();
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
const form = new FormData();
form.append("file", audioBlob, "recording.webm");
// fetch streaming audio directly
console.log("Sending audio to server...");
const resp = await fetch("/chat_stream", {
method: "POST",
body: form,
});
if (!resp.ok) {
const txt = await resp.text();
textStream.innerHTML += "<div style='color:#ffb3b3'>Server error: " + txt + "</div>";
return;
}
// create an object URL from streaming response
const mediaSource = new MediaSource();
player.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', async () => {
const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
const reader = resp.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
sourceBuffer.appendBuffer(value);
await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }));
}
mediaSource.endOfStream();
});
player.play();
};
}
</script>
</body>
</html>