全部产品
云市场

RESTful API 2.0

更新时间:2019-07-25 20:03:31

功能介绍

语音合成RESTful API支持HTTPS GET和POST两种方法的请求,将待合成的文本上传到服务端,服务端返回文本的语音合成结果,开发者需要保证在语音合成结果返回之前连接不被中断。

  • 支持设置合成音频的格式:pcm,wav,mp3;
  • 支持设置合成音频的采样率:8000Hz、16000Hz;
  • 支持设置多种发音人;
  • 支持设置语速、语调、音量。

    重要提示

  • 随着TTS合成效果的不断提升,算法的复杂度也越来越高,对用户而言,可能会遇到合成耗时变长的可能。因此我们建议您使用流式合成机制。本文档及SDK附带Demo示例中有相关流式处理示例代码可做参考;
  • 单次调用传入文本不能超过300个字符,否则超过300字符的内容会被截断,只合成300字符以内的内容,对应更长文本的合成,可以参考SDK附带Demo中的长文本切分及拼接示例;
  • 新增RESTful语音合成Java示例代码,增加关于RESTful、Http Chunked、长文本切分分段合成等演示程序;源码下载地址链接

服务地址

访问类型 说明 URL Host
外网访问 所有服务器均可使用外网访问URL https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts nls-gateway.cn-shanghai.aliyuncs.com
阿里云上海ECS内网访问 您使用阿里云上海ECS(即ECS地域为华东2(上海)),可使用内网访问URL http://nls-gateway.cn-shanghai-internal.aliyuncs.com/stream/v1/tts nls-gateway.cn-shanghai-internal.aliyuncs.com

以下将以使用外网访问URL的方式进行介绍。如果您使用的是阿里云上海ECS,并想使用内网访问URL,则要使用HTTP协议,并替换外网访问的URL和Host。以下Demo中除了Python,均直接支持HTTP和HTTPS协议,Python Demo请在使用时阅读其注意事项。

交互流程

客户端向服务端发送带有文本内容的HTTPS GET方法 或 POST方法的请求,服务端返回带有合成语音数据的HTTP响应。

RESTful

说明:服务端的错误响应都会在返回信息中包含task_id参数,用于表示本次合成任务的ID,请记录下这个值,如果发生错误,请将task_id和错误信息提交到工单。

请求参数

语音合成需要设置的请求参数如下表所示。如果使用HTTPS GET方法的请求,需要将这些参数设置到HTTPS的URL请求参数中;如果使用HTTPS POST方法的请求,需要将这些参数设置到HTTPS的请求体(Body)中。

名称 类型 是否必需 描述
appkey String 应用appkey(获取方法请阅读创建项目一节)
text String 待合成的文本,需要为UTF-8编码。使用GET方法,需要再采用RFC 3986规范进行urlencode编码,比如加号 + 编码为 %2B;使用POST方法不需要urlencode编码。
token String 服务鉴权Token,获取方法请阅读获取访问令牌一节。若不设置token参数,需要在HTTP Headers中设置X-NLS-Token字段来指定Token。
format String 音频编码格式,支持的格式:pcm、wav、mp3,默认是pcm
sample_rate Integer 音频采样率,支持16000Hz、8000Hz,默认是16000Hz
voice String 发音人,默认是xiaoyun,其他发音人名称请在简介中选择
volume Integer 音量,范围是0~100,默认50
speech_rate Integer 语速,范围是-500~500,默认是0
pitch_rate Integer 语调,范围是-500~500,可选,默认是0

GET方法上传文本

一个完整的语音合成RESTful API GET方法的请求包含以下要素:

URL

协议 URL 方法
HTTPS https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts GET

请求参数

见上述请求参数表格。

如上URL和请求参数组成的完整请求链接如下所示,在浏览器中打开该链接可直接获取语音合成的结果:

  1. # appkey请填入您的管控台创建的项目appkey,token请填入您的token,在浏览器中打开该链接,可直接获取语音合成结果。
  2. # text的内容为"今天是周一,天气挺好的。"
  3. https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts?appkey=${您的appkey}&token=${您的token}&text=%E4%BB%8A%E5%A4%A9%E6%98%AF%E5%91%A8%E4%B8%80%EF%BC%8C%E5%A4%A9%E6%B0%94%E6%8C%BA%E5%A5%BD%E7%9A%84%E3%80%82&format=wav&sample_rate=16000

HTTPS GET 请求头部

名称 类型 是否必需 描述
X-NLS-Token String 服务鉴权Token,获取方法请阅读获取访问令牌一节。若请求参数中没有设置token参数,则需要在这里设置该字段。

注意:

  • 服务鉴权Token参数既可以在请求参数token中设置,也可以在HTTPS Headers的X-NLS-Token字段设置,推荐使用请求参数token
  • 参数text必须采用UTF-8编码,在采用RFC 3986规范进行urlencode编码,比如加号 + 编码为 %2B,星号 * 编码为 %2A%7E 编码为 ~

POST方法上传文本

一个完整的语音合成RESTful API POST请求包含以下要素:

URL

协议 URL 方法
HTTPS https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts POST

HTTPS POST 请求头部

名称 类型 是否必需 描述
X-NLS-Token String 服务鉴权Token,获取方法请阅读获取访问令牌一节。若Body请求参数中没有设置token参数,则需要在这里设置该字段。
Content-Type String 必须为“application/json”,表明HTTP Body的内容为JSON格式字符串
Content-Length long HTTP Body中内容的长度

HTTPS POST 请求体

HTTPS POST请求体传入的是请求参数组成的JSON格式的字符串,因此在HTTPS POST请求头部中的Content-Type必须设置为”application/json”。示例如下:

  1. {
  2. "appkey":"31f932fb",
  3. "text":"今天是周一,天气挺好的。",
  4. "token":"45034**********3c793",
  5. "format":"wav"
  6. }

注意:

  • 服务鉴权Token参数既可以在Body中的请求参数token中设置,也可以在HTTPS Headers的X-NLS-Token字段设置,推荐使用Body参数token
  • 使用POST方法的请求,Body中的请求参数text必须采用UTF-8编码,但是不进行urlencode编码,注意与GET方法请求的区分。

响应结果

使用HTTPS GET方法和使用HTTPS POST方法请求的响应是相同的,响应的结果都包含在HTTPS的Body中。响应结果的成功或失败通过HTTPS Header的Content-Type字段来区分:

  • 成功响应

    • HTTPS Headers的Content-Type字段内容为audio/mpeg,表示合成成功,合成的语音数据在Body中。
    • HTTPS Header的X-NLS-RequestId字段内容为请求任务的task_id,方便调试排查。
    • Body内容为合成音频的二进制数据。
  • 失败响应

    • HTTPS Headers没有Content-Type字段,或者Content-Type字段内容为application/json,表示合成失败,错误信息在Body中。
    • HTTPS Header的X-NLS-RequestId字段内容为请求任务的task_id,方便调试排查。
    • Body内容为错误信息,JSON格式的字符串。如下所示:
  1. {
  2. "task_id":"8f95d0b9b6e948bc98e8d0ce64b0cf57",
  3. "result":"",
  4. "status":40000000,
  5. "message":"Gateway:CLIENT_ERROR:in post data, json format illegal"
  6. }

响应字段

失败响应时的错误信息字段如下表所示:

