Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

216
LINES

< > BotCompany Repo | #1009555 // Chrome Speech Recognition Page + WebSocket [WORKS]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Libraryless. Click here for Pure Java version (14048L/102K).

!7

sbool autoClose = true;
static int initialDelay = 0;
sbool infoBox, repeatEverything;

static int port;
static O onUtterance; // voidfunc(S)
static L<S> botsToSendUtterancesTo = ll("Voice Actions.", "Show Item Page.");
static L<S> functionsToSendTo = ll();
static L<WebSocket> webSockets = synchroList();
sbool startRecognition;
static java.util.Timer stopper;
sS language = "en-US";
sS myURL;
static JButton btn;
sbool hadAnyWebSockets; // Does Chrome work at all?

p {
  botsToSendUtterancesTo = persistentList("Bots to send utterances to", botsToSendUtterancesTo);
  functionsToSendTo = persistentList("Fuctions to send to", botsToSendUtterancesTo);
  load('language);
  if (isMainProgram())
    infoBox = repeatEverything = true;
  NanoHTTPD.SOCKET_READ_TIMEOUT = 24*3600*1000; // not long enough - TODO: Fix in NanoHTTPD
  
  port = serveHttpWithWebSockets(9999, func(NanoHTTPD.IHTTPSession handshake) {
    WebSocket ws = new WebSocket(handshake) {
      protected void onPong(WebSocketFrame pongFrame) { print("pong"); }
      protected void onMessage(WebSocketFrame messageFrame) {
        cancelTimeout();
        fS s = messageFrame.getTextPayload();
        thread {
          if (repeatEverything) sendOptInNewThread("Mouth.", infoBoxAndReturn(/*switcheroo*/(s)));
          else infoBoxOrPrint("User said: " + s, infoBox);
          pcallF(onUtterance, s);
          for (S bot : cloneList(botsToSendUtterancesTo)) {
            print("Sending to bot " + bot);
            sendOptInNewThread(bot, "User said: *", s);
          }
          for (fS sf : cloneList(functionsToSendTo)) thread {
            makeAndCall(sf, s);
          }
        }
      }
      protected void onClose(WebSocketFrame.CloseCode code, String reason, boolean initiatedByRemote) { webSockets.remove(this); }
      protected void onException(IOException e) { printStackTrace(e); }
    };
    if (startRecognition) {
      startRecognition = false;
      ws.send("start");
    }
    
    // close any other recognizers
    for (WebSocket ws2 : cloneList(webSockets)) {
      pcall { ws2.close(WebSocketFrame.CloseCode.NormalClosure, ""); }
      webSockets.remove(ws2);
    }
    
    hadAnyWebSockets = true;
    
    ret addAndReturn(webSockets, ws);
  });
  myURL = print("http://localhost:" + port + "/popup");
  startChromeApp(myURL);
  makeBot("Chrome Speech.");
  
  showControls(jcenteredline(btn = jbutton("Open Speech Recognizer", r {
    startChromeApp(myURL)
  })));
  awtEvery(btn, 500, r { setEnabled(btn, empty(webSockets)) });
  
  /*thread "Chrome Re-Starter" {
    sleepSeconds(20);
    repeat with sleep 5 {
      if (hadAnyWebSockets && empty(webSockets)) {
        startChromeApp(myURL);
        sleepSeconds(15);
      }
    }
  });*/
}

html {
  if (neq(uri, "/popup"))
    ret hbody("Opening popup..." + hjavascript([[
      window.open('/popup', 'speech_recognizer', 'width=300,height=300,location=no');
      setTimeout(function() { window.close(); }, 10000);
    ]]));

  ret hhtml(hhead(htitle("Speech Recognizer")) + hbody(div(
    h3("Speech Recognizer")
    + loadJQuery()
    + hdiv("Language: " + language, id := 'lang, style := "font-size: 10px")
    + hdiv("Results come here", id := 'results, style := "margin: 10px")
  + hjavascript([[
    var websocket;
    
    function stopRecognition() {
      recognition.stop();
      started = false;
      $("#btn").html("Start recognition");
      document.title = "Speech Recognizer";
    }
    
    function startRecognition() {
      recognition.start();
      started = true;
      $("#btn").html("Stop recognition");
      document.title = "Listening - Speech Recognizer";
    }
    
    function openWebSocket() {
      websocket = new WebSocket("ws://localhost:#PORT#/");
      websocket.onopen = function(event) {
        $("#btn").prop('disabled', false);
      };
    
      websocket.onmessage = function(event) {
        if (event.data == 'start' && !started) startOrStop();
        if (event.data == 'stop' && started) startOrStop();
        if (event.data.substring(0, 9) == 'language ') {
          var l = event.data.substring(9);
          recognition.lang = l;
          $("#lang").html("Language: " + l);
        }
      };
    
      websocket.onclose = function(event) {
        $("#results").html("WebSocket closed");
        if (#AUTOCLOSE#) window.close();
      };
    }
    
    setTimeout(openWebSocket, #INITIALDELAY#);
      
    var recognition = new webkitSpeechRecognition();
    recognition.lang = "#LANGUAGE#";
    
    recognition.onerror = function(event) { 
      $("#results").html("Error: " + event.error);
      stopRecognition();
    }
    
    recognition.onresult = function(event) { 
      var result = event.results[0];
      var transcript = result[0].transcript;
      $("#results").html("Transcript: " + transcript);
      websocket.send(transcript);
      stopRecognition();
    }
    
    recognition.onnomatch = function(event) { 
      $("#results").html("-");
      stopRecognition();
    }
    
    var started = false;
    
    function startOrStop() {
      if (started) stopRecognition(); else {
        stopRecognition(); startRecognition();
      }
    }
    
    window.resizeTo(300, 300);
  ]]).replace("#PORT#", str(port)).replace("#AUTOCLOSE#", autoClose ? "true" : "false").replace("#INITIALDELAY#", str(initialDelay)).replace("#LANGUAGE#", language)
    + tag('button, "Start recognition", onclick := "startOrStop()", type := 'button, id := 'btn, disabled := 'disabled)
    //+ p(ahref("#", "Popup", onClick := "window.open('/', 'speech_recognizer', 'width=300,height=300,location=no'); return false;"));
  , style := "text-align: center"));
}

svoid startRecognition {
  L<WebSocket> l = cloneList(webSockets);
  if (empty(l)) startRecognition = true;
  else {
    //print("Starting recognition." + (l(l) > 1 ? "Weird: Have " + l(l) + " websockets" : ""));
    pcall {
      first(l).send("start");
    }
  }
}

svoid stopRecognition {
  if (startRecognition) startRecognition = false;
  if (nempty(webSockets)) pcall {
    first(webSockets).send("stop");
  }
}

answer {
  if "start recognition timeout *" {
    final int seconds = parseInt($1);
    startRecognition();
    stopper = timerOnce(toMS(seconds), f stopRecognition);
    ret "OK";
  }
  if "start recognition" { startRecognition(); ret "OK"; }
  if "stop recognition" { stopRecognition(); ret "OK"; }
  if "send to bot *" { setAdd(botsToSendUtterancesTo, $1); ret "OK"; }
  if "what bots are you sending to" ret sfu(botsToSendUtterancesTo);
  if "clear send list" { clear(botsToSendUtterancesTo); ret "OK"; }
  
  if "send to function *" { setAdd(functionsToSendTo, $1); ret "OK"; }
  if "what functions are you sending to" ret sfu(functionsToSendTo);
  if "clear functions list" { clear(functionsToSendTo); ret "OK"; }
  if "language *" {
    setAndSave('language, $1);
    pcall { if (nempty(webSockets)) first(webSockets).send("language " + $1); }
    ret "OK";
  }
}

svoid cancelTimeout {
  if (stopper != null) { stopper.cancel(); stopper = null; }
}

Author comment

Began life as a copy of #1009223

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, wtqryiryparv

No comments. add comment

Snippet ID: #1009555
Snippet name: Chrome Speech Recognition Page + WebSocket [WORKS]
Eternal ID of this version: #1009555/107
Text MD5: 5c14fca2dc288b4f79ab88e9d3a515b5
Transpilation MD5: 3f59c755a65030a0c396e89b1298ab2a
Author: stefan
Category: javax
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-10-06 02:43:17
Source code size: 7271 bytes / 216 lines
Pitched / IR pitched: No / No
Views / Downloads: 831 / 2745
Version history: 106 change(s)
Referenced in: #1009602 - Start English Assistant
#1009608 - Starte deutschen Assistenten
#1009816 - Continuous Recognition Module (just logs, German/English, with "bigOn" switch)