0

I'd like to recognize an audio file in a NodeJS server.

I'm using the command line on Windows 10, and the Node's version is 10.6.0, I've installed @google-cloud/speech regulary with npm. Morest I've declared the environment variable for credentials (explained here https://cloud.google.com/docs/authentication/getting-started?hl=en), and I've copyed the json file in the "credential" folder :

set GOOGLE_APPLICATION_CREDENTIALS="C:\Users\Me\Documents\NodeJs\Project1\credentials\RDCommandeVocale-b521de3b57d9.json"

The file was encoded via ffmpeg with this command :

ffmpeg -i newRecording.aac -vol 512 -c flac -ar 16000 newRecording.flac

My source code is :

const folderName = "uploaded";
const fileName = "newRecording";
const client = new speech.SpeechClient();

const config = {
  encoding:"FLAC",
  sampleRateHertz: 16000,
  languageCode: "fr-FR"
};
const audioBytes = fs.readFileSync(`${__dirname}\\` + folderName + "\\" + fileName + ".flac").toString('base64');
//This doesn't work else with this : 
//const audioBytes = fs.readFileSync(".\\uploaded" + fileName + ".flac").toString('base64');
// ... nor this one
//const audioBytes = fs.readFileSync("./uploaded" + fileName + ".flac").toString('base64');

const request = {
  config: config,
  audio: audioBytes,
};

client.recognize(request).then( response=>{
  const transcription = response.results 
  .map(result => result.alternatives[0].transcript)// récupérer uniquement la première alternative
  .join('\n');
  console.log("Textual transcription: ", transcription );
  res.status(200)
  .json({ status: "success", message: transcription });
},
(err)=>{
  console.log("Transcription ERROR : ", JSON.stringify(err));
  res.status(500)
  .json({ status: "error", message: JSON.stringify(err) });
});

I get this error :

Textual transcription : {"errno":-4058,"syscall":"lstat","code":"ENOENT","path":"c:\Users\Me\Documents\Me\NodeJs\Project1\\"C:"}

Does this error type is referenced anywhere in Google Cloud API docs ?

  • I think it could be a directory error (idea taken here : [https://stackoverflow.com/questions/48370690/cloud-functions-deploy-error-during-lint-on-windows-enoent-enoent-no-such-fil]), but could you tell me if it could be an authentication issue ? Does Google Cloud's authentication is required to send a request to Google Cloud Speech API please ? – François Gardien Oct 02 '19 at 10:20

2 Answers2

1

The following code snippet is fully functional and will display the response object on the console. You were missing the fact that the audio property of the request object expects a { contents: audioBytes } object.

For this test, I also removed all the server-side code you had added.

As you seem to prefer the Promise approach (as opposed to await/async), I kept it, but used the .catch method rather than catching any errors, in a second function inside the .then as you did.

const speech = require('@google-cloud/speech');
const fs = require('fs')
const client = new speech.SpeechClient();

const config = {
    encoding: 'FLAC',
    sampleRateHertz: 16000,
    languageCode: 'en'
};

const audioBytes = fs.readFileSync('test.flac').toString('base64');

const request = {
    config: config,
    audio: {
        content: audioBytes
    }
};

client
    .recognize(request)
    .then( response => {
        const transcription = response.results 
        console.log("Textual transcription: ", JSON.stringify(response, {}, 2));
    })
    .catch((err) => {
        console.log("Transcription ERROR : ", err);
    });

With my audio file, I got this response:

$ node transcribe-test.js 
Textual transcription:  [
  {
    "results": [
      {
        "alternatives": [
          {
            "words": [],
            "transcript": "the following is an audio abstract for 2019",
            "confidence": 0.8660579323768616
          }
        ],
        "channelTag": 0
      }
    ]
  },
  null,
  null
]

Good luck!

jfix
  • 477
  • 4
  • 21
0

This doesn't seem to be an error with Google's Text-to-speech service, but an error of a directory that was not found.

Explore Node's built-in path module, and especially the join() method.

You may want to rewrite this line:

const audioBytes = fs.readFileSync(`${__dirname}\\` + folderName + "\\" + fileName + ".flac").toString('base64');

like this:

const path = require('path')
...
const file = path.join(__dirname, folderName, fileName, '.flac')
const audioBytes = fs.readFileSync(file).toString('base64')

Although this may not be important for you, this will also work on systems other than Windows as Node will automatically do the right thing.

jfix
  • 477
  • 4
  • 21
  • It's ok to use 'path' module, I see that the file exists with this : `console.log("audioBytes ="+JSON.stringify(audioBytes) );`. But now it catch an error with this error in the debug console : `error = {}` It seems that the "empty response" could be caused by a bad file format, according to this documentation : https://cloud.google.com/speech-to-text/docs/troubleshooting. I will check for the good file format. Thanks ! – François Gardien Oct 07 '19 at 17:42
  • @FrançoisGardien I would recommend removing the `JSON.stringify(err)` in your log statement and just keep `err`. At least in my tests, this produced more informative error messages. – jfix Oct 09 '19 at 09:30