名称 类型 描述
task_id String 32位请求任务ID,请记录该值,用于排查错误
result String 服务结果
status Integer 服务状态码
message String 服务状态描述

服务状态码

服务状态码 服务状态描述 解决办法
20000000 请求成功
40000000 默认的客户端错误码 查看错误消息或提交工单
40000001 身份认证失败 检查使用的令牌是否正确,是否过期
40000002 无效的消息 检查发送的消息是否符合要求
40000003 无效的参数 检查参数值设置是否合理
40000004 空闲超时 确认是否长时间没有发送数据掉服务端
40000005 请求数量过多 检查是否超过了并发连接数或者每秒钟请求数
50000000 默认的服务端错误 如果偶现可以忽略,重复出现请提交工单
50000001 内部GRPC调用错误 如果偶现可以忽略,重复出现请提交工单

Java Demo

依赖:

  1. <dependency>
  2. <groupId>com.squareup.okhttp3</groupId>
  3. <artifactId>okhttp</artifactId>
  4. <version>3.9.1</version>
  5. </dependency>
  6. <!-- http://mvnrepository.com/artifact/com.alibaba/fastjson -->
  7. <dependency>
  8. <groupId>com.alibaba</groupId>
  9. <artifactId>fastjson</artifactId>
  10. <version>1.2.42</version>
  11. </dependency>

示例代码:

  1. import java.io.File;
  2. import java.io.FileOutputStream;
  3. import java.io.UnsupportedEncodingException;
  4. import java.net.URLEncoder;
  5. import com.alibaba.fastjson.JSONObject;
  6. import okhttp3.MediaType;
  7. import okhttp3.OkHttpClient;
  8. import okhttp3.Request;
  9. import okhttp3.RequestBody;
  10. import okhttp3.Response;
  11. public class SpeechSynthesizerRestfulDemo {
  12. private String accessToken;
  13. private String appkey;
  14. public SpeechSynthesizerRestfulDemo(String appkey, String token) {
  15. this.appkey = appkey;
  16. this.accessToken = token;
  17. }
  18. /**
  19. * HTTPS GET 请求
  20. */
  21. public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice) {
  22. /**
  23. * 设置HTTPS GET请求
  24. * 1.使用HTTPS协议
  25. * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  26. * 3.语音识别接口请求路径:/stream/v1/tts
  27. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  28. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  29. */
  30. String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  31. url = url + "?appkey=" + appkey;
  32. url = url + "&token=" + accessToken;
  33. url = url + "&text=" + text;
  34. url = url + "&format=" + format;
  35. url = url + "&voice=" + voice;
  36. url = url + "&sample_rate=" + String.valueOf(sampleRate);
  37. // voice 发音人,可选,默认是xiaoyun
  38. // url = url + "&voice=" + "xiaoyun";
  39. // volume 音量,范围是0~100,可选,默认50
  40. // url = url + "&volume=" + String.valueOf(50);
  41. // speech_rate 语速,范围是-500~500,可选,默认是0
  42. // url = url + "&speech_rate=" + String.valueOf(0);
  43. // pitch_rate 语调,范围是-500~500,可选,默认是0
  44. // url = url + "&pitch_rate=" + String.valueOf(0);
  45. System.out.println("URL: " + url);
  46. /**
  47. * 发送HTTPS GET请求,处理服务端的响应
  48. */
  49. Request request = new Request.Builder().url(url).get().build();
  50. try {
  51. long start = System.currentTimeMillis();
  52. OkHttpClient client = new OkHttpClient();
  53. Response response = client.newCall(request).execute();
  54. System.out.println("total latency :" + (System.currentTimeMillis() - start) + " ms");
  55. System.out.println(response.headers().toString());
  56. String contentType = response.header("Content-Type");
  57. if ("audio/mpeg".equals(contentType)) {
  58. File f = new File(audioSaveFile);
  59. FileOutputStream fout = new FileOutputStream(f);
  60. fout.write(response.body().bytes());
  61. fout.close();
  62. System.out.println("The GET request succeed!");
  63. }
  64. else {
  65. // ContentType 为 null 或者为 "application/json"
  66. String errorMessage = response.body().string();
  67. System.out.println("The GET request failed: " + errorMessage);
  68. }
  69. response.close();
  70. } catch (Exception e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. /**
  75. * HTTPS POST 请求
  76. */
  77. public void processPOSTRequest(String text, String audioSaveFile, String format, int sampleRate, String voice) {
  78. /**
  79. * 设置HTTPS POST请求
  80. * 1.使用HTTPS协议
  81. * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  82. * 3.语音合成接口请求路径:/stream/v1/tts
  83. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  84. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  85. */
  86. String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  87. JSONObject taskObject = new JSONObject();
  88. taskObject.put("appkey", appkey);
  89. taskObject.put("token", accessToken);
  90. taskObject.put("text", text);
  91. taskObject.put("format", format);
  92. taskObject.put("voice", voice);
  93. taskObject.put("sample_rate", sampleRate);
  94. // voice 发音人,可选,默认是xiaoyun
  95. // taskObject.put("voice", "xiaoyun");
  96. // volume 音量,范围是0~100,可选,默认50
  97. // taskObject.put("volume", 50);
  98. // speech_rate 语速,范围是-500~500,可选,默认是0
  99. // taskObject.put("speech_rate", 0);
  100. // pitch_rate 语调,范围是-500~500,可选,默认是0
  101. // taskObject.put("pitch_rate", 0);
  102. String bodyContent = taskObject.toJSONString();
  103. System.out.println("POST Body Content: " + bodyContent);
  104. RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
  105. Request request = new Request.Builder()
  106. .url(url)
  107. .header("Content-Type", "application/json")
  108. .post(reqBody)
  109. .build();
  110. try {
  111. OkHttpClient client = new OkHttpClient();
  112. Response response = client.newCall(request).execute();
  113. String contentType = response.header("Content-Type");
  114. if ("audio/mpeg".equals(contentType)) {
  115. File f = new File(audioSaveFile);
  116. FileOutputStream fout = new FileOutputStream(f);
  117. fout.write(response.body().bytes());
  118. fout.close();
  119. System.out.println("The POST request succeed!");
  120. }
  121. else {
  122. // ContentType 为 null 或者为 "application/json"
  123. String errorMessage = response.body().string();
  124. System.out.println("The POST request failed: " + errorMessage);
  125. }
  126. response.close();
  127. } catch (Exception e) {
  128. e.printStackTrace();
  129. }
  130. }
  131. public static void main(String[] args) {
  132. if (args.length < 2) {
  133. System.err.println("SpeechSynthesizerRestfulDemo need params: <token> <app-key>");
  134. System.exit(-1);
  135. }
  136. String token = args[0];
  137. String appkey = args[1];
  138. SpeechSynthesizerRestfulDemo demo = new SpeechSynthesizerRestfulDemo(appkey, token);
  139. String text = "今天是周一,天气挺好的。";
  140. // 采用RFC 3986规范进行urlencode编码
  141. String textUrlEncode = text;
  142. try {
  143. textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
  144. .replace("+", "%20")
  145. .replace("*", "%2A")
  146. .replace("%7E", "~");
  147. } catch (UnsupportedEncodingException e) {
  148. e.printStackTrace();
  149. }
  150. System.out.println(textUrlEncode);
  151. String audioSaveFile = "syAudio.wav";
  152. String format = "wav";
  153. int sampleRate = 16000;
  154. demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "siyue");
  155. //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate, "siyue");
  156. System.out.println("### Game Over ###");
  157. }
  158. }

