Google Speech - Streaming request returns EOF error

Using Go, I take an RTMP stream, transcode it to FLAC (using ffmpeg) and try to pass audio transcription to the Google Speech API. However, I continue to receive EOF errors when sending data. I can’t find the information about this error in the docs, so I'm not quite sure what causes it.

I divide the received data into 3s-clips (the length is not relevant if it is less than the maximum length of the streaming recognition request).

Here is the core of my code:

 func main() { done := make(chan os.Signal) received := make(chan []byte) go receive(received) go transcribe(received) signal.Notify(done, os.Interrupt, syscall.SIGTERM) select { case <-done: os.Exit(0) } } func receive(received chan<- []byte) { var b bytes.Buffer stdout := bufio.NewWriter(&b) cmd := exec.Command("ffmpeg", "-i", "rtmp://127.0.0.1:1935/live/key", "-f", "flac", "-ar", "16000", "-") cmd.Stdout = stdout if err := cmd.Start(); err != nil { log.Fatal(err) } duration, _ := time.ParseDuration("3s") ticker := time.NewTicker(duration) for { select { case <-ticker.C: stdout.Flush() log.Printf("Received %d bytes", b.Len()) received <- b.Bytes() b.Reset() } } } func transcribe(received <-chan []byte) { ctx := context.TODO() client, err := speech.NewClient(ctx) if err != nil { log.Fatal(err) } stream, err := client.StreamingRecognize(ctx) if err != nil { log.Fatal(err) } // Send the initial configuration message. if err = stream.Send(&speechpb.StreamingRecognizeRequest{ StreamingRequest: &speechpb.StreamingRecognizeRequest_StreamingConfig{ StreamingConfig: &speechpb.StreamingRecognitionConfig{ Config: &speechpb.RecognitionConfig{ Encoding: speechpb.RecognitionConfig_FLAC, LanguageCode: "en-GB", SampleRateHertz: 16000, }, }, }, }); err != nil { log.Fatal(err) } for { select { case data := <-received: if len(data) > 0 { log.Printf("Sending %d bytes", len(data)) if err := stream.Send(&speechpb.StreamingRecognizeRequest{ StreamingRequest: &speechpb.StreamingRecognizeRequest_AudioContent{ AudioContent: data, }, }); err != nil { log.Printf("Could not send audio: %v", err) } } } } } 

Running this code gives the following result:

 2017/10/09 16:05:00 Received 191704 bytes 2017/10/09 16:05:00 Saving 191704 bytes 2017/10/09 16:05:00 Sending 191704 bytes 2017/10/09 16:05:00 Could not send audio: EOF 2017/10/09 16:05:03 Received 193192 bytes 2017/10/09 16:05:03 Saving 193192 bytes 2017/10/09 16:05:03 Sending 193192 bytes 2017/10/09 16:05:03 Could not send audio: EOF 2017/10/09 16:05:06 Received 193188 bytes 2017/10/09 16:05:06 Saving 193188 bytes 2017/10/09 16:05:06 Sending 193188 bytes // Notice that this doesn't error 2017/10/09 16:05:09 Received 191704 bytes 2017/10/09 16:05:09 Saving 191704 bytes 2017/10/09 16:05:09 Sending 191704 bytes 2017/10/09 16:05:09 Could not send audio: EOF 

Note that not all of Send fail.

Can someone point me in the right direction? Does this have anything to do with FLAC headers or something else? I also wonder, maybe if flushing the buffer discards some data (i.e., this is a non-trivial operation that actually takes some time) and she doesn't like this missing information?

Any help would be really appreciated.

+8
go ffmpeg google-cloud-platform google-speech-api
source share
1 answer

So, it turns out that it is possible to get more information about the state of the stream, so we do not just need to rely on the returned error.

 if err := stream.Send(&speechpb.StreamingRecognizeRequest{ StreamingRequest: &speechpb.StreamingRecognizeRequest_AudioContent{ AudioContent: data, }, }); err != nil { resp, err := stream.Recv() log.Printf("Could not send audio: %v", resp.GetError()) } 

Fingerprints:

 2017/10/16 17:14:53 Could not send audio: code:3 message:"Invalid audio content: too long." 

This is a much more useful error message!

+7
source share

All Articles