watson-developer-cloud / node-sdk

:comet: Node.js library to access IBM Watson services.
https://www.npmjs.com/package/ibm-watson
Apache License 2.0
1.48k stars 670 forks source link

Speech To Text - Error: write after end exception #202

Closed Nhor closed 8 years ago

Nhor commented 8 years ago

Code from the docs:

var speech_to_text = watson.speech_to_text({
  username: '<username>',
  password: '<password>',
  version: 'v1'
});

fs.createReadStream('./resources/speech.wav')
  .pipe(speech_to_text.createRecognizeStream({ content_type: 'audio/l16; rate=44100' })
  .pipe(fs.createWriteStream('./transcription.txt'));

throws Error: write after end exception. Here's my full stacktrace:

D:\Projects\audalize\routes\add-audio.js:53
            throw(err);
            ^

Error: write after end
    at writeAfterEnd (_stream_writable.js:159:12)
    at TLSSocket.Writable.write (_stream_writable.js:204:5)
    at TLSSocket.Socket.write (net.js:618:40)
    at WebSocketConnection.sendFrame (D:\Projects\audalize\node_modules\watson-developer-cloud\node_modules\websocket\lib\WebSocketConnection.js:852:31)
    at WebSocketConnection.fragmentAndSend (D:\Projects\audalize\node_modules\watson-developer-cloud\node_modules\websocket\lib\WebSocketConnection.js:824:14)
    at WebSocketConnection.sendBytes (D:\Projects\audalize\node_modules\watson-developer-cloud\node_modules\websocket\lib\WebSocketConnection.js:739:10)
    at RecognizeStream._write (D:\Projects\audalize\node_modules\watson-developer-cloud\services\speech_to_text\v1.js:490:21)
    at doWrite (_stream_writable.js:292:12)
    at writeOrBuffer (_stream_writable.js:278:5)
    at RecognizeStream.Writable.write (_stream_writable.js:207:11)
    at ReadStream.ondata (_stream_readable.js:528:20)
    at emitOne (events.js:77:13)
    at ReadStream.emit (events.js:169:7)
    at ReadStream.Readable.read (_stream_readable.js:360:10)
    at flow (_stream_readable.js:743:26)
    at RecognizeStream.<anonymous> (_stream_readable.js:601:7)
nfriedly commented 8 years ago

hi @Nhor, did you update the <username> and <password> fields before running the example?

nfriedly commented 8 years ago

(Note: both the username and password are random characters generated by bluemix - see https://github.com/watson-developer-cloud/node-sdk#getting-the-service-credentials for instructions on how to get them.)

Nhor commented 8 years ago

Yes, I've generated my Watson Speech To Text service credentials and I'm getting the very first chunk of the response, but there goes a cascade of errors. Here's the console.log output:

2016-01-12 19:42:34.299: so it's who makes her home and you know I have a date when you gonna do
2016-01-12 19:42:34.311: Error: write after end
2016-01-12 19:42:34.311: Error: write after end
2016-01-12 19:42:34.311: Error: write after end
2016-01-12 19:42:34.327: Error: write after end
2016-01-12 19:42:34.327: Error: write after end
2016-01-12 19:42:34.327: Error: write after end
nfriedly commented 8 years ago

Hum, that doesn't sound good.. can you email me the sample audio file you're using? [github username]@us.ibm.com

nfriedly commented 8 years ago

Oh, also, please try creating a reference to the recognizeStream and listening for other events to see if anything else stands out. There's an example of this at https://github.com/watson-developer-cloud/node-sdk/blob/master/examples/speech_to_text.v1.js

Nhor commented 8 years ago

I've tried several audio files. So my conclusion is that it seems like the service is working perfectly fine with short phrases but fails to recognize bigger files, throwing Error: write after end exception for each next chunk after the first one.

nfriedly commented 8 years ago

Got the file, reproduced the bug, it looks like the connection is closing with a 1006 error/status code. I'll track down the root cause and get a fix out, hopefully within a day or two.

Nhor commented 8 years ago

Great, thanks!

nfriedly commented 8 years ago

This should be fixed in v1.2.0 - by default, the STT services stops processing after the first sentence/pause, and there's a continuous flag to override this. Node.js streams, though, has their own mechanism for ending the connection so I changed the default value to true (meaning keep transcribing until the audio stops coming) and also made it overrideable.

There may still be some issues to be address when it is overridden and set to false, but this should be a better fit for most usage.