Java Demo-流式合成

  1. import java.io.File;
  2. import java.io.FileOutputStream;
  3. import java.io.UnsupportedEncodingException;
  4. import java.net.URLEncoder;
  5. import java.util.concurrent.CountDownLatch;
  6. import io.netty.handler.codec.http.HttpHeaders;
  7. import org.asynchttpclient.AsyncHandler;
  8. import org.asynchttpclient.AsyncHttpClient;
  9. import org.asynchttpclient.AsyncHttpClientConfig;
  10. import org.asynchttpclient.DefaultAsyncHttpClient;
  11. import org.asynchttpclient.DefaultAsyncHttpClientConfig;
  12. import org.asynchttpclient.HttpResponseBodyPart;
  13. import org.asynchttpclient.HttpResponseStatus;
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16. /**
  17. * 此示例演示了
  18. * 1. TTS的RESTFul接口调用
  19. * 2. 启用http chunked机制的处理方式(流式返回)
  20. */
  21. public class SpeechSynthesizerRestfulChunkedDemo {
  22. private static Logger logger = LoggerFactory.getLogger(SpeechSynthesizerRestfulChunkedDemo.class);
  23. private String accessToken;
  24. private String appkey;
  25. public SpeechSynthesizerRestfulChunkedDemo(String appkey, String token) {
  26. this.appkey = appkey;
  27. this.accessToken = token;
  28. }
  29. public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice, boolean chunked) {
  30. /**
  31. * 设置HTTPS GET请求
  32. * 1.使用HTTPS协议
  33. * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  34. * 3.语音识别接口请求路径:/stream/v1/tts
  35. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  36. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  37. * 6.设置参数chunk,启用http流式返回
  38. */
  39. String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  40. url = url + "?appkey=" + appkey;
  41. url = url + "&token=" + accessToken;
  42. url = url + "&text=" + text;
  43. url = url + "&format=" + format;
  44. url = url + "&voice=" + voice;
  45. url = url + "&sample_rate=" + String.valueOf(sampleRate);
  46. url = url + "&chunk=" + String.valueOf(chunked);
  47. System.out.println("URL: " + url);
  48. try {
  49. AsyncHttpClientConfig config = new DefaultAsyncHttpClientConfig.Builder()
  50. .setConnectTimeout(3000)
  51. .setKeepAlive(true)
  52. .setReadTimeout(10000)
  53. .setRequestTimeout(50000)
  54. .setMaxConnections(1000)
  55. .setMaxConnectionsPerHost(200)
  56. .setPooledConnectionIdleTimeout(-1)
  57. .build();
  58. AsyncHttpClient httpClient = new DefaultAsyncHttpClient(config);
  59. CountDownLatch latch = new CountDownLatch(1);
  60. AsyncHandler<org.asynchttpclient.Response> handler = new AsyncHandler<org.asynchttpclient.Response>() {
  61. FileOutputStream outs;
  62. boolean firstRecvBinary = true;
  63. long startTime = System.currentTimeMillis();
  64. int httpCode = 200;
  65. @Override
  66. public State onStatusReceived(HttpResponseStatus httpResponseStatus) throws Exception {
  67. logger.info("onStatusReceived status {}", httpResponseStatus);
  68. httpCode = httpResponseStatus.getStatusCode();
  69. if (httpResponseStatus.getStatusCode() != 200) {
  70. logger.error("request error " + httpResponseStatus.toString());
  71. }
  72. return null;
  73. }
  74. @Override
  75. public State onHeadersReceived(HttpHeaders httpHeaders) throws Exception {
  76. outs = new FileOutputStream(new File("tts.wav"));
  77. return null;
  78. }
  79. @Override
  80. public State onBodyPartReceived(HttpResponseBodyPart httpResponseBodyPart) throws Exception {
  81. // TODO 重要提示:此处一旦接收到数据流,即可向用户播放或者用于其他处理,以提升响应速度
  82. // TODO 重要提示:请不要在此回调接口中执行耗时操作,可以以异步或者队列形式将二进制TTS语音流推送到另一线程中
  83. logger.info("onBodyPartReceived " + httpResponseBodyPart.getBodyPartBytes().toString());
  84. if(httpCode != 200) {
  85. System.err.write(httpResponseBodyPart.getBodyPartBytes());
  86. }
  87. if (firstRecvBinary) {
  88. firstRecvBinary = false;
  89. // TODO 统计第一包数据的接收延迟,实际上接收到第一包数据后就可以进行业务处理了,比如播放或者发送给调用方,注意:这里的首包延迟也包括了网络建立链接的时间
  90. logger.info("tts first latency " + (System.currentTimeMillis() - startTime) + " ms");
  91. }
  92. // TODO 重要提示:此处仅为举例,将语音流保存到文件中
  93. outs.write(httpResponseBodyPart.getBodyPartBytes());
  94. return null;
  95. }
  96. @Override
  97. public void onThrowable(Throwable throwable) {
  98. logger.error("throwable {}", throwable);
  99. latch.countDown();
  100. }
  101. @Override
  102. public org.asynchttpclient.Response onCompleted() throws Exception {
  103. logger.info("completed");
  104. logger.info("tts total latency " + (System.currentTimeMillis() - startTime) + " ms");
  105. outs.close();
  106. latch.countDown();
  107. return null;
  108. }
  109. };
  110. httpClient.prepareGet(url).execute(handler);
  111. // 等待合成完成
  112. latch.await();
  113. httpClient.close();
  114. }catch (Exception e) {
  115. }
  116. }
  117. public static void main(String[] args) {
  118. if (args.length < 2) {
  119. System.err.println("SpeechSynthesizerRestfulDemo need params: <token> <app-key>");
  120. System.exit(-1);
  121. }
  122. String token = args[0];
  123. String appkey = args[1];
  124. SpeechSynthesizerRestfulChunkedDemo demo = new SpeechSynthesizerRestfulChunkedDemo(appkey, token);
  125. String text = "我家的后面有一个很大的园,相传叫作百草园。现在是早已并屋子一起卖给朱文公的子孙了,连那最末次的相见也已经隔了七八年,其中似乎确凿只有一些野草;但那时却是我的乐园。";
  126. // 采用RFC 3986规范进行urlencode编码
  127. String textUrlEncode = text;
  128. try {
  129. textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
  130. .replace("+", "%20")
  131. .replace("*", "%2A")
  132. .replace("%7E", "~");
  133. } catch (UnsupportedEncodingException e) {
  134. e.printStackTrace();
  135. }
  136. System.out.println(textUrlEncode);
  137. String audioSaveFile = "syAudio.wav";
  138. String format = "wav";
  139. int sampleRate = 16000;
  140. // TODO 说明 最后一个参数为true表示使用http chunked机制
  141. demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "aixia", true);
  142. System.out.println("### Game Over ###");
  143. }
  144. }

C++ Demo

C++ Demo使用了第三方函数库curl处理HTTPS的请求和响应,使用jsoncpp处理POST请求Body内容JSON格式字符串的设置。Demo下载链接。

