Spaces:
Sleeping
Sleeping
Deepak Roshan commited on
Commit Β·
549f96b
1
Parent(s): 38af066
fix: upgrade browser capture to 640x480, server encode to 85, and implement client-side TTS
Browse files- isl_detection.py +1 -1
- templates/dashboard.html +17 -8
isl_detection.py
CHANGED
|
@@ -842,7 +842,7 @@ def core_processing_engine(shared_state, shm_name=None, frame_lock_val=None, fra
|
|
| 842 |
# Send full 640Γ480 frame β browser displays at native resolution.
|
| 843 |
# Skeleton/overlay removed so JPEG compresses cleanly at quality 75.
|
| 844 |
_, buffer_img = cv2.imencode(
|
| 845 |
-
".jpg", frame, [cv2.IMWRITE_JPEG_QUALITY,
|
| 846 |
frame_base64 = base64.b64encode(buffer_img.tobytes()).decode("utf-8")
|
| 847 |
|
| 848 |
# ββ State packet βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 842 |
# Send full 640Γ480 frame β browser displays at native resolution.
|
| 843 |
# Skeleton/overlay removed so JPEG compresses cleanly at quality 75.
|
| 844 |
_, buffer_img = cv2.imencode(
|
| 845 |
+
".jpg", frame, [cv2.IMWRITE_JPEG_QUALITY, 85])
|
| 846 |
frame_base64 = base64.b64encode(buffer_img.tobytes()).decode("utf-8")
|
| 847 |
|
| 848 |
# ββ State packet βββββββββββββββββββββββββββββββββββββββββββββββ
|
templates/dashboard.html
CHANGED
|
@@ -959,7 +959,7 @@
|
|
| 959 |
}
|
| 960 |
try {
|
| 961 |
cameraStream = await navigator.mediaDevices.getUserMedia({
|
| 962 |
-
video: { width: { ideal:
|
| 963 |
audio: false
|
| 964 |
});
|
| 965 |
videoElement = document.createElement('video');
|
|
@@ -970,21 +970,21 @@
|
|
| 970 |
videoElement.style.position = 'absolute';
|
| 971 |
videoElement.style.top = '-10000px';
|
| 972 |
videoElement.style.left = '-10000px';
|
| 973 |
-
videoElement.style.width = '
|
| 974 |
-
videoElement.style.height = '
|
| 975 |
videoElement.style.pointerEvents = 'none';
|
| 976 |
document.body.appendChild(videoElement);
|
| 977 |
|
| 978 |
videoElement.addEventListener('loadeddata', () => {
|
| 979 |
-
captureCanvas.width =
|
| 980 |
-
captureCanvas.height =
|
| 981 |
if (!window.cameraInterval) {
|
| 982 |
window.cameraInterval = setInterval(() => {
|
| 983 |
// Skip if a frame is still being processed by server
|
| 984 |
if (_frameInFlight) return;
|
| 985 |
if (document.visibilityState === 'visible' && socket && socket.connected) {
|
| 986 |
-
captureCtx.drawImage(videoElement, 0, 0,
|
| 987 |
-
const frame = captureCanvas.toDataURL('image/jpeg', 0.
|
| 988 |
_frameInFlight = true;
|
| 989 |
socket.emit('browser_frame', { frame: frame.split(',')[1] });
|
| 990 |
// Auto-release lock after 600ms even if no ack received
|
|
@@ -1160,7 +1160,16 @@
|
|
| 1160 |
const sentence = document.getElementById('cur-sentence').textContent.trim();
|
| 1161 |
const word = document.getElementById('cur-word').textContent.trim();
|
| 1162 |
const text = sentence || (word !== 'β' ? word : '');
|
| 1163 |
-
if (text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1164 |
} else {
|
| 1165 |
if (socket) socket.emit('command', { action });
|
| 1166 |
}
|
|
|
|
| 959 |
}
|
| 960 |
try {
|
| 961 |
cameraStream = await navigator.mediaDevices.getUserMedia({
|
| 962 |
+
video: { width: { ideal: 640 }, height: { ideal: 480 }, facingMode: 'user' },
|
| 963 |
audio: false
|
| 964 |
});
|
| 965 |
videoElement = document.createElement('video');
|
|
|
|
| 970 |
videoElement.style.position = 'absolute';
|
| 971 |
videoElement.style.top = '-10000px';
|
| 972 |
videoElement.style.left = '-10000px';
|
| 973 |
+
videoElement.style.width = '640px';
|
| 974 |
+
videoElement.style.height = '480px';
|
| 975 |
videoElement.style.pointerEvents = 'none';
|
| 976 |
document.body.appendChild(videoElement);
|
| 977 |
|
| 978 |
videoElement.addEventListener('loadeddata', () => {
|
| 979 |
+
captureCanvas.width = 640;
|
| 980 |
+
captureCanvas.height = 480;
|
| 981 |
if (!window.cameraInterval) {
|
| 982 |
window.cameraInterval = setInterval(() => {
|
| 983 |
// Skip if a frame is still being processed by server
|
| 984 |
if (_frameInFlight) return;
|
| 985 |
if (document.visibilityState === 'visible' && socket && socket.connected) {
|
| 986 |
+
captureCtx.drawImage(videoElement, 0, 0, 640, 480);
|
| 987 |
+
const frame = captureCanvas.toDataURL('image/jpeg', 0.7);
|
| 988 |
_frameInFlight = true;
|
| 989 |
socket.emit('browser_frame', { frame: frame.split(',')[1] });
|
| 990 |
// Auto-release lock after 600ms even if no ack received
|
|
|
|
| 1160 |
const sentence = document.getElementById('cur-sentence').textContent.trim();
|
| 1161 |
const word = document.getElementById('cur-word').textContent.trim();
|
| 1162 |
const text = sentence || (word !== 'β' ? word : '');
|
| 1163 |
+
if (text) {
|
| 1164 |
+
// Client-side Web Speech API Synthesis
|
| 1165 |
+
if ('speechSynthesis' in window) {
|
| 1166 |
+
window.speechSynthesis.cancel(); // Stop any currently speaking voice
|
| 1167 |
+
const utterance = new SpeechSynthesisUtterance(text);
|
| 1168 |
+
utterance.lang = 'en-US';
|
| 1169 |
+
window.speechSynthesis.speak(utterance);
|
| 1170 |
+
}
|
| 1171 |
+
if (socket) socket.emit('command', { action: 'speak', text });
|
| 1172 |
+
}
|
| 1173 |
} else {
|
| 1174 |
if (socket) socket.emit('command', { action });
|
| 1175 |
}
|