Watson Voices demo

watson-voice-demo

Simple looping Web page allowing text entry, and selection of available voices from Watson Text to Speech service in (Bluemix)[http://bluemix.net)

this is built from @jthomas text to speech flow

1 Launch the /audio link in a sound-capable browser - Chrome seems to work most reliably. Note: non-secure websocket, so use http:// rather than https://

2 Launch the /speak link to see text entry and voice selection dialog

JSON formatted by very handy validation site JSONlint - great when your clipboard import doesn't quite work

[{
	"id": "d50f5985.b98728",
	"type": "inject",
	"z": "47f6f19a.6e5908",
	"name": "",
	"topic": "",
	"payload": "just testing?",
	"payloadType": "str",
	"repeat": "",
	"crontab": "",
	"once": false,
	"x": 110,
	"y": 160,
	"wires": [
		["27671252.b78196"]
	]
}, {
	"id": "990aa0e9.8206b8",
	"type": "change",
	"z": "47f6f19a.6e5908",
	"name": "",
	"rules": [{
		"t": "set",
		"p": "voice",
		"pt": "msg",
		"to": "payload.voice",
		"tot": "msg"
	}, {
		"t": "set",
		"p": "payload",
		"pt": "msg",
		"to": "payload.text",
		"tot": "msg"
	}],
	"action": "",
	"property": "",
	"from": "",
	"to": "",
	"reg": false,
	"x": 300,
	"y": 160,
	"wires": [
		["5fefe1c7.2dfb48", "27671252.b78196"]
	]
}, {
	"id": "5fefe1c7.2dfb48",
	"type": "debug",
	"z": "47f6f19a.6e5908",
	"name": "",
	"active": true,
	"console": "false",
	"complete": "voice",
	"x": 540,
	"y": 180,
	"wires": []
}, {
	"id": "27671252.b78196",
	"type": "delay",
	"z": "47f6f19a.6e5908",
	"name": "",
	"pauseType": "rate",
	"timeout": "5",
	"timeoutUnits": "seconds",
	"rate": "10",
	"nbRateUnits": "1",
	"rateUnits": "minute",
	"randomFirst": "1",
	"randomLast": "5",
	"randomUnits": "seconds",
	"drop": false,
	"x": 160,
	"y": 280,
	"wires": [
		["dd44c043.9e066", "d280e250.3fdf98"]
	]
}, {
	"id": "1b37cfd0.ee4738",
	"type": "change",
	"z": "47f6f19a.6e5908",
	"name": "",
	"rules": [{
		"t": "set",
		"p": "payload",
		"pt": "msg",
		"to": "speech",
		"tot": "msg"
	}],
	"action": "",
	"property": "",
	"from": "",
	"to": "",
	"reg": false,
	"x": 340,
	"y": 440,
	"wires": [
		["ce713914.1d7e2", "98f1d62d.d6e228"]
	]
}, {
	"id": "ce713914.1d7e2",
	"type": "websocket out",
	"z": "47f6f19a.6e5908",
	"name": "",
	"server": "b8e85fa3.1ec4a",
	"client": "",
	"x": 580,
	"y": 380,
	"wires": []
}, {
	"id": "98f1d62d.d6e228",
	"type": "debug",
	"z": "47f6f19a.6e5908",
	"name": "",
	"active": true,
	"console": "false",
	"complete": "false",
	"x": 568,
	"y": 448.3999938964844,
	"wires": []
}, {
	"id": "398047.28d517ba",
	"type": "http response",
	"z": "47f6f19a.6e5908",
	"name": "",
	"x": 570,
	"y": 500,
	"wires": []
}, {
	"id": "52118484.6cf59c",
	"type": "template",
	"z": "47f6f19a.6e5908",
	"name": "Watson Speaks",
	"field": "",
	"fieldType": "msg",
	"syntax": "mustache",
	"template": "<!DOCTYPE html>\n<html>\n<head>\n  <title>IBM Watson - Text To Speech</title>\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></script>\n  \n  <script type=\"text/javascript\">\n    var socketaddy = \"ws://\" + window.location.host + \"/ws/audio\";\n\n    $(document).ready(function(){\n      var output = document.getElementById('output')\n      $('#output').on('playing', function () {\n          $('#text').text('Audio ...')\n          \n      });\n      $('#output').on('ended', function () {\n          $('#text').text('Waiting ...')\n          \n      });\n      sock = new WebSocket(socketaddy);\n      sock.onopen = function(){\n          $('#text').text('Waiting ...');\n          console.log(\"Connected websocket\");\n      };\n      sock.onerror = function(){ \n          console.log(\"Websocket error\"); \n      };\n      sock.onclose = function () {\n          $('#text').text('Not connected. Refresh the page?')\n      }\n      sock.onmessage = function(evt){\n        console.log(\"Websocket message\", evt); \n        output.src = window.URL.createObjectURL(evt.data);\n        output.play();\n      };\n    });\n  </script>\n  \n</head>\n<body style=\"font-size: 56px; font-family: helvetica; text-align: center; margin-top: 100px;\">\n  <div id=\"text\">Connecting...</div>\n  <audio id=\"output\"></audio>\n</body>\n</html>",
	"x": 340,
	"y": 500,
	"wires": [
		["398047.28d517ba"]
	]
}, {
	"id": "ac50e1cb.93c4a",
	"type": "http in",
	"z": "47f6f19a.6e5908",
	"name": "",
	"url": "/audio",
	"method": "get",
	"swaggerDoc": "",
	"x": 120,
	"y": 500,
	"wires": [
		["52118484.6cf59c"]
	]
}, {
	"id": "c8571453.cac178",
	"type": "http in",
	"z": "47f6f19a.6e5908",
	"name": "",
	"url": "/speak",
	"method": "get",
	"swaggerDoc": "",
	"x": 110,
	"y": 60,
	"wires": [
		["19c74bb3.00a1fc"]
	]
}, {
	"id": "9f4d21a.42f42e",
	"type": "http in",
	"z": "47f6f19a.6e5908",
	"name": "",
	"url": "/speak",
	"method": "post",
	"swaggerDoc": "",
	"x": 110,
	"y": 100,
	"wires": [
		["19c74bb3.00a1fc", "990aa0e9.8206b8", "2eb56d3e.77c982"]
	]
}, {
	"id": "19c74bb3.00a1fc",
	"type": "template",
	"z": "47f6f19a.6e5908",
	"name": "",
	"field": "payload",
	"fieldType": "msg",
	"format": "handlebars",
	"syntax": "mustache",
	"template": "<html>\n    <head>\n        \n    </head>\n    <body>\n        <h1>Voice and text entry</h1>\n        <form action=speak method=post>\n    <select name=\"voice\">\n    <option selected=\"true\" value=\"en-US_MichaelVoice\">American English (en-US): Michael (male, expressive, transformable)</option>\n    <option value=\"de-DE_BirgitVoice\">German (de-DE): Birgit (female)</option>\n    <option value=\"de-DE_DieterVoice\">German (de-DE): Dieter (male)</option>\n    <option value=\"en-GB_KateVoice\">British English (en-GB): Kate (female)</option>\n    <option value=\"en-US_AllisonVoice\">American English (en-US): Allison (female, expressive, transformable)</option>\n    <option value=\"en-US_LisaVoice\">American English (en-US): Lisa (female, transformable)</option>\n    <option value=\"es-ES_EnriqueVoice\">Castilian Spanish (es-ES): Enrique (male)</option>\n    <option value=\"es-ES_LauraVoice\">Castilian Spanish (es-ES): Laura (female)</option>\n    <option value=\"es-LA_SofiaVoice\">Latin American Spanish (es-LA): Sofia (female)</option>\n    <option value=\"es-US_SofiaVoice\">North American Spanish (es-US): Sofia (female)</option>\n    <option value=\"fr-FR_ReneeVoice\">French (fr-FR): Renee (female)</option>\n    <option value=\"it-IT_FrancescaVoice\">Italian (it-IT): Francesca (female)</option>\n    <option value=\"ja-JP_EmiVoice\">Japanese (ja-JP): Emi (female)</option>\n    <option value=\"pt-BR_IsabelaVoice\">Brazilian Portuguese (pt-BR): Isabela (female)</option>\n        </select>\n        <p>        \n        <input name=text type=text maxlength=500 length=100></input>\n        <p>\n        <input name=go type=submit>Say it</input>\n            \n        </form>\n    </body>\n</html>",
	"x": 310,
	"y": 100,
	"wires": [
		["bc39c992.daa77"]
	]
}, {
	"id": "bc39c992.daa77",
	"type": "http response",
	"z": "47f6f19a.6e5908",
	"name": "",
	"x": 490,
	"y": 100,
	"wires": []
}, {
	"id": "d280e250.3fdf98",
	"type": "watson-text-to-speech",
	"z": "47f6f19a.6e5908",
	"name": "US Allison",
	"lang": "english",
	"voice": "en-US_AllisonVoice",
	"format": "audio/wav",
	"x": 350,
	"y": 340,
	"wires": [
		["1b37cfd0.ee4738"]
	]
}, {
	"id": "dd44c043.9e066",
	"type": "debug",
	"z": "47f6f19a.6e5908",
	"name": "",
	"active": true,
	"console": "false",
	"complete": "voice",
	"x": 360,
	"y": 220,
	"wires": []
}, {
	"id": "2eb56d3e.77c982",
	"type": "debug",
	"z": "47f6f19a.6e5908",
	"name": "",
	"active": true,
	"console": "false",
	"complete": "false",
	"x": 530,
	"y": 140,
	"wires": []
}, {
	"id": "b8e85fa3.1ec4a",
	"type": "websocket-listener",
	"z": "",
	"path": "/ws/audio",
	"wholemsg": "false"
}]
ibmrcruicks

Flow Info

created 7 months, 3 weeks ago

Node Types

Core
  • change (x2)
  • debug (x4)
  • delay (x1)
  • http in (x3)
  • http response (x2)
  • inject (x1)
  • template (x2)
  • websocket out (x1)
  • websocket-listener (x1)
Other

Tags

  • watson
  • text-to-speech
  • bluemix
  • audio
  • voice
  • node-red
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option