google-cloud-node
google-cloud-node copied to clipboard
Surprising errors in production code using v2 of @google-cloud/speech
Hey guys, our system today started to produce surprisingly many errors, our PROD server is affected and all our users.
Error on "error" in recognizeStream {"code":3,"details":"Audio data does not appear to be in a supported encoding. If you believe this to be incorrect, try explicitly specifying the decoding parameters.","metadata":{}}
We did not change any implementation and I hope that recent update of Google Chrome also did not touch audio interfaces. We are using MediaRecorder API and up until today all users were happy and get their streams recognized successfully.
Here is our main service:
type StreamingRecognitionConfig =
protos.google.cloud.speech.v2.IStreamingRecognitionConfig;
export const createGoogleService = ({
language,
send,
}: {
language: string;
send: Sender<MachineEvent>;
}): Promise<TranscriptionService> => {
return new Promise((resolve, reject) => {
try {
const client = new speech.SpeechClient({
keyFilename: 'assistant-demo.json',
});
const recognizer = findRecognizerByLanguageCode(language).name;
const streamingConfig: StreamingRecognitionConfig = {
config: {
autoDecodingConfig: {},
},
streamingFeatures: {
interimResults: false,
enableVoiceActivityEvents: true, // Add this line to enable voice activity events
voiceActivityTimeout: {
speechStartTimeout: { seconds: 60 },
speechEndTimeout: { seconds: 60 },
},
},
};
const configRequest = {
recognizer,
streamingConfig,
};
logger.info('Creating Google service with recogniser:', recognizer);
const recognizeStream = client
._streamingRecognize()
.on('error', error => {
logger.error(
'Error on "error" in recognizeStream',
JSON.stringify(error)
);
send({ type: 'ERROR', data: parseErrorMessage(error) });
})
.on('data', (data: StreamingRecognizeResponse) => {
if (data.results.length > 0) {
const transcription = transformGoogleResponse(data);
if (transcription) {
const transcriptionText = getText(transcription);
if (!transcriptionText?.length) {
// if the transcription is empty, do nothing
return;
}
send({ type: 'NEW_TRANSCRIPTION', data: transcriptionText });
}
}
})
.on('end', () => {
logger.warn('Google recognizeStream ended');
});
let configSent = false;
let headersSent = false;
const transcribeAudio = (audio: Buffer, headers: Buffer) => {
if (!configSent) {
recognizeStream.write(configRequest);
configSent = true;
return;
}
if (configSent && !headersSent) {
recognizeStream.write({ audio: headers });
headersSent = true;
return;
}
recognizeStream.write({ audio });
};
const stop = () => {
if (recognizeStream) {
recognizeStream.end();
}
};
resolve({ stop, transcribeAudio });
} catch (error) {
logger.error('Error creating Google service:', error);
reject(error);
}
});
};