我正在创建 Unity WebGL 版本,并且必须在我的应用程序中使用 Google Cloud Speech To Text API。 Unity 在 WebGL 构建中不支持麦克风,但有一种解决方法,使用 jslib 文件通过 Javascript 代码访问麦克风。 问题是,无论我尝试什么或在网络上查看,都没有关于如何使用纯 Javascript 使用 HTTP POST 请求提交此数据以在 Google Cloud 中处理的文档(因为我无法轻松使用其他方法或库并且不希望此代码太复杂)。 我创建了一个 API 密钥(可能没有必要...),但我尝试发送的所有请求(例如下面的代码)都会返回错误代码 400 错误请求或类似内容:
fetch("https://speech.googleapis.com/v1/speech:recognize?key=API_KEY", {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json())
.then(data => {
// 3. Process the response
processResponse(data);
})
.catch(error => {
console.error('Error:', error);
});
哎呀,我什至尝试询问 ChatGPT 4 但没有得到答案。我承认我不是 Javascript 人,更不是专家,所以如果有人熟悉创建此类请求,请与我分享您的知识。 谢谢!
编辑: 由于它看起来有些不清楚,这是完整的代码(我现在不关心约定或样式,我需要首先运行核心功能):
StartRecording: function () {
console.log("Beginning of StartRecording");
// Function to send audio data to Google Cloud Speech-to-Text API
var sendToSpeechToText = function (blob) {
console.log("Beginning of SendToSpeechToText");
const apiKey = '<REMOVED>'; // Replace with your Google Cloud API key
const url = `https://speech.googleapis.com/v1/speech:recognize?key=${apiKey}`;
const reader = new FileReader();
reader.onload = function() {
const base64data = reader.result;
const audioBytes = base64data.split('base64,')[1];
const requestData = {
config: {
encoding: 'WEBM_OPUS',
sampleRateHertz: 16000,
languageCode: 'en-US'
},
audio: {
content: audioBytes
}
};
fetch(url, {
method: 'POST',
body: JSON.stringify(requestData),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log("Data Received!");
// Process the response data (transcript)
window.alert(data["results"]["0"]["alternatives"]["0"]["transcript"]);
})
.catch(error => console.error('Error:', error));
};
console.log("End of SendToSpeechToText");
reader.readAsDataURL(blob);
};
var handleSuccess = function(stream) {
console.log("Beginning of HandleSuccess");
const options = {
mimeType: 'audio/webm'
};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) recordedChunks.push(e.data);
});
mediaRecorder.addEventListener('stop', function() {
sendToSpeechToText(new Blob(recordedChunks));
});
mediaRecorder.start();
// For example, stop recording after 5 seconds
setTimeout(() => {
mediaRecorder.stop();
}, 5000);
console.log("End of HandleSuccess");
};
navigator.mediaDevices.getUserMedia({ audio: {
deviceId: "default",
sampleRate: 16000,
sampleSize: 16,
channelCount: 1
}, video: false })
.then(handleSuccess);
console.log("End of StartRecording");
}
我还尝试将
Authorization: 'Bearer ${apiKey}'
添加到标头,而不是在 url 中提供 API 密钥,但结果相同。
我将其留在这里,以防将来有人遇到此用例:
虽然我找不到我想要的答案,但我确实找到了使用本地 NodeJS 服务器的解决方法。它产生了额外的复杂性(以及必须维护的另一项服务),但它使我能够执行我想要的任务。
我只是将请求发布到 NodeJS 本地服务器,它读取 Google Cloud 请求的 Base64 编码音频数据和参数,使用我设置的服务帐户生成 API 密钥,发送并等待对 Google Cloud Speech To Text 的请求用于处理的API。当收到响应时,它只是将其传播回来作为对原始发布请求的响应。