目录说明:

  • CMakeLists.txt demo工程的CMakeList文件
  • demo
文件名 描述
restfulTtsDemo.cpp 语音合成RESTful API Demo
  • include
目录名 描述
curl curl库头文件目录
json jsoncpp库头文件目录
  • lib包含curl、jsoncpp动态库。根据平台不同,可以选择linux版本(glibc:2.5及以上, Gcc4, Gcc5)、windows版本(VS2013、VS2015)。
  • readme.txt 说明
  • release.log 更新记录
  • version 版本号
  • build.sh demo编译脚本

注意:

  1. Linux环境下,运行环境最低要求:Glibc 2.5及以上, Gcc4、Gcc5。
  2. token值有效期默认24小时,超时请重新获取,否则会导致请求识别。
  3. Windows下需要您自己搭建demo工程。

运行编译:

  1. 1. 请确认本地系统以安装Cmake,最低版本2.4
  2. 2. cd path/to/sdk/lib
  3. 3. tar -zxvpf linux.tar.gz
  4. 4. cd path/to/sdk
  5. 5. 执行[./build.sh]编译demo
  6. 6. 编译完毕,进入demo目录,执行[./restfulTtsDemo <your-token> <your-appkey>]
  7. 如果不支持cmake,可以尝试手动编译:
  8. 1: cd path/to/sdk/lib
  9. 2: tar -zxvpf linux.tar.gz
  10. 3: cd path/to/sdk/demo
  11. 4: g++ -o restfulTtsDemo restfulTtsDemo.cpp -I path/to/sdk/include -L path/to/sdk/lib/linux -ljsoncpp -lssl -lcrypto -lcurl -D_GLIBCXX_USE_CXX11_ABI=0
  12. 5: export LD_LIBRARY_PATH=path/to/sdk/lib/linux/
  13. 6: ./restfulTtsDemo your-token your-appkey
  14. Windows平台需要您自己搭建工程。

示例代码:

  1. #ifdef _WIN32
  2. #include <Windows.h>
  3. #endif
  4. #include <iostream>
  5. #include <string>
  6. #include <map>
  7. #include <fstream>
  8. #include <sstream>
  9. #include "curl/curl.h"
  10. #include "json/json.h"
  11. using namespace std;
  12. #ifdef _WIN32
  13. string GBKToUTF8(const string &strGBK) {
  14. string strOutUTF8 = "";
  15. WCHAR * str1;
  16. int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
  17. str1 = new WCHAR[n];
  18. MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
  19. n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
  20. char * str2 = new char[n];
  21. WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
  22. strOutUTF8 = str2;
  23. delete[] str1;
  24. str1 = NULL;
  25. delete[] str2;
  26. str2 = NULL;
  27. return strOutUTF8;
  28. }
  29. #endif
  30. void stringReplace(string& src, const string& s1, const string& s2) {
  31. string::size_type pos = 0;
  32. while ((pos = src.find(s1, pos)) != string::npos) {
  33. src.replace(pos, s1.length(), s2);
  34. pos += s2.length();
  35. }
  36. }
  37. string urlEncode(const string& src) {
  38. CURL* curl = curl_easy_init();
  39. char* output = curl_easy_escape(curl, src.c_str(), src.size());
  40. string result(output);
  41. curl_free(output);
  42. curl_easy_cleanup(curl);
  43. return result;
  44. }
  45. size_t responseHeadersCallback(void* ptr, size_t size, size_t nmemb, void* userdata)
  46. {
  47. map<string, string> *headers = (map<string, string>*)userdata;
  48. string line((char*)ptr);
  49. string::size_type pos = line.find(':');
  50. if (pos != line.npos)
  51. {
  52. string name = line.substr(0, pos);
  53. string value = line.substr(pos + 2);
  54. size_t p = 0;
  55. if ((p = value.rfind('\r')) != value.npos) {
  56. value = value.substr(0, p);
  57. }
  58. headers->insert(make_pair(name, value));
  59. }
  60. return size * nmemb;
  61. }
  62. size_t responseBodyCallback(void* ptr, size_t size, size_t nmemb, void* userData) {
  63. size_t len = size * nmemb;
  64. char* pBuf = (char*)ptr;
  65. string* bodyContent = (string*)userData;
  66. (*bodyContent).append(string(pBuf, pBuf + len));
  67. return len;
  68. }
  69. int processGETRequest(string appKey, string token, string text,
  70. string audioSaveFile, string format, int sampleRate) {
  71. CURL* curl = NULL;
  72. CURLcode res;
  73. curl = curl_easy_init();
  74. if (curl == NULL) {
  75. return -1;
  76. }
  77. string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  78. /**
  79. * 设置HTTPS URL请求参数
  80. */
  81. ostringstream oss;
  82. oss << url;
  83. oss << "?appkey=" << appKey;
  84. oss << "&token=" << token;
  85. oss << "&text=" << text;
  86. oss << "&format=" << format;
  87. oss << "&sample_rate=" << sampleRate;
  88. // voice 发音人,可选,默认是xiaoyun
  89. // oss << "&voice=" << "xiaoyun";
  90. // volume 音量,范围是0~100,可选,默认50
  91. // oss << "&volume=" << 50;
  92. // speech_rate 语速,范围是-500~500,可选,默认是0
  93. // oss << "&speech_rate=" << 0;
  94. // pitch_rate 语调,范围是-500~500,可选,默认是0
  95. // oss << "&pitch_rate=" << 0;
  96. string request = oss.str();
  97. cout << request << endl;
  98. curl_easy_setopt(curl, CURLOPT_URL, request.c_str());
  99. /**
  100. * 设置获取响应的HTTPS Headers回调函数
  101. */
  102. map<string, string> responseHeaders;
  103. curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
  104. curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
  105. /**
  106. * 设置获取响应的HTTPS Body回调函数
  107. */
  108. string bodyContent = "";
  109. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
  110. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
  111. /**
  112. * 发送HTTPS GET请求
  113. */
  114. res = curl_easy_perform(curl);
  115. /**
  116. * 释放资源
  117. */
  118. curl_easy_cleanup(curl);
  119. if (res != CURLE_OK) {
  120. cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
  121. return -1;
  122. }
  123. /**
  124. * 处理服务端返回的响应
  125. */
  126. map<string, string>::iterator it = responseHeaders.find("Content-Type");
  127. if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
  128. ofstream fs;
  129. fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
  130. if (!fs.is_open()) {
  131. cout << "The audio save file can not open!";
  132. return -1;
  133. }
  134. fs.write(bodyContent.c_str(), bodyContent.size());
  135. fs.close();
  136. cout << "The GET request succeed!" << endl;
  137. }
  138. else {
  139. cout << "The GET request failed: " + bodyContent << endl;
  140. return -1;
  141. }
  142. return 0;
  143. }
  144. int processPOSTRequest(string appKey, string token, string text,
  145. string audioSaveFile, string format, int sampleRate) {
  146. CURL* curl = NULL;
  147. CURLcode res;
  148. curl = curl_easy_init();
  149. if (curl == NULL) {
  150. return -1;
  151. }
  152. string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  153. /**
  154. * 设置HTTPS POST URL
  155. */
  156. curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  157. curl_easy_setopt(curl, CURLOPT_POST, 1L);
  158. /**
  159. * 设置HTTPS POST请求头部
  160. */
  161. struct curl_slist* headers = NULL;
  162. // Content-Type
  163. headers = curl_slist_append(headers, "Content-Type:application/json");
  164. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  165. /**
  166. * 设置HTTPS POST请求体
  167. */
  168. Json::Value root;
  169. Json::FastWriter writer;
  170. root["appkey"] = appKey;
  171. root["token"] = token;
  172. root["text"] = text;
  173. root["format"] = format;
  174. root["sample_rate"] = sampleRate;
  175. // voice 发音人,可选,默认是xiaoyun
  176. // root["voice"] = "xiaoyun";
  177. // volume 音量,范围是0~100,可选,默认50
  178. // root["volume"] = 50;
  179. // speech_rate 语速,范围是-500~500,可选,默认是0
  180. // root["speech_rate"] = 0;
  181. // pitch_rate 语调,范围是-500~500,可选,默认是0
  182. // root["pitch_rate"] = 0;
  183. string task = writer.write(root);
  184. cout << "POST request Body: " << task << endl;
  185. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, task.c_str());
  186. curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, task.length());
  187. /**
  188. * 设置获取响应的HTTPS Headers回调函数
  189. */
  190. map<string, string> responseHeaders;
  191. curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
  192. curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
  193. /**
  194. * 设置获取响应的HTTPS Body回调函数
  195. */
  196. string bodyContent = "";
  197. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
  198. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
  199. /**
  200. * 发送HTTPS POST请求
  201. */
  202. res = curl_easy_perform(curl);
  203. /**
  204. * 释放资源
  205. */
  206. curl_slist_free_all(headers);
  207. curl_easy_cleanup(curl);
  208. if (res != CURLE_OK) {
  209. cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
  210. return -1;
  211. }
  212. /**
  213. * 处理服务端返回的响应
  214. */
  215. map<string, string>::iterator it = responseHeaders.find("Content-Type");
  216. if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
  217. ofstream fs;
  218. fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
  219. if (!fs.is_open()) {
  220. cout << "The audio save file can not open!";
  221. return -1;
  222. }
  223. fs.write(bodyContent.c_str(), bodyContent.size());
  224. fs.close();
  225. cout << "The POST request succeed!" << endl;
  226. }
  227. else {
  228. cout << "The POST request failed: " + bodyContent << endl;
  229. return -1;
  230. }
  231. return 0;
  232. }
  233. int main(int argc, char* argv[]) {
  234. if (argc < 3) {
  235. cerr << "params is not valid. Usage: ./demo your_token your_appkey" << endl;
  236. return -1;
  237. }
  238. string token = argv[1];
  239. string appKey = argv[2];
  240. string text = "今天是周一,天气挺好的。";
  241. #ifdef _WIN32
  242. text = GBKToUTF8(text);
  243. #endif
  244. string textUrlEncode = urlEncode(text);
  245. stringReplace(textUrlEncode, "+", "%20");
  246. stringReplace(textUrlEncode, "*", "%2A");
  247. stringReplace(textUrlEncode, "%7E", "~");
  248. string audioSaveFile = "syAudio.wav";
  249. string format = "wav";
  250. int sampleRate = 16000;
  251. // 全局只初始化一次
  252. curl_global_init(CURL_GLOBAL_ALL);
  253. processGETRequest(appKey, token, textUrlEncode, audioSaveFile, format, sampleRate);
  254. //processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate);
  255. curl_global_cleanup();
  256. return 0;
  257. }

