如何在 cordova 应用程序中使用 Watson Text2Speech REST API?
How to use the Watson Text2Speech REST API in a cordova App?
有很多示例:如何在 Node.JS 中使用 Watson 服务,但是如果您将 REST API 与 HTTP 调用一起使用,我 运行 会遇到授权问题。
API的documentation讲述了命令行curl界面,
但是没有针对 Web 或混合应用程序 使用 javascript.
的 HTTP 调用 的具体示例
在我的情况下,我想在 cordova 移动应用程序中使用 Watson Text2Speech,为此我将建立一个工厂。
我使用的 http 调用确实适用于其他 APIs,但是我在这里做错了什么?
缺少格式吗?
有人能帮忙吗?
看起来像这样:
.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
};
}])
注意:顺便说一句,在邮递员中,HTTP 调用工作正常。 GET Token 和 POST 合成.
我试过类似的方法:
$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);
});
我会得到这个错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize.
(Reason: missing token 'access-control-allow-headers' in CORS header
'Access-Control-Allow-Headers' from CORS preflight channel).
行为相同,当我删除 "Access-Control-Allow-Headers" header 中的 "access-control-allow-headers" 条目时...
运行 同样在 postman 中工作正常。
如何让我的 cordova 应用程序调用远程资源?
您是否已在 Cordova 应用程序中将 stream.watsonplatform.net
来源列入白名单?在我看来,域被阻止了。此处有关白名单的详细信息:https://cordova.apache.org/docs/en/latest/guide/appdev/whitelist/
根据我的情况,我想直接从 service broker 获取令牌。
目前看来,为了与text2speech service进行通信,我需要一个额外的server app,例如[= Node.JS Server 上的 74=],它为 cordova app 客户端提供 token .
文档中提供了 服务器令牌应用程序 的示例代码。
这在使用令牌主题的编程模型一章中有记录。
Watson Documentation Link
这与 watson 服务的开发模型有关。
原因是允许 Postman 和 CURL 调用,而 Web 或移动应用程序的其他请求不是有效来源。
因此您可以不直接从移动应用程序或 Web 应用程序使用 REST API。同样的情况,是通过使用 Watson IoT。
这就是我使用 Browserify Sample GitHub Project: browserfied-ibmiotf-webapplication
在 Angular Web 应用程序中使用节点框架的原因
为了更好地理解 Watson API 文档中的一张图片。
这记录在使用令牌主题的编程模型一章中。
Watson Documentation Link
@感谢 Rene 和 Andrew 指出我的方向。
现在我有一个可以使用 Text2Speech 的 cordova 应用程序。
我在这个示例中没有使用 token,语音直接从 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 应用程序:
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);
});
};
有很多示例:如何在 Node.JS 中使用 Watson 服务,但是如果您将 REST API 与 HTTP 调用一起使用,我 运行 会遇到授权问题。
API的documentation讲述了命令行curl界面, 但是没有针对 Web 或混合应用程序 使用 javascript.
的 HTTP 调用 的具体示例在我的情况下,我想在 cordova 移动应用程序中使用 Watson Text2Speech,为此我将建立一个工厂。
我使用的 http 调用确实适用于其他 APIs,但是我在这里做错了什么? 缺少格式吗?
有人能帮忙吗?
看起来像这样:
.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
};
}])
注意:顺便说一句,在邮递员中,HTTP 调用工作正常。 GET Token 和 POST 合成.
我试过类似的方法:
$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);
});
我会得到这个错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
行为相同,当我删除 "Access-Control-Allow-Headers" header 中的 "access-control-allow-headers" 条目时...
运行 同样在 postman 中工作正常。
如何让我的 cordova 应用程序调用远程资源?
您是否已在 Cordova 应用程序中将 stream.watsonplatform.net
来源列入白名单?在我看来,域被阻止了。此处有关白名单的详细信息:https://cordova.apache.org/docs/en/latest/guide/appdev/whitelist/
根据我的情况,我想直接从 service broker 获取令牌。
目前看来,为了与text2speech service进行通信,我需要一个额外的server app,例如[= Node.JS Server 上的 74=],它为 cordova app 客户端提供 token .
文档中提供了 服务器令牌应用程序 的示例代码。
这在使用令牌主题的编程模型一章中有记录。 Watson Documentation Link
这与 watson 服务的开发模型有关。 原因是允许 Postman 和 CURL 调用,而 Web 或移动应用程序的其他请求不是有效来源。
因此您可以不直接从移动应用程序或 Web 应用程序使用 REST API。同样的情况,是通过使用 Watson IoT。 这就是我使用 Browserify Sample GitHub Project: browserfied-ibmiotf-webapplication
在 Angular Web 应用程序中使用节点框架的原因为了更好地理解 Watson API 文档中的一张图片。 这记录在使用令牌主题的编程模型一章中。 Watson Documentation Link
@感谢 Rene 和 Andrew 指出我的方向。
现在我有一个可以使用 Text2Speech 的 cordova 应用程序。 我在这个示例中没有使用 token,语音直接从 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 应用程序:
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);
});
};