VoiceVision-AI / static /script.js
azizmeer40's picture
Update static/script.js
e48ceed verified
// /* ================================================================
// 1. WELCOME VOICE & INITIALIZATION
// ================================================================ */
// window.onload = () => {
// if (sessionStorage.getItem('isShuttingDown') === 'true') {
// sessionStorage.removeItem('isShuttingDown');
// return;
// }
// // Welcome sound & speech logic
// setTimeout(() => {
// const nameElement = document.getElementById('user-name-data');
// let actualName = (nameElement && nameElement.innerText.trim() !== "") ? nameElement.innerText.trim() : "User";
// const message = `Welcome ${actualName} to the Voice Vision world.`;
// const speech = new SpeechSynthesisUtterance(message);
// speech.rate = 0.9;
// window.speechSynthesis.speak(speech);
// }, 1500);
// };
// /* ================================================================
// 2. DASHBOARD DYNAMIC CONTROLS (POWER ON / OFF)
// ================================================================ */
// let cameraOn = false;
// let isDetecting = false;
// async function handlePowerOn() {
// const video = document.getElementById('video');
// const cameraBox = document.getElementById('cameraBox');
// const powerBtn = document.getElementById('powerBtn');
// try {
// // Muted hona zaroori hai browser policy ke liye
// const stream = await navigator.mediaDevices.getUserMedia({
// video: { width: 640, height: 480 }
// });
// video.srcObject = stream;
// cameraOn = true;
// cameraBox.style.display = 'block';
// powerBtn.style.display = 'none';
// document.getElementById('startDetectBtn').style.display = 'inline-block';
// document.getElementById('powerOffBtn').style.display = 'inline-block';
// window.speechSynthesis.speak(new SpeechSynthesisUtterance("System online."));
// } catch (err) {
// alert("Camera permission denied!");
// console.error(err);
// }
// }
// function handlePowerOff() {
// sessionStorage.setItem('isShuttingDown', 'true');
// window.location.reload();
// }
// /* ================================================================
// 3. DETECTION LOGIC (Cloud Optimized)
// ================================================================ */
// function handleStartDetection() {
// isDetecting = true;
// document.getElementById('modeButtonsGroup').style.display = 'flex';
// document.getElementById('startDetectBtn').style.display = 'none';
// window.speechSynthesis.speak(new SpeechSynthesisUtterance("Detection started."));
// // Detection loop shuru karein
// captureAndSend();
// }
// async function captureAndSend() {
// if (!cameraOn || !isDetecting) return;
// const video = document.getElementById('video');
// const canvas = document.createElement('canvas'); // Arzi canvas frame lene ke liye
// canvas.width = 640;
// canvas.height = 480;
// const ctx = canvas.getContext('2d');
// ctx.drawImage(video, 0, 0, 640, 480);
// const dataUrl = canvas.toDataURL('image/jpeg', 0.6); // Quality kam taake fast transfer ho
// try {
// const response = await fetch('/process_frame', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ image: dataUrl })
// });
// const result = await response.json();
// if (result.detections) {
// // Screen par boxes draw karne wala function
// drawDetections(result.detections);
// // Agar koi object milay to bolein
// if (result.detections.length > 0) {
// const labels = result.detections.map(d => d.label).join(", ");
// // Sirf tab bolein jab naya object aaye (optional)
// // window.speechSynthesis.speak(new SpeechSynthesisUtterance("I see " + labels));
// }
// }
// } catch (error) {
// console.log("Error sending frame:", error);
// }
// // Har 1 second baad agla frame bhejein (Cloud ke liye 1s safe hai)
// if (isDetecting) setTimeout(captureAndSend, 1000);
// }
// // Canvas par Boxes draw karne ka function
// function drawDetections(detections) {
// const canvas = document.getElementById('detectionCanvas');
// if (!canvas) return;
// const ctx = canvas.getContext('2d');
// ctx.clearRect(0, 0, canvas.width, canvas.height); // Purane boxes saaf karein
// detections.forEach(det => {
// const [x1, y1, x2, y2] = det.box;
// // Box style
// ctx.strokeStyle = "#00FF00";
// ctx.lineWidth = 3;
// ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
// // Label style
// ctx.fillStyle = "#00FF00";
// ctx.font = "18px Arial";
// ctx.fillText(`${det.label} (${Math.round(det.confidence * 100)}%)`, x1, y1 > 20 ? y1 - 5 : y1 + 20);
// });
// }
// function logout() {
// window.location.href = "/logout";
// }
/* ================================================================
1. GLOBAL VARIABLES & VOICE SETTINGS
================================================================ */
let cameraOn = false;
let isDetecting = false;
let isProcessing = false;
let lastSpokenTime = 0; // Smoothness ke liye
let lastMessage = "";
function speak(text, force = false) {
const now = Date.now();
// Smoothness: Har 2 second se pehle dobara mat bolein (agar STOP na ho)
if (!force && (now - lastSpokenTime < 2000)) return;
if (text === lastMessage && !force) return;
window.speechSynthesis.cancel();
let msg = new SpeechSynthesisUtterance(text);
msg.rate = 0.9; // Fast se slow kar diya (insani awaz)
msg.pitch = 1.0;
lastSpokenTime = now;
lastMessage = text;
window.speechSynthesis.speak(msg);
}
/* ================================================================
2. POWER OFF & LOGOUT (THE RESET FIX)
================================================================ */
async function stopSystemProperly() {
isDetecting = false;
cameraOn = false;
// Camera Hardware Release
const video = document.getElementById('video');
if (video && video.srcObject) {
video.srcObject.getTracks().forEach(track => track.stop());
video.srcObject = null;
}
window.speechSynthesis.cancel();
}
async function handlePowerOff() {
speak("System shutting down. Please wait.", true);
await stopSystemProperly();
setTimeout(() => {
window.location.replace(window.location.href); // Hard reload
}, 1000);
}
async function logout() {
speak("Logging out. Goodbye.", true);
await stopSystemProperly();
setTimeout(() => {
window.location.replace("/logout"); // Server-side logout
}, 1000);
}
/* ================================================================
3. DETECTION LOGIC (WITH SMOOTHING)
================================================================ */
async function handlePowerOn() {
const video = document.getElementById('video');
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 } });
video.srcObject = stream;
cameraOn = true;
document.getElementById('powerBtn').style.display = 'none';
document.getElementById('startDetectBtn').style.display = 'inline-block';
document.getElementById('powerOffBtn').style.display = 'inline-block';
speak("System Online.", true);
} catch (err) {
alert("Camera error. Please refresh.");
}
}
function handleStartDetection() {
isDetecting = true;
document.getElementById('modeButtonsGroup').style.display = 'flex';
document.getElementById('startDetectBtn').style.display = 'none';
speak("Detection Active.", true);
captureLoop();
}
async function captureLoop() {
if (!cameraOn || !isDetecting) return;
if (isProcessing) {
setTimeout(captureLoop, 200);
return;
}
const video = document.getElementById('video');
const canvas = document.createElement('canvas');
canvas.width = 640; canvas.height = 480;
canvas.getContext('2d').drawImage(video, 0, 0, 640, 480);
isProcessing = true;
try {
const response = await fetch('/process_frame', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ image: canvas.toDataURL('image/jpeg', 0.4) })
});
const result = await response.json();
if (result.detections && isDetecting) {
updateUI(result.detections);
}
} catch (e) { console.log("Loop skip..."); }
isProcessing = false;
// Delay barha diya taake system par bojh na paray
setTimeout(captureLoop, 800);
}
function updateUI(detections) {
const canvas = document.getElementById('detectionCanvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (detections.length > 0) {
let obj = detections[0];
// Visuals
ctx.strokeStyle = "#00FF00"; ctx.lineWidth = 4;
ctx.strokeRect(obj.x, obj.y, obj.w, obj.h);
ctx.fillStyle = "#00FF00"; ctx.font = "bold 20px Arial";
ctx.fillText(obj.label.toUpperCase(), obj.x, obj.y - 10);
// VI Logic
let direction = obj.x + (obj.w/2) < 213 ? "on your left" : (obj.x + (obj.w/2) > 426 ? "on your right" : "in front");
let area = (obj.w * obj.h) / (640*480);
let msg = area > 0.4 ? `STOP! ${obj.label} very close` : `${obj.label} ${direction}`;
speak(msg, area > 0.4); // Force speak if very close
}
}