Python Demo

注意:

  1. Python 2.x请使用httplib模块;Python 3.x请使用http.client模块。
  2. 采用RFC 3986规范进行urlencode编码,Python 2.x请使用urllib模块的urllib.quote,Python 3.x请使用urllib.parse模块的urllib.parse.quote_plus。
  3. 如果使用内网访问URL,使用HTTP协议,需要替换如下函数,即将HTTPSConnection修改为HTTPConnection :

    1. # Python 2.x 请使用httplib
    2. # conn = httplib.HTTPConnection(host)
    3. # Python 3.x 请使用http.client
    4. conn = http.client.HTTPConnection(host)

示例:

  1. # -*- coding: UTF-8 -*-
  2. # Python 2.x 引入httplib模块
  3. # import httplib
  4. # Python 3.x 引入http.client模块
  5. import http.client
  6. # Python 2.x 引入urllib模块
  7. # import urllib
  8. # Python 3.x 引入urllib.parse模块
  9. import urllib.parse
  10. import json
  11. def processGETRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
  12. host = 'nls-gateway.cn-shanghai.aliyuncs.com'
  13. url = 'https://' + host + '/stream/v1/tts'
  14. # 设置URL请求参数
  15. url = url + '?appkey=' + appKey
  16. url = url + '&token=' + token
  17. url = url + '&text=' + text
  18. url = url + '&format=' + format
  19. url = url + '&sample_rate=' + str(sampleRate)
  20. # voice 发音人,可选,默认是xiaoyun
  21. # url = url + '&voice=' + 'xiaoyun'
  22. # volume 音量,范围是0~100,可选,默认50
  23. # url = url + '&volume=' + str(50)
  24. # speech_rate 语速,范围是-500~500,可选,默认是0
  25. # url = url + '&speech_rate=' + str(0)
  26. # pitch_rate 语调,范围是-500~500,可选,默认是0
  27. # url = url + '&pitch_rate=' + str(0)
  28. print(url)
  29. # Python 2.x 请使用httplib
  30. # conn = httplib.HTTPSConnection(host)
  31. # Python 3.x 请使用http.client
  32. conn = http.client.HTTPSConnection(host)
  33. conn.request(method='GET', url=url)
  34. # 处理服务端返回的响应
  35. response = conn.getresponse()
  36. print('Response status and response reason:')
  37. print(response.status ,response.reason)
  38. contentType = response.getheader('Content-Type')
  39. print(contentType)
  40. body = response.read()
  41. if 'audio/mpeg' == contentType :
  42. with open(audioSaveFile, mode='wb') as f:
  43. f.write(body)
  44. print('The GET request succeed!')
  45. else :
  46. print('The GET request failed: ' + str(body))
  47. conn.close()
  48. def processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
  49. host = 'nls-gateway.cn-shanghai.aliyuncs.com'
  50. url = 'https://' + host + '/stream/v1/tts'
  51. # 设置HTTPS Headers
  52. httpHeaders = {
  53. 'Content-Type': 'application/json'
  54. }
  55. # 设置HTTPS Body
  56. body = {'appkey': appKey, 'token': token, 'text': text, 'format': format, 'sample_rate': sampleRate}
  57. body = json.dumps(body)
  58. print('The POST request body content: ' + body)
  59. # Python 2.x 请使用httplib
  60. # conn = httplib.HTTPSConnection(host)
  61. # Python 3.x 请使用http.client
  62. conn = http.client.HTTPSConnection(host)
  63. conn.request(method='POST', url=url, body=body, headers=httpHeaders)
  64. # 处理服务端返回的响应
  65. response = conn.getresponse()
  66. print('Response status and response reason:')
  67. print(response.status ,response.reason)
  68. contentType = response.getheader('Content-Type')
  69. print(contentType)
  70. body = response.read()
  71. if 'audio/mpeg' == contentType :
  72. with open(audioSaveFile, mode='wb') as f:
  73. f.write(body)
  74. print('The POST request succeed!')
  75. else :
  76. print('The POST request failed: ' + str(body))
  77. conn.close()
  78. appKey = '您的appkey'
  79. token = '您的token'
  80. text = '今天是周一,天气挺好的。'
  81. # 采用RFC 3986规范进行urlencode编码
  82. textUrlencode = text
  83. # Python 2.x请使用 urllib.quote
  84. # textUrlencode = urllib.quote(textUrlencode, '')
  85. # Python 3.x请使用urllib.parse.quote_plus
  86. textUrlencode = urllib.parse.quote_plus(textUrlencode)
  87. textUrlencode = textUrlencode.replace("+", "%20")
  88. textUrlencode = textUrlencode.replace("*", "%2A")
  89. textUrlencode = textUrlencode.replace("%7E", "~")
  90. print('text: ' + textUrlencode)
  91. audioSaveFile = 'syAudio.wav'
  92. format = 'wav'
  93. sampleRate = 16000
  94. # GET 请求方式
  95. processGETRequest(appKey, token, textUrlencode, audioSaveFile, format, sampleRate)
  96. # POST 请求方式
  97. # processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate)

