File size: 9,879 Bytes
64e19fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e35ef8
e48ceed
7e35ef8
 
 
64e19fc
e48ceed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e35ef8
64e19fc
e48ceed
64e19fc
e48ceed
 
0024c63
e48ceed
 
0024c63
 
e48ceed
0024c63
 
 
 
 
e48ceed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e35ef8
 
 
e48ceed
7e35ef8
 
e48ceed
7e35ef8
 
e48ceed
7e35ef8
e48ceed
7e35ef8
 
 
 
 
 
 
e48ceed
 
7e35ef8
 
e48ceed
0024c63
 
e48ceed
0024c63
 
7e35ef8
 
e48ceed
 
 
64e19fc
 
7e35ef8
 
 
 
e48ceed
7e35ef8
 
0024c63
e48ceed
7e35ef8
e48ceed
 
 
 
 
7e35ef8
 
e48ceed
7e35ef8
 
64e19fc
7e35ef8
e48ceed
 
 
 
 
 
 
 
 
 
 
 
 
64e19fc
4b943a0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
// /* ================================================================ 
//    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
    }
}