通过 node.js 在浏览器上将音频流式传输到 Azure 语音 api
Stream audio to Azure speech api by node.js on browser
我正在 node.js 在浏览器上使用 Azure 语音 api 制作语音到文本的演示。根据 API 文档 here,它确实指定需要 .wav 或 .ogg 文件。但是下面的示例通过将字节数据发送到 api.
来调用 api
所以我已经以字节数组形式从麦克风获取数据。将其转换为字节并发送到 api 是正确的路径吗?或者我最好将它保存为 .wav 文件然后发送到 api?
下面是我的代码。
这是来自麦克风部分的流。
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => { handlerFunction(stream) })
function handlerFunction(stream) {
rec = new MediaRecorder(stream);
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive") {
let blob = new Blob(audioChunks, { type: 'audio/wav; codec=audio/pcm; samplerate=16000' });
recordedAudio.src = URL.createObjectURL(blob);
recordedAudio.controls = true;
recordedAudio.autoplay = true;
console.log(blob);
let fileReader = new FileReader();
var arrayBuffer = new Uint8Array(1024);
var reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onloadend = function () {
var byteArray = new Uint8Array(reader.result);
console.log("reader result" + reader.result)
etTimeout(() => getText(byteArray), 1000);
}
}
}
}
这是api通话部分
function getText(audio, callback) {
console.log("in function audio " + audio);
console.log("how many byte?: " + audio.byteLength)
const sendTime = Date.now();
fetch('https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US', {
method: "POST",
headers: {
'Accept': 'application/json',
'Ocp-Apim-Subscription-Key': YOUR_API_KEY,
// 'Transfer-Encoding': 'chunked',
// 'Expect': '100-continue',
'Content-type': 'audio/wav; codec=audio/pcm; samplerate=16000'
},
body: audio
})
.then(function (r) {
return r.json();
})
.then(function (response) {
if (sendTime < time) {
return
}
time = sendTime
//callback(response)
}).catch(e => {
console.log("Error", e)
})
}
它 returns 与 400 (Bad Request)
并说:
{Message: "Unsupported audio format"}
原因:
请注意,您不是通过
创建具有 audio/wav
mimeType 的 MediaRecorder
new Blob(audioChunks,{type:'audio/wav; codec=audio/pcm; samplerate=16000'})
此声明只是对blob的描述。我用 isTypeSupported
:
测试我的 Chrome(v71)
MediaRecorder.isTypeSupported("audio/wav") // return false
MediaRecorder.isTypeSupported("audio/ogg") // return false
MediaRecorder.isTypeSupported("audio/webm") // return true
MediaRecorder 似乎只会录制 audio/webm
中的音频。此外,当我 运行 Chrome 上的以下代码时,默认 rec.mimeType
是 audio/webm;codecs=opus
rec = new MediaRecorder(stream);
根据 Audio formats Requiremnts,尚不支持 audio/webm
。
方法:
在调用getText()
之前,我们需要先将webm
转换为wav
。有很多库可以帮助我们做到这一点。我只是在您的代码之前复制 Jam3's script 以将 webm
转换为 wav
:
// add Jam3's script between Line 2 and Line 94 or import that module as you like
// create a audioContext that helps us decode the webm audio
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
rec = new MediaRecorder(stream,{
mimeType : 'audio/webm',
codecs : "opus",
});
// ...
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive") {
var blob = new Blob(audioChunks, { 'type': 'audio/webm; codecs=opus' });
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
arrayBuffer = event.target.result;
};
fileReader.readAsArrayBuffer(blob);
fileReader.onloadend=function(d){
audioCtx.decodeAudioData(
fileReader.result,
function(buffer) {
var wav = audioBufferToWav(buffer);
setTimeout(() => getText(wav), 1000);
},
function(e){ console.log( e); }
);
};
}
}
对我来说效果很好:
附带说明一下,我建议您应该使用您的后端来调用语音转文本服务。 切勿在浏览器中调用 azure stt
服务。那是因为将您的订阅密钥暴露给前端是非常危险的。 任何人都可以检查网络并窃取您的密钥。
我正在 node.js 在浏览器上使用 Azure 语音 api 制作语音到文本的演示。根据 API 文档 here,它确实指定需要 .wav 或 .ogg 文件。但是下面的示例通过将字节数据发送到 api.
来调用 api所以我已经以字节数组形式从麦克风获取数据。将其转换为字节并发送到 api 是正确的路径吗?或者我最好将它保存为 .wav 文件然后发送到 api?
下面是我的代码。
这是来自麦克风部分的流。
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => { handlerFunction(stream) })
function handlerFunction(stream) {
rec = new MediaRecorder(stream);
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive") {
let blob = new Blob(audioChunks, { type: 'audio/wav; codec=audio/pcm; samplerate=16000' });
recordedAudio.src = URL.createObjectURL(blob);
recordedAudio.controls = true;
recordedAudio.autoplay = true;
console.log(blob);
let fileReader = new FileReader();
var arrayBuffer = new Uint8Array(1024);
var reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onloadend = function () {
var byteArray = new Uint8Array(reader.result);
console.log("reader result" + reader.result)
etTimeout(() => getText(byteArray), 1000);
}
}
}
}
这是api通话部分
function getText(audio, callback) {
console.log("in function audio " + audio);
console.log("how many byte?: " + audio.byteLength)
const sendTime = Date.now();
fetch('https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US', {
method: "POST",
headers: {
'Accept': 'application/json',
'Ocp-Apim-Subscription-Key': YOUR_API_KEY,
// 'Transfer-Encoding': 'chunked',
// 'Expect': '100-continue',
'Content-type': 'audio/wav; codec=audio/pcm; samplerate=16000'
},
body: audio
})
.then(function (r) {
return r.json();
})
.then(function (response) {
if (sendTime < time) {
return
}
time = sendTime
//callback(response)
}).catch(e => {
console.log("Error", e)
})
}
它 returns 与 400 (Bad Request)
并说:
{Message: "Unsupported audio format"}
原因:
请注意,您不是通过
创建具有audio/wav
mimeType 的 MediaRecorder
new Blob(audioChunks,{type:'audio/wav; codec=audio/pcm; samplerate=16000'})
此声明只是对blob的描述。我用 isTypeSupported
:
MediaRecorder.isTypeSupported("audio/wav") // return false
MediaRecorder.isTypeSupported("audio/ogg") // return false
MediaRecorder.isTypeSupported("audio/webm") // return true
MediaRecorder 似乎只会录制 audio/webm
中的音频。此外,当我 运行 Chrome 上的以下代码时,默认 rec.mimeType
是 audio/webm;codecs=opus
rec = new MediaRecorder(stream);
根据 Audio formats Requiremnts,尚不支持 audio/webm
。
方法:
在调用getText()
之前,我们需要先将webm
转换为wav
。有很多库可以帮助我们做到这一点。我只是在您的代码之前复制 Jam3's script 以将 webm
转换为 wav
:
// add Jam3's script between Line 2 and Line 94 or import that module as you like
// create a audioContext that helps us decode the webm audio
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
rec = new MediaRecorder(stream,{
mimeType : 'audio/webm',
codecs : "opus",
});
// ...
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive") {
var blob = new Blob(audioChunks, { 'type': 'audio/webm; codecs=opus' });
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
arrayBuffer = event.target.result;
};
fileReader.readAsArrayBuffer(blob);
fileReader.onloadend=function(d){
audioCtx.decodeAudioData(
fileReader.result,
function(buffer) {
var wav = audioBufferToWav(buffer);
setTimeout(() => getText(wav), 1000);
},
function(e){ console.log( e); }
);
};
}
}
对我来说效果很好:
附带说明一下,我建议您应该使用您的后端来调用语音转文本服务。 切勿在浏览器中调用 azure stt
服务。那是因为将您的订阅密钥暴露给前端是非常危险的。 任何人都可以检查网络并窃取您的密钥。