Search code examples
node.jsexpressgoogle-speech-api

Using Google Speech API in Express server


I am trying to write a simple web app that uses the Google Speech API to transcribe an audio file to text. I set up the Google Speech API Authentication etc. correctly so I managed to run Google's node sample. Now I want to call it from my own server on a local file called "audio.raw" that lives in the same directory as the following server.js:

const express = require("express");
const fs = require("fs");
const app = express();
app.set("port", process.env.PORT || 3001);

function syncRecognize (filename, encoding, sampleRateHertz, languageCode) {

  const Speech = require('@google-cloud/speech');
  const speech = Speech();

  const request = {
    encoding: encoding,
    sampleRateHertz: sampleRateHertz,
    languageCode: languageCode
  };

  speech.recognize(filename, request)
    .then((results) => {
      const transcription = results[0];
      return transcription;
    })
    .catch((err) => {
      console.error('ERROR:', err);
    });
}

app.get("/api/transcribe", (req, res) => {

  syncRecognize(
    './audio.raw',
    'LINEAR16',
    16000,
    'en-US'
  ).then(text => {res.json(text)})
  .catch((err) => {
    console.error('ERROR:', err);
  });   
})

When I try to do this, I get the following error:

[0] TypeError: Cannot read property 'then' of undefined
[0]     at /path/to/server.js:62:4 // the .then after syncRecognize(...)
...

What do I need to do differently?

EDIT

Ok so I verified that the syncRecognize function indeed returns the correct const transcription at some point. The problem is that for some reason the .then won't wait for this to be returned.

I read that in order to use the ".then" operator you need to return a promise. I am not exactly sure on how to do this or whether there is a better option. I guess it's really a problem with my lack of knowledge about asynchronism.


Solution

  • We can see on the last few lines of the function that the method call recognize() does indeed return a Promise. You can easily tell by the use f .then() and .catch()

    Since you're calling this method in app.get() as a Promise, simply return the Promise in your method:

    const Speech = require('@google-cloud/speech')
    const speech = Speech()
    
    function syncRecognize (filename, encoding, sampleRateHertz, languageCode) {
    
      const request = {
        encoding,
        sampleRateHertz,
        languageCode,
      }
    
      return speech.recognize(filename, request)
    }