我第一次使用Google Cloud Speech,说实话,我很遗憾。
首先,我在这里快速总结一下我的主要目的:我试图将一个麦克风输入放入一个React组件,该组件允许用户通过语音输入输入以及输入。为了这些目的,我'使用getUserMedia(我只需要Firefox和Chrome兼容性)通过socket.io-stream将音频流传输到后端服务,后端服务又将音频数据流式传输到Google Cloud Speech,然后使用转录的输入发出响应。
现在,我已将其设置为仅在音频停止录制后使用blobReadStream流式传输到我的流(通过ss.createStream()
创建)。之后的目标是流式传输实时音频,以便在用户说话时显示结果,但是现在,我只想得到结果显示,期间,而且我没有太多运气。
因为我最终希望支持实时结果,按照this tutorial,我实现了以下代码:
在我的前端:
getTextFromAudio: function(audioBlob, onUpdate, onEnd, onError) {
if(!audioBlob) {
return;
}
//Creates an instance of socket.io-stream
let stream = ss.createStream();
let options = {
request: {
config: {
'encoding':'LINEAR16',
'sampleRateHertz': 16000,
'languageCode': 'en-US'
},
interimResults: true
}
};
ss(socket).emit('SpeechToTextUpload', stream, options);
//Stream the blob to the backend
ss.createBlobReadStream(audioBlob).pipe(stream);
if(onUpdate) {
socket.on('SpeechToTextUploadUpdate', onUpdate);
}
if(onEnd) {
socket.on('SpeechToTextUploadEnd', onEnd);
}
if(onError) {
socket.on('SpeechToTextUploadError', onError);
}
}
在我的后端:
ss(socket).on('SpeechToTextUpload', (stream, data) => {
// If this socket is not authorized...
if (!authorizedSockets[socket.id]) {
let error = new Error('Unauthorized Socket ' + socket.id);
error.status = 401;
console.error(error);
//Front end Error Mesage:
socket.emit('SpeechToTextUploadFailed', error);
} else {
//initializes cloud speech
let speech = require('@google-cloud/speech');
let client = new speech.SpeechClient({
projectId: projectId,
credentials: GCSServiceAccount
});
let recognizeStream = client
.streamingRecognize(data.request)
.on('error', (error) => {
socket.emit('SpeechToTextUploadError', error);
})
.on('data', (speechData) => {
console.log('speechData', speechData);
if (speechData && speechData.results && speechData.results[0] &&
speechData.results[0].alternatives && speechData.results[0].alternatives[0]) {
let transcript = speechData.results[0].alternatives[0].transcript;
socket.emit('SpeechToTextUploadUpdate', transcript);
} else {
let error = new Error('Reached transcription time limit. Please stop your recording and start again.');
error.status = 402;
socket.emit('SpeechToTextUploadError', error);
}
})
.on('end', (value) => {
console.log('Recognize stream end', value);
socket.emit('SpeechToTextUploadEnd');
});
stream.pipe(recognizeStream);
} // end authorized socket
stream.on('data', chunk => {
console.log('Well, at least a chunk is being received:', chunk);
});
stream.on('error', error => {
socket.emit('SpeechToTextUploadError', error);
});
});
经过一番kajiggering,我终于得到了这个来停止抛出错误......但现在它只是没有发送任何东西。通过控制台日志记录,我发现:
stream.on('data')
会注销正在接收的数据块recognizeStream.on('data')
从不记录任何内容,这意味着此事件永远不会触发!因此,出于某种原因,我正在将数据流式传输到recognizeStream
,并且只是在没有收到end
的情况下立即触发data
事件。
我很困惑。我的设置有什么问题?是不是不实际发送实时数据,只是现有的blob?从浏览器中的录音到通过Google Cloud Speech进行实时转录,我找不到任何好的教程,特别是使用socket.io-stream。
编辑:我仍然不确定为什么这不起作用,但我能够circumvent this problem entirely。然而,经过一番思考后,我将这个问题保留原样,因为我不清楚为什么这不起作用。