PHP Demo

说明:PHP Demo中使用了cURL函数,要求PHP的版本在4.0.2以上,并且确保安装了cURL扩展。

  1. <?php
  2. function processGETRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
  3. $url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  4. $url = $url . "?appkey=" . $appkey;
  5. $url = $url . "&token=" . $token;
  6. $url = $url . "&text=" . $text;
  7. $url = $url . "&format=" . $format;
  8. $url = $url . "&sample_rate=" . strval($sampleRate);
  9. // voice 发音人,可选,默认是xiaoyun
  10. // $url = $url . "&voice=" . "xiaoyun";
  11. // volume 音量,范围是0~100,可选,默认50
  12. // $url = $url . "&volume=" . strval(50);
  13. // speech_rate 语速,范围是-500~500,可选,默认是0
  14. // $url = $url . "&speech_rate=" . strval(0);
  15. // pitch_rate 语调,范围是-500~500,可选,默认是0
  16. // $url = $url . "&pitch_rate=" . strval(0);
  17. print $url . "\n";
  18. $curl = curl_init();
  19. curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  20. /**
  21. * 设置HTTPS GET URL
  22. */
  23. curl_setopt($curl, CURLOPT_URL, $url);
  24. /**
  25. * 设置返回的响应包含HTTPS头部信息
  26. */
  27. curl_setopt($curl, CURLOPT_HEADER, TRUE);
  28. /**
  29. * 发送HTTPS GET请求
  30. */
  31. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  32. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  33. $response = curl_exec($curl);
  34. if ($response == FALSE) {
  35. print "curl_exec failed!\n";
  36. curl_close($curl);
  37. return ;
  38. }
  39. /**
  40. * 处理服务端返回的响应
  41. */
  42. $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
  43. $headers = substr($response, 0, $headerSize);
  44. $bodyContent = substr($response, $headerSize);
  45. curl_close($curl);
  46. if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
  47. file_put_contents($audioSaveFile, $bodyContent);
  48. print "The GET request succeed!\n";
  49. }
  50. else {
  51. print "The GET request failed: " . $bodyContent . "\n";
  52. }
  53. }
  54. function processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
  55. $url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  56. /**
  57. * 请求参数,以JSON格式字符串填入HTTPS POST请求的Body中
  58. */
  59. $taskArr = array(
  60. "appkey" => $appkey,
  61. "token" => $token,
  62. "text" => $text,
  63. "format" => $format,
  64. "sample_rate" => $sampleRate
  65. // voice 发音人,可选,默认是xiaoyun
  66. // "voice" => "xiaoyun",
  67. // volume 音量,范围是0~100,可选,默认50
  68. // "volume" => 50,
  69. // speech_rate 语速,范围是-500~500,可选,默认是0
  70. // "speech_rate" => 0,
  71. // pitch_rate 语调,范围是-500~500,可选,默认是0
  72. // "pitch_rate" => 0
  73. );
  74. $body = json_encode($taskArr);
  75. print "The POST request body content: " . $body . "\n";
  76. $curl = curl_init();
  77. curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  78. /**
  79. * 设置HTTPS POST URL
  80. */
  81. curl_setopt($curl, CURLOPT_URL, $url);
  82. curl_setopt($curl, CURLOPT_POST, TRUE);
  83. /**
  84. * 设置HTTPS POST请求头部
  85. * */
  86. $httpHeaders = array(
  87. "Content-Type: application/json"
  88. );
  89. curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
  90. /**
  91. * 设置HTTPS POST请求体
  92. */
  93. curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
  94. /**
  95. * 设置返回的响应包含HTTPS头部信息
  96. */
  97. curl_setopt($curl, CURLOPT_HEADER, TRUE);
  98. /**
  99. * 发送HTTPS POST请求
  100. */
  101. $response = curl_exec($curl);
  102. if ($response == FALSE) {
  103. print "curl_exec failed!\n";
  104. curl_close($curl);
  105. return ;
  106. }
  107. /**
  108. * 处理服务端返回的响应
  109. */
  110. $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
  111. $headers = substr($response, 0, $headerSize);
  112. $bodyContent = substr($response, $headerSize);
  113. curl_close($curl);
  114. if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
  115. file_put_contents($audioSaveFile, $bodyContent);
  116. print "The POST request succeed!\n";
  117. }
  118. else {
  119. print "The POST request failed: " . $bodyContent . "\n";
  120. }
  121. }
  122. $appkey = "您的appkey";
  123. $token = "您的token";
  124. $text = "今天是周一,天气挺好的。";
  125. $textUrlEncode = urlencode($text);
  126. $textUrlEncode = preg_replace('/\+/', '%20', $textUrlEncode);
  127. $textUrlEncode = preg_replace('/\*/', '%2A', $textUrlEncode);
  128. $textUrlEncode = preg_replace('/%7E/', '~', $textUrlEncode);
  129. $audioSaveFile = "syAudio.wav";
  130. $format = "wav";
  131. $sampleRate = 16000;
  132. processGETRequest($appkey, $token, $textUrlEncode, $audioSaveFile, $format, $sampleRate);
  133. // processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate);
  134. ?>

Node.js Demo

说明:request依赖安装,请在您的Demo文件所在目录执行如下命令:

  1. npm install request --save

