如何在cordova应用程序中使用Watson Text2Speech REST API?

时间:2017-02-07 08:25:45

标签: javascript rest cordova ibm-cloud ibm-watson

有很多示例:如何在Node.JS中使用Watson服务,但如果您使用REST API进行HTTP调用,我会遇到授权问题。

API的documentation告诉命令行 curl 界面, 但是,对于网络或混合应用程序使用javascript HTTP调用没有具体示例。

在我的情况下,我想在Cordova Mobile APP中使用Watson Text2Speech,为此我将建立一个工厂。

我使用的http调用适用于其他API,但我在这里做错了什么? 任何遗漏的格式?

有人可以帮忙吗?

看起来像这样:

.factory('GetSpeech', ['$http','$cordovaDialogs','$cordovaMedia','Base64', function($http,
                                                                                    $cordovaDialogs,
                                                                                    $cordovaMedia,
                                                                                    Base64){
  // http://ngcordova.com/docs/plugins/media/
  // https://www.ibm.com/watson/developercloud/doc/speech-to-text/input.shtml
  // https://www.npmjs.com/package/cordova-plugin-speech-recognition-feat-siri
  var watson_url = "https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize";
  var watson_token_url = "https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api";
  var watson_token = "";
  var username='YOUR_KEY';
  var password='YOUR_PW';
  var authdata = 'Basic ' + Base64.encode(username + ':' + password);
  console.log(">>> Watson - authdata: ",authdata);
  var the_get_header = "{'Authorization':'"+ authdata +"','Content-Type':'application/json'}";

  var message = "";

  var getSpeech_innner = function (){ $http({method: 'GET',
                                            url:  watson_token_url,
                                            headers: the_get_header
                                       }).then( function successCallback(response) {
                                           console.log(">>> GetToken  Success:",response);
                                           watson_token=response;
                                           var the_post_header = "{'X-Watson-Authorization-Token':'"+ watson_token +"','Content-Type':'application/json','Accept':'audio/wav'}";
                                           var the_post_text = JSON.stringify({ "text":"This is the first sentence of the paragraph. Here is another sentence. Finally, this is the last sentence."
                                                                              });
                                           $http({
                                              method: 'POST',
                                              url: watson_url,
                                              headers: the_post_header,
                                              data: the_post_text
                                            }).then(function successCallback(response) {
                                                // this callback will be called asynchronously
                                                // when the response is available
                                                console.log(">>> GetSpeech Success:",response);
                                                message = "Success: " + response;
                                                alert(message);
                                                return true;
                                                }, function errorCallback(response) {
                                                  // called asynchronously if an error occurs
                                                  // or server returns response with an error status.
                                                  console.log(">>> GetSpeech  Error:",response);
                                                  message = "Error: " + response;
                                                  alert(message);
                                                  return false;
                                                })
                                            }, function errorCallback(response) {
                                               console.log(">>> GetToken  Error:",response);
                                            });
                                      };
  return {
    getSpeech :  getSpeech_innner
  };

}])

enter image description here

注意:顺便说一下,邮递员会调用HTTP。 GET令牌 POST合成

3 个答案:

答案 0 :(得分:1)

我也尝试过类似的方法:

  $http({
    method: 'POST',
    url: tts_url,
    headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'access-control-allow-headers, Authorization',
          'content-type': 'application/json',
          'Authorization': 'Basic <base64(uid:password)>',
          'Accept': 'audio/wav'
          },
    data: {'\"text\"': '\"hello world\"' },
    output: 'hello_world.wav'
    }).then(function successCallback(response) {
      console.log(">>> Success:",response.status);
    }, function errorCallback(response) {
      console.log(">>> Error:", response.status);
  });

我会收到此错误:

  

阻止跨源请求:同源策略禁止读取   远程资源在   https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize。   (原因:在CORS标头中缺少令牌'access-control-allow-headers'   来自CORS预检频道的“Access-Control-Allow-Headers”。

当我删除“Access-Control-Allow-Headers”标题中的“access-control-allow-headers”条目时,行为是相同的......

在邮递员中运行相同的工作正常。

如何允许我的cordova应用程序呼叫远程资源?

答案 1 :(得分:1)

您是否已将Cordova应用程序中的stream.watsonplatform.net来源列入白名单?在我看来,域名被阻止了。有关白名单的详细信息:https://cordova.apache.org/docs/en/latest/guide/appdev/whitelist/

答案 2 :(得分:1)

我的情况我想直接从服务经纪人获取令牌。

目前情况似乎是与 text2speech服务进行通信,我需要额外的服务器应用,例如在 Node.JS Server上运行< / strong>,为 cordova app 客户端提供令牌

文档中提供了服务器令牌应用的示例代码。

这在使用令牌的主题编程模型一章中有记录。 Watson Documentation Link

这与沃森服务的开发模型有关。 原因是允许Postman和CURL调用,Web或移动应用程序的其他请求不是有效的Origins。

因此,您可以直接从移动应用程序或Web应用程序使用REST API。同样的情况是使用Watson IoT。 这就是我使用Browserify Sample GitHub Project: browserfied-ibmiotf-webapplication

在Angular Web App中使用节点框架的原因

为了更好地理解Watson API文档中的一张图片。 这在使用令牌的主题中的编程模型一章中有记录。 Watson Documentation Link

enter image description here

@Thanks 给Rene和Andrew指出了我的方向。

现在我有一个使用Text2Speech的有效的cordova应用程序。 我不在此示例中使用令牌,语音直接从Node.JS服务器提供给移动应用程序。

@感谢给Andrii,提供一些代码来执行此操作。

Node.JS服务器:

app.get('/getText2SpeechOutput', function (req, res) {
    console.log(' -> text function called');

    console.log('     calling watson to synthesize -> ', req.header('synthesize-text'));

    var text_to_speech_l = new Text2speech({
        username: req.header('service-username'),
        password: req.header('service-password'),
    });

    var params = {
        text: req.header('synthesize-text'),
        voice: 'en-US_AllisonVoice',
        accept: 'audio/wav'
    };

    var tempaudio = text_to_speech_l.synthesize(params);
    console.log('     response received from Watson');
    var reader = new wav.Reader();

    reader.on('format', function (format) {

        console.log('     file read success');
        var writer = new wav.FileWriter('output.wav', {
                channels: 1,
                sampleRate: 22050,
                bitDepth: 16
            });

        reader.pipe(writer);

        console.log('     file write success');

        writer.pipe(res)

        console.log(' <- response provided');
    });

    tempaudio.pipe(reader);
})

Cordova App:

 var getSpeech_innner = function (thetext, callback){
                            //const fileTransfer = new FileTransfer();
                            var headers = {
                              "Authorization": authdata,
                              "Accept": "audio/wav",
                              "synthesize-text": thetext,
                              "service-username": username,
                              "service-password": password
                            };

                            var options = {
                              headers: headers,
                              replace: true
                            };

                            $cordovaFileTransfer.download(get_speech_url , cordova.file.dataDirectory + 'speech.wav', options, true).then(
                              function (FileEntry) {
                                console.debug('>>> Success', FileEntry);
                                var filePath = cordova.file.dataDirectory + 'speech.wav';
                                callback(filePath);
                              },
                              function (error) {
                                console.debug('>>> download failure', error);
                                callback(error);
                              });
                        };