Team Ai
Apppublic

Piyush23890/Sign_Language_Decoder

sourceHugging Facemitupdated 7mo agoView on Hugging Face
0likes
script.js176 linesDownload Raw Back to static
1/**2 * SignBridge — script.js3 * ======================4 * Handles all client-side logic:5 *   - WebSocket connection to Flask-SocketIO backend6 *   - Real-time sign + sentence display updates7 *   - Keyboard shortcut bindings8 *   - Text-to-Speech (Web Speech API)9 *   - Speech-to-Text  (Web Speech API)10 *   - Language switching (→ emits to backend for translation)11 *   - Clipboard copy12 */13 14"use strict";15 16// ── WebSocket ────────────────────────────────────────────────────────────────────17const socket = io();18 19socket.on("connect", () => {20  console.log("[SignBridge] WebSocket connected — id:", socket.id);21});22 23socket.on("disconnect", () => {24  console.warn("[SignBridge] WebSocket disconnected.");25});26 27// ── DOM refs ─────────────────────────────────────────────────────────────────────28const signEl     = document.getElementById("current-sign");29const sentenceEl = document.getElementById("sentence-display");30const speechEl   = document.getElementById("speech-display");31const micBtn     = document.getElementById("mic-btn");32const langSel    = document.getElementById("lang-select");33 34// ── Real-time update from backend ─────────────────────────────────────────────────35socket.on("update_status", ({ sign, sentence }) => {36  // Sign badge37  if (sign) {38    signEl.textContent = sign;39    signEl.style.color = "#10b981";   // accent green when active40  } else {41    signEl.textContent = "Listening…";42    signEl.style.color = "#94a3b8";   // muted when idle43  }44 45  // Sentence46  sentenceEl.textContent = sentence || "";47});48 49// ── Command helpers ───────────────────────────────────────────────────────────────50function sendCommand(action) {51  socket.emit("command", { action });52}53 54// ── Language selector ─────────────────────────────────────────────────────────────55function changeLanguage() {56  const lang = langSel.value;57  socket.emit("set_language", { language: lang });58}59 60// ── Text-to-Speech ────────────────────────────────────────────────────────────────61function speakText() {62  const text = sentenceEl.textContent.trim();63  if (!text || !window.speechSynthesis) return;64 65  const lang = langSel.value === "hi" ? "hi-IN" : "en-US";66  const utt  = new SpeechSynthesisUtterance(text);67  utt.lang   = lang;68  utt.rate   = 0.95;69  window.speechSynthesis.cancel();   // cancel any ongoing speech first70  window.speechSynthesis.speak(utt);71}72 73// ── Speech-to-Text ────────────────────────────────────────────────────────────────74let recognition = null;75let isListening = false;76 77(function initSTT() {78  const SR = window.SpeechRecognition || window.webkitSpeechRecognition;79  if (!SR) {80    if (speechEl)  speechEl.textContent = "STT not supported in this browser.";81    if (micBtn)    micBtn.disabled = true;82    return;83  }84 85  recognition = new SR();86  recognition.continuous     = false;87  recognition.interimResults = false;88  recognition.lang           = "en-US";89 90  recognition.onstart = () => {91    isListening           = true;92    micBtn.textContent    = "🔴 Listening…";93    micBtn.classList.add("active");94    speechEl.textContent  = "…";95  };96 97  recognition.onresult = (event) => {98    const transcript = event.results[0][0].transcript;99    const lang       = langSel.value;100 101    if (lang === "hi") {102      // Ask backend to translate103      socket.emit("translate_now", { text: transcript, target: "hi" });104    } else {105      speechEl.textContent = transcript;106    }107  };108 109  // Receive translation from backend110  socket.on("stt_translation", ({ translated }) => {111    if (speechEl) speechEl.textContent = translated;112  });113 114  recognition.onerror = (event) => {115    stopListening();116    const errorMap = {117      "network"    : "Network error — internet required for STT.",118      "not-allowed": "Microphone access denied.",119      "no-speech"  : "No speech detected. Try again.",120    };121    speechEl.textContent = errorMap[event.error] ?? `Error: ${event.error}`;122  };123 124  recognition.onend = stopListening;125})();126 127function toggleSpeech() {128  if (!recognition) return;129  isListening ? recognition.stop() : recognition.start();130}131 132function stopListening() {133  isListening           = false;134  micBtn.textContent    = "🎤 Tap to Speak";135  micBtn.classList.remove("active");136}137 138// ── Clipboard helpers ─────────────────────────────────────────────────────────────139function _copyAndFlash(text, btn) {140  if (!text) return;141  navigator.clipboard.writeText(text).then(() => {142    const orig = btn.textContent;143    btn.textContent = "✅";144    setTimeout(() => { btn.textContent = orig; }, 2000);145  });146}147 148function copyToClipboard() {149  const btn = document.querySelector(".sentence-card .icon-btn");150  _copyAndFlash(sentenceEl.textContent, btn);151}152 153function copySpeechToClipboard() {154  const btn = document.querySelector(".speech-card .icon-btn");155  _copyAndFlash(speechEl.textContent, btn);156}157 158// ── Keyboard shortcuts ────────────────────────────────────────────────────────────159document.addEventListener("keydown", (e) => {160  // Don't fire when typing in an input161  if (document.activeElement.tagName === "INPUT") return;162 163  switch (e.key) {164    case "Enter":     speakText();             break;165    case "Backspace": sendCommand("backspace"); e.preventDefault(); break;166    case "c":167    case "C":         sendCommand("clear");    break;168  }169});170 171// ── Init ──────────────────────────────────────────────────────────────────────────172// Sync language on page load173window.addEventListener("DOMContentLoaded", () => {174  changeLanguage();175});176