示例代码:

  1. const request = require('request');
  2. const fs = require('fs');
  3. function processGETRequest(appkey, token, text, audioSaveFile, format, sampleRate) {
  4. var url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts';
  5. /**
  6. * 设置URL请求参数
  7. */
  8. url = url + '?appkey=' + appkey;
  9. url = url + '&token=' + token;
  10. url = url + '&text=' + text;
  11. url = url + '&format=' + format;
  12. url = url + '&sample_rate=' + sampleRate;
  13. // voice 发音人,可选,默认是xiaoyun
  14. // url = url + "&voice=" + "xiaoyun";
  15. // volume 音量,范围是0~100,可选,默认50
  16. // url = url + "&volume=" + 50;
  17. // speech_rate 语速,范围是-500~500,可选,默认是0
  18. // url = url + "&speech_rate=" + 0;
  19. // pitch_rate 语调,范围是-500~500,可选,默认是0
  20. // url = url + "&pitch_rate=" + 0;
  21. console.log(url);
  22. /**
  23. * 设置HTTPS GET请求
  24. * encoding必须设置为null,HTTPS响应的Body为二进制Buffer类型
  25. */
  26. var options = {
  27. url: url,
  28. method: 'GET',
  29. encoding: null
  30. };
  31. request(options, function (error, response, body) {
  32. /**
  33. * 处理服务端的响应
  34. */
  35. if (error != null) {
  36. console.log(error);
  37. }
  38. else {
  39. var contentType = response.headers['content-type'];
  40. if (contentType === undefined || contentType != 'audio/mpeg') {
  41. console.log(body.toString());
  42. console.log('The GET request failed!');
  43. }
  44. else {
  45. fs.writeFileSync(audioSaveFile, body);
  46. console.log('The GET request is succeed!');
  47. }
  48. }
  49. });
  50. }
  51. function processPOSTRequest(appkeyValue, tokenValue, textValue, audioSaveFile, formatValue, sampleRateValue) {
  52. var url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts';
  53. /**
  54. * 请求参数,以JSON格式字符串填入HTTPS POST 请求的Body中
  55. */
  56. var task = {
  57. appkey : appkeyValue,
  58. token : tokenValue,
  59. text : textValue,
  60. format : formatValue,
  61. sample_rate : sampleRateValue
  62. // voice 发音人,可选,默认是xiaoyun
  63. // voice : 'xiaoyun',
  64. // volume 音量,范围是0~100,可选,默认50
  65. // volume : 50,
  66. // speech_rate 语速,范围是-500~500,可选,默认是0
  67. // speech_rate : 0,
  68. // pitch_rate 语调,范围是-500~500,可选,默认是0
  69. // pitch_rate : 0
  70. };
  71. var bodyContent = JSON.stringify(task);
  72. console.log('The POST request body content: ' + bodyContent);
  73. /**
  74. * 设置HTTPS POST请求头部
  75. */
  76. var httpHeaders = {
  77. 'Content-type' : 'application/json'
  78. }
  79. /**
  80. * 设置HTTPS POST请求
  81. * encoding必须设置为null,HTTPS响应的Body为二进制Buffer类型
  82. */
  83. var options = {
  84. url: url,
  85. method: 'POST',
  86. headers: httpHeaders,
  87. body: bodyContent,
  88. encoding: null
  89. };
  90. request(options, function (error, response, body) {
  91. /**
  92. * 处理服务端的响应
  93. */
  94. if (error != null) {
  95. console.log(error);
  96. }
  97. else {
  98. var contentType = response.headers['content-type'];
  99. if (contentType === undefined || contentType != 'audio/mpeg') {
  100. console.log(body.toString());
  101. console.log('The POST request failed!');
  102. }
  103. else {
  104. fs.writeFileSync(audioSaveFile, body);
  105. console.log('The POST request is succeed!');
  106. }
  107. }
  108. });
  109. }
  110. var appkey = '您的appkey';
  111. var token = '您的token';
  112. var text = '今天是周一,天气挺好的。';
  113. var textUrlEncode = encodeURIComponent(text)
  114. .replace(/[!'()*]/g, function(c) {
  115. return '%' + c.charCodeAt(0).toString(16);
  116. });
  117. console.log(textUrlEncode);
  118. var audioSaveFile = 'syAudio.wav';
  119. var format = 'wav';
  120. var sampleRate = 16000;
  121. processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate);
  122. // processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate);

.Net Demo

说明: Demo中依赖了System.Net.Http、System.Web、Newtonsoft.Json.Linq。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Net.Http;
  7. using System.Web;
  8. using Newtonsoft.Json.Linq;
  9. namespace RESTfulAPI
  10. {
  11. class SpeechSynthesizerRESTfulDemo
  12. {
  13. private string appkey;
  14. private string token;
  15. public SpeechSynthesizerRESTfulDemo(string appkey, string token)
  16. {
  17. this.appkey = appkey;
  18. this.token = token;
  19. }
  20. public void processGETRequest(string text, string audioSaveFile, string format, int sampleRate)
  21. {
  22. /**
  23. * 设置HTTPS GET请求
  24. * 1.使用HTTPS协议
  25. * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  26. * 3.语音识别接口请求路径:/stream/v1/tts
  27. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  28. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  29. */
  30. string url = "http://nls-gateway.aliyuncs.com/stream/v1/tts";
  31. url = url + "?appkey=" + appkey;
  32. url = url + "&token=" + token;
  33. url = url + "&text=" + text;
  34. url = url + "&format=" + format;
  35. url = url + "&sample_rate=" + sampleRate.ToString();
  36. // voice 发音人,可选,默认是xiaoyun
  37. // url = url + "&voice=" + "xiaoyun";
  38. // volume 音量,范围是0~100,可选,默认50
  39. // url = url + "&volume=" + 50;
  40. // speech_rate 语速,范围是-500~500,可选,默认是0
  41. // url = url + "&speech_rate=" + 0;
  42. // pitch_rate 语调,范围是-500~500,可选,默认是0
  43. // url = url + "&pitch_rate=" + 0;
  44. System.Console.WriteLine(url);
  45. /**
  46. * 发送HTTPS GET请求,处理服务端的响应
  47. */
  48. HttpClient client = new HttpClient();
  49. HttpResponseMessage response = null;
  50. response = client.GetAsync(url).Result;
  51. string contentType = null;
  52. if (response.IsSuccessStatusCode)
  53. {
  54. string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
  55. if (typesArray.Length > 0)
  56. {
  57. contentType = typesArray.First();
  58. }
  59. }
  60. if ("audio/mpeg".Equals(contentType))
  61. {
  62. byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
  63. FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
  64. fs.Write(audioBuff, 0, audioBuff.Length);
  65. fs.Flush();
  66. fs.Close();
  67. System.Console.WriteLine("The GET request succeed!");
  68. }
  69. else
  70. {
  71. // ContentType 为 null 或者为 "application/json"
  72. System.Console.WriteLine("Response status code and reason phrase: " +
  73. response.StatusCode + " " + response.ReasonPhrase);
  74. string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
  75. System.Console.WriteLine("The GET request failed: " + responseBodyAsText);
  76. }
  77. }
  78. public void processPOSTRequest(string text, string audioSaveFile, string format, int sampleRate)
  79. {
  80. /**
  81. * 设置HTTPS POST请求
  82. * 1.使用HTTPS协议
  83. * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  84. * 3.语音合成接口请求路径:/stream/v1/tts
  85. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  86. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  87. */
  88. string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
  89. JObject obj = new JObject();
  90. obj["appkey"] = appkey;
  91. obj["token"] = token;
  92. obj["text"] = text;
  93. obj["format"] = format;
  94. obj["sample_rate"] = sampleRate;
  95. // voice 发音人,可选,默认是xiaoyun
  96. // obj["voice"] = "xiaoyun";
  97. // volume 音量,范围是0~100,可选,默认50
  98. // obj["volume"] = 50;
  99. // speech_rate 语速,范围是-500~500,可选,默认是0
  100. // obj["speech_rate"] = 0;
  101. // pitch_rate 语调,范围是-500~500,可选,默认是0
  102. // obj["pitch_rate"] = 0;
  103. String bodyContent = obj.ToString();
  104. StringContent content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
  105. /**
  106. * 发送HTTPS POST请求,处理服务端的响应
  107. */
  108. HttpClient client = new HttpClient();
  109. HttpResponseMessage response = client.PostAsync(url, content).Result;
  110. string contentType = null;
  111. if (response.IsSuccessStatusCode)
  112. {
  113. string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
  114. if (typesArray.Length > 0)
  115. {
  116. contentType = typesArray.First();
  117. }
  118. }
  119. if ("audio/mpeg".Equals(contentType))
  120. {
  121. byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
  122. FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
  123. fs.Write(audioBuff, 0, audioBuff.Length);
  124. fs.Flush();
  125. fs.Close();
  126. System.Console.WriteLine("The POST request succeed!");
  127. }
  128. else
  129. {
  130. System.Console.WriteLine("Response status code and reason phrase: " +
  131. response.StatusCode + " " + response.ReasonPhrase);
  132. string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
  133. System.Console.WriteLine("The POST request failed: " + responseBodyAsText);
  134. }
  135. }
  136. static void Main(string[] args)
  137. {
  138. if (args.Length < 2)
  139. {
  140. System.Console.WriteLine("SpeechSynthesizerRESTfulDemo need params: <token> <app-key>");
  141. return;
  142. }
  143. string token = args[0];
  144. string appkey = args[1];
  145. SpeechSynthesizerRESTfulDemo demo = new SpeechSynthesizerRESTfulDemo(appkey, token);
  146. string text = "今天是周一,天气挺好的。";
  147. // 采用RFC 3986规范进行urlencode编码
  148. string textUrlEncode = text;
  149. textUrlEncode = HttpUtility.UrlEncode(textUrlEncode, Encoding.UTF8)
  150. .Replace("+", "%20")
  151. .Replace("*", "%2A")
  152. .Replace("%7E", "~");
  153. System.Console.WriteLine(textUrlEncode);
  154. string audioSaveFile = "syAudio.wav";
  155. string format = "wav";
  156. int sampleRate = 16000;
  157. demo.processGETRequest(textUrlEncode, audioSaveFile, format, sampleRate);
  158. //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate);
  159. }
  160. }
  161. }

