IBM Watson Speech-to-Text 发送麦克风数据关闭连接
IBM Watson Speech-to-Text sending microphone data closes connection
我正在研究 IBM Watson Speech-to-Text 的 tutorial,使用 WebSocket 进行实时转录。我正在使用 Angular.
前 25 行代码是从 API reference 复制的。此代码成功连接并发起识别请求。 Watson 给我发了一条消息 { "state": "listening" }
.
我写了 function onClose()
在连接关闭时记录。
我制作了一个运行处理程序的按钮 $scope.startSpeechRecognition
。这使用 getUserMedia()
从麦克风流式传输音频,并使用 websocket.send()
将数据流式传输到 Watson。这是行不通的。单击此按钮将关闭连接。我认为我发送了错误类型的数据并且 Watson 正在关闭连接?
我将 websocket.send(blob);
从 onOpen
移到了我的处理程序 $scope.startSpeechRecognition
。我将 websocket.send(blob);
更改为 websocket.send(mediaStream);
。我可能有这个错误:'content-type': 'audio/l16;rate=22050'
。我怎么知道麦克风的比特率是多少?
是否有 JavaScript 的教程?当我google "IBM Watson Speech-to-Text JavaScript tutorial" 最上面是一个8000-line SDK。是否需要 SDK 或者我可以编写一个简单的程序来了解该服务的工作原理吗?
这是我的控制器:
'use strict';
app.controller('WatsonController', ['$scope', 'watsonToken', function($scope, watsonToken) {
console.log("Watson controller.");
var token = watsonToken;
var wsURI = "wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize"
+ "?watson-token=" + token + '&model=en-US_BroadbandModel';
var websocket = new WebSocket(wsURI); // opens connection to Watson
websocket.onopen = function(evt) { onOpen(evt) }; // executes when a connection opens
websocket.onclose = function(evt) { onClose(evt) }; // executes when a connection closes
websocket.onmessage = function(evt) { onMessage(evt) }; // logs messages from Watson to the console
websocket.onerror = function(evt) { onError(evt) }; // logs errors to the console
function onOpen(evt) {
var message = {
action: 'start',
'content-type': 'audio/flac',
'interim_results': true,
'max-alternatives': 3,
keywords: ['colorado', 'tornado', 'tornadoes'],
'keywords_threshold': 0.5
};
websocket.send(JSON.stringify(message));
// Prepare and send the audio file.
// websocket.send(blob);
// websocket.send(JSON.stringify({action: 'stop'}));
}
function onClose() {
console.log("Connection closed.");
};
function onMessage(evt) {
console.log(evt.data); // log the message to the console
}
$scope.startSpeechRecognition = () => {
console.log("Starting speech recognition.");
var constraints = { audio: true, video: false };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
console.log("Streaming audio.");
websocket.send(mediaStream);
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // log errors
};
$scope.stopSpeechRecognition = () => { // handler for button
console.log("Stopping speech recognition.");
websocket.send(JSON.stringify({action: 'stop'}));
};
$scope.closeWatsonSpeechToText = () => { // handler for button
console.log("Closing connection to Watson.");
websocket.close(); // closes connection to Watson?
};
}]);
这是我的模板:
<div class="row">
<div class="col-sm-2 col-md-2 col-lg-2">
<p>Watson test.</p>
</div>
</div>
<div class="row">
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-primary" ng-click="startSpeechRecognition()">Start</button>
</div>
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-warning" ng-click="stopSpeechRecognition()">Stop</button>
</div>
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-danger" ng-click="closeWatsonSpeechToText()">Close</button>
</div>
</div>
The SDK 不是必需的,但正如 Geman Attanasio 所说,它确实让您的生活更轻松。
但是,在你的代码中,这一行肯定行不通:
websocket.send(mediaStream);
来自 getUserMedia()
的 mediaStream 对象无法直接通过 WebsSocket 发送 - WebSocket 仅接受文本和二进制数据(原始示例中的 blob
)。您必须提取音频,然后只发送它。
但在这种情况下,即使这样还不够,因为 WebAudio API 以 32 位浮点数提供音频,这不是 Watson API 本身可以理解的格式。 SDK自动提取并转换为audio/l16;rate=16000
(16位整数)。
How do I know what bit rate comes from the microphone?
它在 AudioContext and, if you add a scriptProcessorNode, it can be passed AudioBuffers 上可用,包括音频数据和采样率。将采样率乘以每个样本的大小(转换为 l16 之前为 32 位,转换为 l16 后为 16 位)乘以通道数(通常为 1)以获得比特率。
但请注意,您在 rate=
之后输入内容类型的数字是采样率,而不是比特率。因此,您可以直接从 AudioContext 或 AudioBuffer 中复制它,而无需乘法运算。 (除非你像 SDK 那样对音频进行下采样。那么它应该设置为目标采样率,而不是输入率。)
如果您想了解这一切是如何工作的,整个 SDK 都是开源的:
- 正在从 mediaStream 中提取音频:https://github.com/saebekassebil/microphone-stream/blob/master/microphone-stream.js
- 转换和下采样:https://github.com/watson-developer-cloud/speech-javascript-sdk/blob/master/speech-to-text/webaudio-l16-stream.js
- 管理 WebSocket:https://github.com/watson-developer-cloud/speech-javascript-sdk/blob/master/speech-to-text/recognize-stream.js
熟悉 Node.js Streams standard 有助于阅读这些文件。
FWIW,如果您使用的是 Browserify 或 Webpack 等捆绑系统,您可以只挑选您需要的 SDK 部分,并获得更小的文件大小。您还可以将其设置为在页面加载和呈现后下载,因为 SDK 不会成为您初始呈现的一部分。
我正在研究 IBM Watson Speech-to-Text 的 tutorial,使用 WebSocket 进行实时转录。我正在使用 Angular.
前 25 行代码是从 API reference 复制的。此代码成功连接并发起识别请求。 Watson 给我发了一条消息 { "state": "listening" }
.
我写了 function onClose()
在连接关闭时记录。
我制作了一个运行处理程序的按钮 $scope.startSpeechRecognition
。这使用 getUserMedia()
从麦克风流式传输音频,并使用 websocket.send()
将数据流式传输到 Watson。这是行不通的。单击此按钮将关闭连接。我认为我发送了错误类型的数据并且 Watson 正在关闭连接?
我将 websocket.send(blob);
从 onOpen
移到了我的处理程序 $scope.startSpeechRecognition
。我将 websocket.send(blob);
更改为 websocket.send(mediaStream);
。我可能有这个错误:'content-type': 'audio/l16;rate=22050'
。我怎么知道麦克风的比特率是多少?
是否有 JavaScript 的教程?当我google "IBM Watson Speech-to-Text JavaScript tutorial" 最上面是一个8000-line SDK。是否需要 SDK 或者我可以编写一个简单的程序来了解该服务的工作原理吗?
这是我的控制器:
'use strict';
app.controller('WatsonController', ['$scope', 'watsonToken', function($scope, watsonToken) {
console.log("Watson controller.");
var token = watsonToken;
var wsURI = "wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize"
+ "?watson-token=" + token + '&model=en-US_BroadbandModel';
var websocket = new WebSocket(wsURI); // opens connection to Watson
websocket.onopen = function(evt) { onOpen(evt) }; // executes when a connection opens
websocket.onclose = function(evt) { onClose(evt) }; // executes when a connection closes
websocket.onmessage = function(evt) { onMessage(evt) }; // logs messages from Watson to the console
websocket.onerror = function(evt) { onError(evt) }; // logs errors to the console
function onOpen(evt) {
var message = {
action: 'start',
'content-type': 'audio/flac',
'interim_results': true,
'max-alternatives': 3,
keywords: ['colorado', 'tornado', 'tornadoes'],
'keywords_threshold': 0.5
};
websocket.send(JSON.stringify(message));
// Prepare and send the audio file.
// websocket.send(blob);
// websocket.send(JSON.stringify({action: 'stop'}));
}
function onClose() {
console.log("Connection closed.");
};
function onMessage(evt) {
console.log(evt.data); // log the message to the console
}
$scope.startSpeechRecognition = () => {
console.log("Starting speech recognition.");
var constraints = { audio: true, video: false };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
console.log("Streaming audio.");
websocket.send(mediaStream);
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // log errors
};
$scope.stopSpeechRecognition = () => { // handler for button
console.log("Stopping speech recognition.");
websocket.send(JSON.stringify({action: 'stop'}));
};
$scope.closeWatsonSpeechToText = () => { // handler for button
console.log("Closing connection to Watson.");
websocket.close(); // closes connection to Watson?
};
}]);
这是我的模板:
<div class="row">
<div class="col-sm-2 col-md-2 col-lg-2">
<p>Watson test.</p>
</div>
</div>
<div class="row">
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-primary" ng-click="startSpeechRecognition()">Start</button>
</div>
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-warning" ng-click="stopSpeechRecognition()">Stop</button>
</div>
<div class="col-sm-2 col-md-2 col-lg-2">
<button type="button" class="btn btn-danger" ng-click="closeWatsonSpeechToText()">Close</button>
</div>
</div>
The SDK 不是必需的,但正如 Geman Attanasio 所说,它确实让您的生活更轻松。
但是,在你的代码中,这一行肯定行不通:
websocket.send(mediaStream);
来自 getUserMedia()
的 mediaStream 对象无法直接通过 WebsSocket 发送 - WebSocket 仅接受文本和二进制数据(原始示例中的 blob
)。您必须提取音频,然后只发送它。
但在这种情况下,即使这样还不够,因为 WebAudio API 以 32 位浮点数提供音频,这不是 Watson API 本身可以理解的格式。 SDK自动提取并转换为audio/l16;rate=16000
(16位整数)。
How do I know what bit rate comes from the microphone?
它在 AudioContext and, if you add a scriptProcessorNode, it can be passed AudioBuffers 上可用,包括音频数据和采样率。将采样率乘以每个样本的大小(转换为 l16 之前为 32 位,转换为 l16 后为 16 位)乘以通道数(通常为 1)以获得比特率。
但请注意,您在 rate=
之后输入内容类型的数字是采样率,而不是比特率。因此,您可以直接从 AudioContext 或 AudioBuffer 中复制它,而无需乘法运算。 (除非你像 SDK 那样对音频进行下采样。那么它应该设置为目标采样率,而不是输入率。)
如果您想了解这一切是如何工作的,整个 SDK 都是开源的:
- 正在从 mediaStream 中提取音频:https://github.com/saebekassebil/microphone-stream/blob/master/microphone-stream.js
- 转换和下采样:https://github.com/watson-developer-cloud/speech-javascript-sdk/blob/master/speech-to-text/webaudio-l16-stream.js
- 管理 WebSocket:https://github.com/watson-developer-cloud/speech-javascript-sdk/blob/master/speech-to-text/recognize-stream.js
熟悉 Node.js Streams standard 有助于阅读这些文件。
FWIW,如果您使用的是 Browserify 或 Webpack 等捆绑系统,您可以只挑选您需要的 SDK 部分,并获得更小的文件大小。您还可以将其设置为在页面加载和呈现后下载,因为 SDK 不会成为您初始呈现的一部分。