Spaces:
Sleeping
Sleeping
| /** | |
| * PROJECT: VOICE VISION - Cloud Optimized Handler | |
| */ | |
| let isProcessing = false; | |
| let lastSpokenMessage = ""; | |
| let speechCounter = 0; | |
| async function sendFrameToBackend() { | |
| if (isProcessing || !cameraOn) return; | |
| const video = document.getElementById('video'); | |
| const canvas = document.createElement('canvas'); | |
| canvas.width = 640; | |
| canvas.height = 480; | |
| const ctx = canvas.getContext('2d'); | |
| ctx.drawImage(video, 0, 0, 640, 480); | |
| // Quality 0.3 speed ke liye behtar hai | |
| const dataUrl = canvas.toDataURL('image/jpeg', 0.3); | |
| isProcessing = true; | |
| 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) { | |
| drawVisuals(result.detections); | |
| processVIOutput(result.detections); | |
| } | |
| } catch (err) { | |
| console.error("Link Error:", err); | |
| } finally { | |
| isProcessing = false; | |
| // 200ms ka gap Hugging Face CPU ke liye ideal hai | |
| setTimeout(sendFrameToBackend, 200); | |
| } | |
| } | |
| function drawVisuals(detections) { | |
| const canvas = document.getElementById('detectionCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| // --- DEMO KE LIYE SECTORS DRAW KARNA --- | |
| ctx.strokeStyle = "rgba(255, 255, 255, 0.2)"; | |
| ctx.setLineDash([5, 5]); | |
| ctx.beginPath(); | |
| ctx.moveTo(213, 0); ctx.lineTo(213, 480); // Left line | |
| ctx.moveTo(426, 0); ctx.lineTo(426, 480); // Right line | |
| ctx.stroke(); | |
| ctx.setLineDash([]); | |
| detections.forEach((obj, index) => { | |
| // Sirf top object ko highlight karein (Reality-based) | |
| ctx.strokeStyle = index === 0 ? "#00FF00" : "#ffcc00"; | |
| ctx.lineWidth = index === 0 ? 4 : 2; | |
| ctx.strokeRect(obj.x, obj.y, obj.w, obj.h); | |
| ctx.fillStyle = index === 0 ? "#00FF00" : "#ffcc00"; | |
| ctx.font = "bold 18px Arial"; | |
| ctx.fillText(`${obj.label}`, obj.x, obj.y - 10); | |
| }); | |
| } | |
| function processVIOutput(detections) { | |
| if (detections.length === 0) return; | |
| // Sabse bada object (Sabat se kareeb) | |
| let primary = detections[0]; | |
| let centerX = primary.x + (primary.w / 2); | |
| let areaRatio = (primary.w * primary.h) / (640 * 480); | |
| // 1. Direction Logic | |
| let direction = "in front of you"; | |
| if (centerX < 213) direction = "on your left"; | |
| else if (centerX > 426) direction = "on your right"; | |
| // 2. Proximity Logic | |
| let alert = ""; | |
| if (areaRatio > 0.45) alert = "STOP! "; | |
| else if (areaRatio > 0.2) alert = "Careful, "; | |
| let message = `${alert}${primary.label} ${direction}`; | |
| // Status update on screen | |
| document.getElementById('aiStatus').innerText = `Target: ${message}`; | |
| // 3. Smart Voice Filter (Har waqt bolna band) | |
| speechCounter++; | |
| if (message !== lastSpokenMessage || speechCounter > 15) { | |
| speak(message); | |
| lastSpokenMessage = message; | |
| speechCounter = 0; | |
| } | |
| } | |
| function speak(text) { | |
| window.speechSynthesis.cancel(); | |
| let utterance = new SpeechSynthesisUtterance(text); | |
| utterance.rate = 1.3; | |
| utterance.pitch = 1.0; | |
| window.speechSynthesis.speak(utterance); | |
| } |