GO Demo

  1. package main
  2. import (
  3. "fmt"
  4. "net/url"
  5. "net/http"
  6. "io/ioutil"
  7. "encoding/json"
  8. "strconv"
  9. "os"
  10. "bytes"
  11. "strings"
  12. )
  13. func processGETRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
  14. /**
  15. * 设置HTTPS GET请求
  16. * 1.使用HTTPS协议
  17. * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  18. * 3.语音识别接口请求路径:/stream/v1/tts
  19. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  20. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  21. */
  22. var url string = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts"
  23. url = url + "?appkey=" + appkey
  24. url = url + "&token=" + token
  25. url = url + "&text=" + text
  26. url = url + "&format=" + format
  27. url = url + "&sample_rate=" + strconv.Itoa(sampleRate)
  28. // voice 发音人,可选,默认是xiaoyun
  29. // url = url + "&voice=" + "xiaoyun"
  30. // volume 音量,范围是0~100,可选,默认50
  31. // url = url + "&volume=" + strconv.Itoa(50)
  32. // speech_rate 语速,范围是-500~500,可选,默认是0
  33. // url = url + "&speech_rate=" + strconv.Itoa(0)
  34. // pitch_rate 语调,范围是-500~500,可选,默认是0
  35. // url = url + "&pitch_rate=" + strconv.Itoa(0)
  36. fmt.Println(url)
  37. /**
  38. * 发送HTTPS GET请求,处理服务端的响应
  39. */
  40. response, err := http.Get(url)
  41. if err != nil {
  42. fmt.Println("The GET request failed!")
  43. panic(err)
  44. }
  45. defer response.Body.Close()
  46. contentType := response.Header.Get("Content-Type")
  47. body, _ := ioutil.ReadAll(response.Body)
  48. if ("audio/mpeg" == contentType) {
  49. file, _ := os.Create(audioSaveFile)
  50. defer file.Close()
  51. file.Write([]byte(body))
  52. fmt.Println("The GET request succeed!")
  53. } else {
  54. // ContentType 为 null 或者为 "application/json"
  55. statusCode := response.StatusCode
  56. fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode))
  57. fmt.Println("The GET request failed: " + string(body))
  58. }
  59. }
  60. func processPOSTRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
  61. /**
  62. * 设置HTTPS POST请求
  63. * 1.使用HTTPS协议
  64. * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
  65. * 3.语音合成接口请求路径:/stream/v1/tts
  66. * 4.设置必须请求参数:appkey、token、text、format、sample_rate
  67. * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
  68. */
  69. var url string = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts"
  70. bodyContent := make(map[string]interface{})
  71. bodyContent["appkey"] = appkey
  72. bodyContent["text"] = text
  73. bodyContent["token"] = token
  74. bodyContent["format"] = format
  75. bodyContent["sample_rate"] = sampleRate
  76. // voice 发音人,可选,默认是xiaoyun
  77. // bodyContent["voice"] = "xiaoyun"
  78. // volume 音量,范围是0~100,可选,默认50
  79. // bodyContent["volume"] = 50
  80. // speech_rate 语速,范围是-500~500,可选,默认是0
  81. // bodyContent["speech_rate"] = 0
  82. // pitch_rate 语调,范围是-500~500,可选,默认是0
  83. // bodyContent["pitch_rate"] = 0
  84. bodyJson, err := json.Marshal(bodyContent)
  85. if err != nil {
  86. panic(nil)
  87. }
  88. fmt.Println(string(bodyJson))
  89. /**
  90. * 发送HTTPS POST请求,处理服务端的响应
  91. */
  92. response, err := http.Post(url, "application/json;charset=utf-8", bytes.NewBuffer([]byte(bodyJson)))
  93. if err != nil {
  94. panic(err)
  95. }
  96. defer response.Body.Close()
  97. contentType := response.Header.Get("Content-Type")
  98. body, _ := ioutil.ReadAll(response.Body)
  99. if ("audio/mpeg" == contentType) {
  100. file, _ := os.Create(audioSaveFile)
  101. defer file.Close()
  102. file.Write([]byte(body))
  103. fmt.Println("The POST request succeed!")
  104. } else {
  105. // ContentType 为 null 或者为 "application/json"
  106. statusCode := response.StatusCode
  107. fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode))
  108. fmt.Println("The POST request failed: " + string(body))
  109. }
  110. }
  111. func main() {
  112. var appkey string = "您的appkey"
  113. var token string = "您的token"
  114. var text string = "今天是周一,天气挺好的。"
  115. var textUrlEncode = text
  116. textUrlEncode = url.QueryEscape(textUrlEncode)
  117. textUrlEncode = strings.Replace(textUrlEncode, "+", "%20", -1)
  118. textUrlEncode = strings.Replace(textUrlEncode, "*", "%2A", -1)
  119. textUrlEncode = strings.Replace(textUrlEncode, "%7E", "~", -1)
  120. fmt.Println(textUrlEncode)
  121. var audioSaveFile string = "syAudio.wav"
  122. var format string = "wav"
  123. var sampleRate int = 16000
  124. processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate)
  125. // processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate)
  126. }