【问题标题】:WebSocket problems with IBM WatsonIBM Watson 的 WebSocket 问题
【发布时间】:2020-01-27 20:36:22
【问题描述】:

这太令人沮丧了。我想创建简单的语音到文本应用程序,但连接有问题。我能够获得令牌,但出现了问题,屏幕如下:handshake error、http error。首先我尝试关注这个youtube guy,但他的代码不起作用。然后我尝试关注文档watson-speech npm 和ibm-watson npm,但现在我被卡住了。

我得到了令牌,但是我不能更进一步,我正在使用 server.js 和 App.js 来实现这个目标,这里是代码:

server.js

'use strict';

const express = require('express');
const app = express();
const vcapServices = require('vcap_services');
const cors = require('cors');

const { IamTokenManager } = require('ibm-watson/auth');

if (process.env.VCAP_SERVICES) {

  // enable rate-limiting
  const RateLimit = require('express-rate-limit');
  app.enable('trust proxy'); // required to work properly behind Bluemix's reverse proxy

  const limiter = new RateLimit({
    windowMs: 30000, // 0.5 minute
    max: 100 // limit each IP to 100 requests per windowMs
  });

  //  apply to /api/*
  app.use('/api/', limiter);
  const secure = require('express-secure-only');
  app.use(secure());
}

// app.use(express.static(__dirname + '/static'));
app.use(cors())

const sttAuthenticator = new IamTokenManager(
  {
     apikey: 'knkk_???_XjW7C9p4DUxlk6p1B9-rez8gJykyh-rYm'
  }
);

// speech to text token endpoint
app.use('/api/speech-to-text/token', function(req, res) {
  return sttAuthenticator
    .requestToken()
    .then(({ result }) => {
      res.json({ accessToken: result.access_token, url: 'https://stream.watsonplatform.net/speech-to-text/knkk_???_XjW7C9p4DUxlk6p1B9-rez8gJykyh-rYm' });
    })
    .catch(console.error);
});

const port = process.env.PORT || process.env.VCAP_APP_PORT || 3002;
app.listen(port, function() {
  console.log('Example IBM Watson Speech JS SDK client app & token server live at http://localhost:%s/', port);
});

// Chrome requires https to access the user's microphone unless it's a localhost url so
// this sets up a basic server on port 3001 using an included self-signed certificate
// note: this is not suitable for production use
// however bluemix automatically adds https support at https://<myapp>.mybluemix.net

if (!process.env.VCAP_SERVICES) {
  const fs = require('fs');
  const https = require('https');
  const HTTPS_PORT = 3001;

  const options = {
    key: fs.readFileSync(__dirname + '/keys/localhost.pem'),
    cert: fs.readFileSync(__dirname + '/keys/localhost.cert')
  };
  https.createServer(options, app).listen(HTTPS_PORT, function() {
    console.log('Secure server live at https://localhost:%s/', HTTPS_PORT);
  });
}

App.js

import React, { Component } from 'react';
import './App.css';

import recognizeMic from 'watson-speech/speech-to-text/recognize-microphone';
import WatsonSpeech from 'watson-speech/dist/watson-speech';

class App extends Component {

  constructor() {
    super()
    this.state = {

    }
  }

  onListenClick() {
    fetch('http://localhost:3002/api/speech-to-text/token')
      .then(function(response) {
          return response.text();
      }).then((token) => {
        console.log('token is', token)
        var stream = recognizeMic({
            token: token,
            objectMode: true, // send objects instead of text
            extractResults: true, // convert {results: [{alternatives:[...]}], result_index: 0} to {alternatives: [...], index: 0}
            format: false // optional - performs basic formatting on the results such as capitals an periods
        });
        stream.on('data', (data) => {
          this.setState({
            text: data.alternatives[0].transcript
          })
        });
        stream.on('error', function(err) {
            console.log(err);
        });
        document.querySelector('#stop').onclick = stream.stop.bind(stream);
      }).catch(function(error) {
          console.log(error);
      });
  }
  render() {
    return (
      <div className="App">
        <button onClick={this.onListenClick.bind(this)}>Start</button>
        <div style={{fontSize: '40px'}}>{this.state.text}</div>

      </div>
    );
  }
}

