Skip to content

Instantly share code, notes, and snippets.

@kmomose
Last active September 26, 2017 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmomose/d43d0733b42ee0d42e7bba896d20d09b to your computer and use it in GitHub Desktop.
Save kmomose/d43d0733b42ee0d42e7bba896d20d09b to your computer and use it in GitHub Desktop.
Watson Speech to Text websocket API

This sample application demonstrates Watson Speech to Text (STT) in websocket mode. Transcript of voice recording can be shown in stream fashion by both standard STT and custom STT (trained by you). It also shows timestamp and Confidence of each sentences.

[{"id":"f75ab2a.2f3815","type":"http in","z":"84a189af.1120f8","name":"","url":"/std","method":"get","swaggerDoc":"","x":86,"y":113.00001525878906,"wires":[["61253d51.bbdf54"]]},{"id":"81e255d8.0c7aa8","type":"http response","z":"84a189af.1120f8","name":"","x":722.0001678466797,"y":111.00001525878906,"wires":[]},{"id":"a3076265.819cf8","type":"http request","z":"84a189af.1120f8","name":"get Custom STT Token","method":"GET","ret":"txt","url":"https://stream.watsonplatform.net/authorization/api/v1/customizations/e161d8f0-0578-11e7-94ad-3b2269260fbc/token?url=https://stream.watsonplatform.net/speech-to-text/api","tls":"","x":289.4999542236328,"y":214.04039001464844,"wires":[["5612f29a.dacfdc"]]},{"id":"aabf7100.ee42c8","type":"debug","z":"84a189af.1120f8","name":"","active":false,"console":"true","complete":"true","x":720.5001068115234,"y":213.1323699951172,"wires":[]},{"id":"61253d51.bbdf54","type":"http request","z":"84a189af.1120f8","name":"get Standard STT Token","method":"GET","ret":"txt","url":"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api","tls":"","x":294.99998474121094,"y":113,"wires":[["d5e7c6e3.1a87a"]]},{"id":"d5e7c6e3.1a87a","type":"template","z":"84a189af.1120f8","name":"Standard Watson STT","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<html>\n<head>\n <script type=\"text/javascript\">\n var token = \"{{payload}}\";\n var model = \"ja-JP_NarrowbandModel\"; // Change to your own model\n var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=' +\n token + '&model=' + model;\n var message = { 'action': 'start',\n 'content-type': 'audio/wav',\n 'continuous': true,\n 'interim_results': true,\n 'inactivity_timeout': 6000,\n 'word_confidence': false,\n 'timestamps': true,\n 'max_alternatives': 0,\n 'keywords': ['imposible', 'unavailable'],\n 'keywords_threshold': 0.8,\n 'speaker_labels': true\n };\n\tvar message2 = {'action': 'stop'};\n\tvar index = 0;\n\tvar ws = new WebSocket(wsURI);\n ws.onopen = function(evt) { onOpen(evt) };\n ws.onmessage = function(evt) { onMessage(evt) };\n ws.onclose = function(evt) { onClose(evt) };\n ws.onerror = function(evt) { onError(evt) };\n\nfunction sendMessage() {\n console.log(\"sendMessae\");\n var file = parent.frame1.document.getElementById('file_input').files[0];\n\tvar reader = new FileReader();\n reader.onload = function () {\n ws.send(reader.result);\n };\n reader.readAsArrayBuffer(file);\n};\n\nfunction onOpen(evt) {\n fileselection();\n console.log(\"onOpen:\"+JSON.stringify(message));\n ws.send(JSON.stringify(message));\n};\n\nfunction onClose(evt) {\n console.log(\"onClose:\"+evt.code+evt.reason);\n ws.close();\n};\n\nfunction onMessage(evt) {\n  var object = JSON.parse(evt.data);\n console.log(\"onMessage:\"+evt.data);\n if ( evt.data.indexOf(\"results\") >= 1) {\n if (object[\"results\"][0][\"final\"] == true) {\n printout(\n object[\"results\"][0][\"alternatives\"][0][\"timestamps\"][0][2],\n object[\"results\"][0][\"alternatives\"][0][\"confidence\"],\n object[\"results\"][0][\"alternatives\"][0][\"transcript\"],\n object[\"result_index\"]\n );\n };\n };\n};\nfunction onError(evt) {\n console.log(\"onError:\"+evt.data);\n};\n\nfunction disconnect() {\n ws.send(JSON.stringify(message2));\n console.log(\"disconnect\");\n ws.close();\n};\n\nfunction printout(time,confidence,text,i){\n\tparent.frame2.document.write(\n\t \"<div style=\\\"text-align:left\\\" >\"\n\t +i\n\t +\" (\"+time+\") [\"\n\t +Math.round(confidence*1000)/10+\"%]\"\n\t +text+\n\t \"</div><p></p>\");\n};\n\nfunction fileselection(){\n parent.frame1.document.open();\n parent.frame1.document.write('<h1>Standard Watson STT Websocket Sample Application</h1>\\n');\n parent.frame1.document.write('<form>\\n');\n parent.frame1.document.write('<input type=\"file\" id=\"file_input\" onchange=\"parent.sendMessage()\">\\n');\n parent.frame1.document.write('<div><button onclick=\"parent.disconnect()\">Disconnect</button></div>\\n');\n parent.frame2.document.close();\n};\n\n</script>\n</head>\n<frameset cols=\"300,*\">\n<frame src=\"\" name=\"frame1\">\n<frame src=\"\" name=\"frame2\">\n</frameset>\n</html>\n","x":529.0000152587891,"y":112,"wires":[["81e255d8.0c7aa8","aabf7100.ee42c8"]]},{"id":"8ca5d2ce.6b7108","type":"http in","z":"84a189af.1120f8","name":"","url":"/custom","method":"get","swaggerDoc":"","x":94.99998474121094,"y":215,"wires":[["a3076265.819cf8"]]},{"id":"2d269014.98709","type":"comment","z":"84a189af.1120f8","name":"Trigger","info":"","x":88.48893737792969,"y":50.040435791015625,"wires":[]},{"id":"787f6f2.e01389","type":"comment","z":"84a189af.1120f8","name":"Transcription","info":"","x":518.4962921142578,"y":47.04779052734375,"wires":[]},{"id":"61b9517d.3c42f","type":"comment","z":"84a189af.1120f8","name":"output","info":"","x":705.4852752685547,"y":48.04779052734375,"wires":[]},{"id":"d1ce740c.b657d8","type":"comment","z":"84a189af.1120f8","name":"Authentication","info":"","x":279.99998474121094,"y":47,"wires":[]},{"id":"5612f29a.dacfdc","type":"template","z":"84a189af.1120f8","name":"Standard Watson STT","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<html>\n<head>\n <script type=\"text/javascript\">\n var token = \"{{payload}}\";\n var customid = \"e161d8f0-0578-11e7-94ad-3b2269260fbc\"; //Change to your own customid\n var model = \"ja-JP_NarrowbandModel\"; //Cange to your own model\n var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=' +\n token + '&customization_id=' + customid + '&model=' + model;\n var message = { 'action': 'start',\n 'content-type': 'audio/wav',\n 'continuous': true,\n 'interim_results': true,\n 'inactivity_timeout': 6000,\n 'word_confidence': false,\n 'timestamps': false,\n 'max_alternatives': 0,\n 'keywords': ['できません', '不可能'], //Change to your own keywords\n 'keywords_threshold': 0.8,\n 'speaker_labels': true\n };\n \n\tvar message2 = {'action': 'stop'};\n\tvar index = 0;\n\tvar ws = new WebSocket(wsURI);\n ws.onopen = function(evt) { onOpen(evt) };\n ws.onmessage = function(evt) { onMessage(evt) };\n ws.onclose = function(evt) { onClose(evt) };\n ws.onerror = function(evt) { onError(evt) };\n\nfunction sendMessage() {\n console.log(\"sendMessae\");\n var file = parent.frame1.document.getElementById('file_input').files[0];\n\tvar reader = new FileReader();\n reader.onload = function () {\n ws.send(reader.result);\n };\n reader.readAsArrayBuffer(file);\n};\n\nfunction onOpen(evt) {\n fileselection();\n console.log(\"onOpen:\"+JSON.stringify(message));\n ws.send(JSON.stringify(message));\n};\n\nfunction onClose(evt) {\n console.log(\"onClose:\"+evt.code+evt.reason);\n ws.close();\n};\n\nfunction onMessage(evt) {\n  var object = JSON.parse(evt.data);\n console.log(\"onMessage:\"+evt.data);\n if ( evt.data.indexOf(\"results\") >= 1) {\n if (object[\"results\"][0][\"final\"] == true) {\n printout(\n object[\"results\"][0][\"alternatives\"][0][\"timestamps\"][0][2],\n object[\"results\"][0][\"alternatives\"][0][\"confidence\"],\n object[\"results\"][0][\"alternatives\"][0][\"transcript\"],\n object[\"result_index\"]\n );\n };\n };\n};\nfunction onError(evt) {\n console.log(\"onError:\"+evt.data);\n};\n\nfunction disconnect() {\n ws.send(JSON.stringify(message2));\n console.log(\"disconnect\");\n ws.close();\n};\n\nfunction printout(time,confidence,text,i){\n\tparent.frame2.document.write(\n\t \"<div style=\\\"text-align:left\\\" >\"\n\t +i\n\t +\" (\"+time+\") [\"\n\t +Math.round(confidence*1000)/10+\"%]\"\n\t +text+\n\t \"</div><p></p>\");\n};\n\nfunction fileselection(){\n parent.frame1.document.open();\n parent.frame1.document.write('<h1>Custom Watson STT Websocket Sample Application</h1>\\n');\n parent.frame1.document.write('<form>\\n');\n parent.frame1.document.write('<input type=\"file\" id=\"file_input\" onchange=\"parent.sendMessage()\">\\n');\n parent.frame1.document.write('<div><button onclick=\"parent.disconnect()\">Disconnect</button></div>\\n');\n parent.frame2.document.close();\n};\n\n</script>\n</head>\n<frameset cols=\"300,*\">\n<frame src=\"\" name=\"frame1\">\n<frame src=\"\" name=\"frame2\">\n</frameset>\n</html>\n","x":532,"y":214,"wires":[["81e255d8.0c7aa8","aabf7100.ee42c8"]]}]
@imv7
Copy link

imv7 commented Jul 25, 2017

Hello, thank you for sharing.
I could not find how to set up the Watson conversation in the json you provided.
What is the next step after to paste the flow in the node red? To create the Watson speech to text API ? where do I set up the API Token? thanks

@imv7
Copy link

imv7 commented Jul 25, 2017

I know where the credentials of the services are. But I could not find these info in my bluemix. Can you help me with walkthrough?

<script type="text/javascript">
var token = "{{payload}}";
var model = "ja-JP_NarrowbandModel";  // Change to your own model
var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=' +
            token + '&model=' + model;

@kmomose
Copy link
Author

kmomose commented Sep 26, 2017

Hello,
You can find your Watson STT service credential (userid and password) at the "service credentials" tab in your bluemix dashboard. Copy&Paste it to the username and password attributes in "get standard STT token" node on your Node-Red Flow. The username and password attributes can be shown by opt-in "user basic authentication" radio button in the STT token node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment