Google Cloud Speech会识别Stream无法接收数据吗?

时间:2018-06-18 16:00:39

标签: socket.io google-cloud-speech

我第一次使用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。然而,经过一番思考后,我将这个问题保留原样,因为我不清楚为什么这不起作用。

0 个答案:

没有答案