export default App;

当我将流变量更改为此时出现握手错误:

var stream = WatsonSpeech.SpeechToText.recognizeMicrophone(Object.assign(token, {
          objectMode: true, // send objects instead of text
          format: false // optional - performs basic formatting on the results such as capitals an periods
      })

更改为 IamAuthenticator 并使用 API 参考后,我仍然无法在终端中使用它。与此同时,我尝试了谷歌语音到文本,它可以工作:on the left google, on the right ibm。

你能看到我的代码中有什么错误吗?

'use strict';

// Node-Record-lpcm16
const recorder = require('node-record-lpcm16');

const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1');
const { IamAuthenticator } = require('ibm-watson/auth');

const speechToText = new SpeechToTextV1({
  authenticator: new IamAuthenticator({
    apikey: 'knkk_O4nfg_XjW7C9p4DUxlk6p1B9-rez8gJykyh-rYm',
  }),
  url: 'https://api.eu-gb.speech-to-text.watson.cloud.ibm.com/instances/c7572958-6b9c-4215-943f-7ff935bb0037',
});

const params = {
  objectMode: true,
  contentType: 'audio/flac',
  model: 'en-US_BroadbandModel',
  keywords: ['turn on', 'turn off', 'on', 'off'],
  keywordsThreshold: 0.5,
  maxAlternatives: 3,
  headers: 'chunked'
};

// Create the stream.
const recognizeStream = speechToText.recognizeUsingWebSocket(params);

// Listen for events.
recognizeStream.on('data', function(event) { onEvent('Data:', event); });
recognizeStream.on('error', function(event) { onEvent('Error:', event); });
recognizeStream.on('close', function(event) { onEvent('Close:', event); });

// Display events on the console.
function onEvent(name, event) {
    console.log(name, JSON.stringify(event, null, 2));
};

// Start recording and send the microphone input to the Speech API
recorder
.record({
    sampleRateHertz: 16000,
    threshold: 0, //silence threshold
    recordProgram: 'rec', // Try also "arecord" or "sox"
    silence: '5.0', //seconds of silence before ending
})
.stream()
.on('error', console.error)
.pipe(recognizeStream);

【问题讨论】:

    标签: node.js reactjs ibm-watson voice-recognition


    【解决方案1】:

    版本 5 中已删除对令牌参数的支持。请使用 IamAuthenticator。

    查看MIGRATION doc 和API reference 示例

    【讨论】:

    • 谢谢,我已经实现了更改,但仍然有问题,因为我在控制台中没有得到结果,我用新代码编辑了我的帖子,这与之前的代码非常相似我成功使用了 Google API,您可以看看吗?
    • 很抱歉,此更改未能解决整体问题。很遗憾,我无法为您的问题提供更具体的解决方案。顺便说一句,如果这是您发布的真实 API 密钥,您应该删除它并创建另一组凭据。
    【解决方案2】:

    您的代码大部分看起来都不错,因此您应该非常接近使其正常工作。

    您发布的第一个示例看起来应该有一个例外 - 您需要使用 accessToken 参数而不是 token 参数:

    var stream = recognizeMic({
            accessToken: token,
            objectMode: true, // send objects instead of text
            extractResults: true, // convert {results: [{alternatives:[...]}], result_index: 0} to {alternatives: [...], index: 0}
            format: false // optional - performs basic formatting on the results such as capitals an periods
        });
    

    您可以照常使用令牌管理器(尽管最终它会被 Authenticators 弃用)。

    至于您的最后一个示例,服务器端代码,一切看起来都不错。您可能遇到的问题是停止代码永远不会发送到服务器以触发它发送响应。尝试将参数interimResults: true 传递给它。如果您按预期获得数据,那么这就是您的问题。解决此问题的方法是在您的代码中添加一个完成处理程序,如 this example 中所示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      相关资源
      最近更新 更多