googleapis / nodejs-speech

This repository is deprecated. All of its content and history has been moved to googleapis/google-cloud-node.
https://cloud.google.com/speech/
Apache License 2.0
689 stars 291 forks source link

"Long duration elapsed without audio" after input stream closes #894

Closed tony-ist closed 1 year ago

tony-ist commented 2 years ago

Hi.

I am getting ApiError: Audio Timeout Error: Long duration elapsed without audio. Audio should be sent close to real time. after my input stream closes.

The following code writes only Noop stream close, even though it seems like it should end recognize stream.

// From https://github.com/sindresorhus/noop-stream
function readableNoopStream({ size = 0, ...options } = {}) {
  let producedSize = 0

  return new ReadableStream({
    ...options,
    read(readSize: number) {
      let shouldEnd = false

      if ((producedSize + readSize) >= size) {
        readSize = size - producedSize
        shouldEnd = true
      }

      setImmediate(() => {
        if (size === 0) {
          this.push(null)
        }

        producedSize += readSize
        // this.push(Buffer.alloc(readSize))

        if (shouldEnd) {
          this.push(null)
        }
      })
    },
  })
}

async function testStream() {
  const inputStream = readableNoopStream({ size: Infinity })
    .on('end', () => console.log('Noop stream end'))
    .on('close', () => console.log('Noop stream close'))
    .on('error', error => console.error('Noop stream error:', error))

  const request = {
    config: {
      encoding: AudioEncoding.LINEAR16,
      sampleRateHertz: 48000,
      languageCode: config.languageCode,
    },
    interimResults: false,
  }

  const googleSpeechClient = new googleSpeech.SpeechClient()
  const recognizeStream: Stream.Duplex = googleSpeechClient.streamingRecognize(request)
    .on('end', () => console.log('Recognize stream end'))
    .on('close', () => console.log('Recognize stream close'))
    .on('error', error => console.error('Recognize stream error:', error))

  inputStream
    .pipe(recognizeStream)
    .on('data', data => console.log('transcription:', data.results[0].alternatives[0].transcript))
    .on('error', error => console.error('Pipe error:', error))

  inputStream.emit('close')
}

testStream().catch(console.error)

If I change inputStream.emit('close') to inputStream.emit('end') it ends recognize stream correctly. This does not reproduce the API error, but I think shows a problem well. Am I missing something?

telpirion commented 1 year ago

I think you've got your readable streams and your writable streams mixed up, which is why 'end' works and 'close" does not.

Regardless, this client library and its samples are migrating to new locations:

If needed, please reopen this issue in the appropriate location. Thank you!