此代码使用opus编码流作为云语音识别的输入(选项:contentType:'OGG_OPUS',sampleRateHertz:48000,),并且工作正常。
但是,示例二进制二进制upload code之后发送到Cloud Storage api的同一流的bufferCopy会导致错误,导致下载后音频无法播放。同样在下载时,使用'ogg'和'opus'文件类型,ffprobe将无法正确检测编码。
控制台和从上载到GCS的输出看起来都不错-有关正确大小的二进制文件在那里,可以使用gsutils下载。
适用于Google云识别api的opus流不适用于云存储api,因为它是音频流的简单文件接收器。我使用gsutil从云中获取音频文件,但是它无法在任何播放器中播放,并且ffprobe不会检测到编码。
我不知道如何调试问题。客户端上的原始音频Blob可以正常播放,其字节大小非常接近,但不等于上传到GCS api /从GCS api下载的文件的大小。
下面的代码详细信息:socket-io用于从js层获取数据到此Express服务器实例。...
client.on('startGoogleCloudStream', function (data) {
// startRecognitionStream(this, data);
console.log('STRMbeg ' + typeof recognizeStream);
rs = new stream.Readable();
rs._read = function () {};
readStream1 = new ReadableStreamClone(rs);
readStream2 = new ReadableStreamClone(rs);
startRecognitionStream(this);
let rfil = 'audio/' +uuidv4() + '.ogg'; //typ '.opus' same error
const file = myBucket.file(rfil);
var otstrm = file.createWriteStream({
metadata: {
contentType: 'audio/ogg'
},
gzip: false,
resumable: false
});
readStream1.pipe(recognizeStream);// works fine
readStream2.pipe(otstrm) // gets a corrupted binary up on cloud
.on('error', function(err) {
console.log('second strm ' + err);
})
.on('finish', function() {
console.log('Done BcketFilaudio local');
});
});
client.on('endGoogleCloudStream', function (data) {
console.log('STRMend');
// stopRecognitionStream();
rs.push(null); // null is Stream.END
recognizeStream = null;
});
client.on('binaryData', function (data) {
console.log('data ' + data.length ); // log binary data
if (recognizeStream !== null) {
let _bfr = Buffer.from(data.buffer);
rs.push(_bfr);
}
});
function startRecognitionStream (client, data) {
recognizeStream = speechClient.streamingRecognize(request)
.on('error', console.error)
.on('data', (data) => { // back to client on socket.io
// Dev only logging
process.stdout.write(
(data.results[0] && data.results[0].alternatives[0])
? `Transcription: ${data.results[0].alternatives[0].transcript}\n`
: `\n\nReached transcription time limit, press Ctrl+C\n`
);
client.emit('speechData', data);
if (data.results[0] && data.results[0].isFinal) {
postRecSpeech(data.results[0].alternatives[0].transcript);
}
});
}
答案 0 :(得分:1)
由于某些原因,GCS不接受使用Cloud Speech的流的副本,并且由于向多个API的输入而无法重用服务器端流。
-解决方法
即使流(音频记录器)已经作为流在服务器端使用,流流块也必须浓缩到客户端上的Blob,然后重新发布以像执行curl / POST一样表达...
curl -X POST --header "Transfer-Encoding: chunked" --header "Content-Type: audio/ogg; rate=48000" --data-binary @myaudio.opus "https://localhost${PORT}/audio/upload"
下面的我的快速代码可以正常工作,而GCS音频可以很好地进行下载。
app.post("/audio/upload", gcsAudio);
const gcsAudio = (req, res) => {
const type = req.get('Content-Type');
let gcsname = 'audio/' +uuidv4() + '.opus';
const files = myBucket.file(gcsname);
const stream = files.createWriteStream({
metadata: {
contentType: type
},
resumable: false
});
req
.pipe(stream)
.on("error", (err) => {
restify.InternalServerError(err);
})
.on('finish', () => {
res.json({
success: true,
fileUrl: `https://storage.googleapis.com/${_bucket}/${gcsname}`
})
});
};