@@ -116,7 +116,10 @@ module.exports = function (RED) {
116116 websocket = null ,
117117 socketCreationInProcess = false ,
118118 socketListening = false ,
119- contentType = null ,
119+ startPacket = { action : 'start' ,
120+ 'content-type' :'audio/wav' ,
121+ 'interim_results' : true
122+ } ,
120123 audioStack = [ ] ;
121124 const HOUR = 60 * 60 ;
122125
@@ -242,13 +245,12 @@ module.exports = function (RED) {
242245
243246 if ( "string" === typeof msg . payload ) {
244247 msg . payload = JSON . parse ( tmp ) ;
245- if ( msg . payload . mode &&
246- 'start' === msg . payload . mode &&
247- msg . payload . type ) {
248- contentType = msg . payload . type ;
248+ if ( msg . payload . action &&
249+ 'start' === msg . payload . action ) {
250+ startPacket = msg . payload ;
249251 }
250252 } else {
251- msg . payload = { 'mode ' : 'data' , 'data' : tmp } ;
253+ msg . payload = { 'action ' : 'data' , 'data' : tmp } ;
252254 }
253255
254256 return Promise . resolve ( msg . payload ) ;
@@ -347,81 +349,86 @@ module.exports = function (RED) {
347349 return p ;
348350 }
349351
350- function connectIfNeeded ( dataIn ) {
352+ function connectIfNeeded ( ) {
353+ console . log ( 're-establishing the connect' ) ;
354+ websocket = null ;
355+ socketCreationInProcess = false ;
356+ processSTTSocketStart ( )
357+ . then ( ( ) => {
358+ return Promise . resolve ( ) ;
359+ //return;
360+ } )
351361 }
352362
353- function connectToSTTSocket ( dataIn ) {
363+ function processSTTSocketStart ( ) {
354364 var p = new Promise ( function resolver ( resolve , reject ) {
355- //return connectIfNeeded(audioData);
356- //resolve();
357- var audioData = dataIn ;
358365 var model = config . lang + '_' + config . band ;
359- var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize'
360- + '?watson-token=' + token + '&model=' + model ;
361-
362- //if (!audioData) {
363- // audioData = {mode : 'start'};
364- //}
365-
366- if ( ! websocket && ! socketCreationInProcess &&
367- 'start' === audioData . mode ) {
368- socketCreationInProcess = true ;
369- var ws = new WebSocket ( wsURI ) ;
370- ws . on ( 'open' , ( ) => {
371- console . log ( '******************' ) ;
372- console . log ( 'Web Socket is now open' ) ;
373-
374- var message = {
375- action : 'start' ,
376- 'content-type' : contentType ? contentType :'audio/wav' ,
377- //'content-type': 'audio/webm',
378- 'interim_results' : true
379- //'max-alternatives': 3,
380- //keywords: ['colorado', 'tornado', 'tornadoes'],
381- //'keywords_threshold': 0.5
382- } ;
383- console . log ( 'Signalling Start' ) ;
384- ws . send ( JSON . stringify ( message ) ) ;
385- websocket = ws ;
386- socketCreationInProcess = false ;
366+ var wsURI = '' ;
367+
368+ if ( endpoint ) {
369+ var tmp = endpoint . replace ( 'https' , 'wss' ) ;
370+ wsURI = tmp + '/v1/recognize'
371+ + '?watson-token=' + token + '&model=' + model ;
372+ // https://stream.watsonplatform.net/speech-to-text/api
373+ } else {
374+ wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize'
375+ + '?watson-token=' + token + '&model=' + model ;
376+ }
377+
378+ if ( ! websocket && ! socketCreationInProcess ) {
379+ socketCreationInProcess = true ;
380+ var ws = new WebSocket ( wsURI ) ;
381+ ws . on ( 'open' , ( ) => {
382+ console . log ( '******************' ) ;
383+ console . log ( 'Web Socket is now open' ) ;
384+
385+ console . log ( 'Signalling Start' ) ;
386+ ws . send ( JSON . stringify ( startPacket ) ) ;
387+ websocket = ws ;
388+ socketCreationInProcess = false ;
387389 //resolve();
388- } ) ;
389- ( function ( dIn ) {
390- ws . on ( 'message' , ( data ) => {
391- // First message will be 'state': 'listening'
392- console . log ( '-----------------------' ) ;
393- console . log ( 'Data Received from Input' ) ;
394- console . log ( data ) ;
395- socketListening = true ;
396- var d = JSON . parse ( data )
397- var newMsg = { payload : JSON . parse ( data ) } ;
398- node . send ( newMsg ) ;
399- if ( dIn && d && d . state && 'listening' === d . state ) {
400- console . log ( 'We are now listening' ) ;
401- //resolve(true);
402- }
403- } ) ;
404- } ) ( dataIn ) ;
405-
406- ws . on ( 'close' , ( ) => {
407- if ( websocket ) {
408- websocket . close ( ) ;
409- }
410- websocket = null ;
411- socketListening = false ;
412- console . log ( 'STT Socket disconnected' ) ;
413- //setTimeout(connectToSTTSocket, 1000);
414390 } ) ;
391+
392+ ws . on ( 'message' , ( data ) => {
393+ // First message will be 'state': 'listening'
394+ console . log ( '-----------------------' ) ;
395+ console . log ( 'Data Received from Input' ) ;
396+ console . log ( data ) ;
397+ var d = JSON . parse ( data )
398+ var newMsg = { payload : JSON . parse ( data ) } ;
399+ node . send ( newMsg ) ;
400+ if ( d && d . state && 'listening' === d . state ) {
401+ socketListening = true ;
402+ console . log ( 'We are now listening' ) ;
403+ resolve ( ) ;
404+ }
405+ } ) ;
406+
407+ ws . on ( 'close' , ( ) => {
408+ //if (websocket) {
409+ // websocket.close();
410+ //}
411+ //websocket = null;
412+ socketListening = false ;
413+ console . log ( 'STT Socket disconnected' ) ;
414+ setTimeout ( connectIfNeeded , 1000 ) ;
415+ } ) ;
416+
417+ ws . on ( 'error' , ( err ) => {
418+ socketListening = false ;
419+ console . log ( 'Error Detected' ) ;
420+ reject ( err ) ;
421+ } ) ;
422+
415423 } else {
416- if ( dataIn ) {
417- //resolve(false);
418- }
424+ resolve ( ) ;
419425 }
420- resolve ( socketListening ) ;
426+
421427 } ) ;
422428 return p ;
423429 }
424430
431+
425432 function stackAudioFile ( audioData ) {
426433 console . log ( 'Pushing onto the stack' ) ;
427434 audioStack . push ( audioData ) ;
@@ -433,14 +440,14 @@ module.exports = function (RED) {
433440 var p = new Promise ( function resolver ( resolve , reject ) {
434441 console . log ( 'Sending Audio - outer ' ) ;
435442 console . log ( audioData ) ;
436- if ( audioData && audioData . mode ) {
437- if ( 'data' === audioData . mode ) {
443+ if ( audioData && audioData . action ) {
444+ if ( 'data' === audioData . action ) {
438445 console . log ( 'Sending Audio - inner' ) ;
439446
440447 // send stack First
441448 if ( audioStack && audioStack . length ) {
442449 audioStack . forEach ( ( a ) => {
443- if ( a && a . mode && 'data' === a . mode ) {
450+ if ( a && a . action && 'data' === a . action ) {
444451 websocket . send ( a . data ) ;
445452 }
446453 } ) ;
@@ -456,11 +463,11 @@ module.exports = function (RED) {
456463 }
457464 } ) ;
458465 } else {
459- var message = { action : 'stop' } ;
460- if ( audioData . mode === 'stop' ) {
466+ // var message = { action: 'stop' };
467+ if ( audioData . action === 'stop' ) {
461468 console . log ( 'Signalling Stop' ) ;
462- websocket . send ( JSON . stringify ( message ) ) ;
463- socketListening = false ;
469+ websocket . send ( JSON . stringify ( audioData ) ) ;
470+ // socketListening = false;
464471
465472 // Closing as refresh doesn't appear to work
466473 //websocket.close();
@@ -477,13 +484,23 @@ module.exports = function (RED) {
477484 var speech_to_text = determineService ( ) ;
478485 var p = getToken ( speech_to_text )
479486 . then ( ( ) => {
480- return connectToSTTSocket ( audioData ) ;
481- } )
482- . then ( ( listening ) => {
483- if ( listening ) {
484- return sendAudioSTTSocket ( audioData ) ;
485- } else {
486- return stackAudioFile ( audioData ) ;
487+ switch ( audioData . action ) {
488+ case 'start' :
489+ //return Promise.reject('Its a start');
490+ return processSTTSocketStart ( ) ;
491+ case 'stop' :
492+ case 'data' :
493+ // Add a Delay to allow the listening thread to kick in
494+ setTimeout ( ( ) => {
495+ if ( socketListening ) {
496+ return sendAudioSTTSocket ( audioData ) ;
497+ } else {
498+ return stackAudioFile ( audioData ) ;
499+ }
500+ } , 1000 ) ;
501+ //return Promise.reject('Its a data or stop');
502+ default :
503+ return Promise . resolve ( ) ;
487504 }
488505 } )
489506 . then ( ( ) => {
0 commit comments