全部产品
云市场
云游戏

RESTful API

更新时间:2020-08-25 15:06:06

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

功能介绍

支持如下设置:

  • PCM/WAV/MP3音频格式

  • 8000Hz/16000Hz采样率

  • 多种发音人

  • 语速/语调/音量

注意

  • 随着TTS合成效果不断提升,算法的复杂度也越来越高,对您而言,可能会遇到合成耗时变长的情况。因此我们建议您使用流式合成机制。本文档及SDK示例中有相关流式处理示例代码可供参考。

  • 单次调用传入文本不能超过300个字符,超过的字符会被截断。对于更长文本的合成,请参考SDK中的长文本切分及拼接示例。

  • 下载nls-restful-java-demo.zip

    新增RESTful语音合成Java示例代码,增加关于RESTful、HTTP Chunked、长文本切分分段合成等演示程序。

前提条件

服务地址

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

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

交互流程

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

RESTful

说明

服务端的错误响应都会在返回信息中包含表示本次合成任务的task_id参数,请记录该值,如果出现错误,请将task_id和错误信息提交到工单。

请求参数

语音合成的请求参数如下表所示。

  • 如果使用HTTPS GET方法的请求,需要在HTTPS的URL请求参数中设置这些参数。

  • 如果使用HTTPS POST方法的请求,需要在HTTPS的请求体(Body)中设置这些参数。

名称类型是否必选描述
appkeyString项目appkey。
textString待合成的文本,需要为UTF-8编码。使用GET方法,需要再采用RFC 3986规范进行urlencode编码;使用POST方法不需要urlencode编码。
tokenString若不设置token参数,需要在HTTP Headers中设置X-NLS-Token字段来指定Token。
formatString音频编码格式,支持PCM/WAV/MP3格式。默认值:PCM。
sample_rateInteger音频采样率,支持16000Hz/8000Hz,默认值:16000Hz。
voiceString发音人,默认值:xiaoyun。更多发音人请参见接口说明
volumeInteger音量,取值范围:0~100,默认值:50。
speech_rateInteger语速,取值范围:-500~500,默认值:0。
pitch_rateInteger语调,取值范围:-500~500,默认值:0。

GET方法上传文本

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

  • URL

    协议URL方法
    HTTPSnls-gateway.cn-shanghai.aliyuncs.com/stream/v1/ttsGET

  • 请求参数

    参见上述表格请求参数

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

# text文本:"今天是周一,天气挺好的。"
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-TokenString服务鉴权Token。

注意

  • 服务鉴权Token参数有如下两种设置方式:

    • (推荐)在请求参数token中设置

    • 在HTTPS Headers的X-NLS-Token字段设置

  • 参数text必须采用UTF-8编码,再采用RFC 3986规范进行urlencode编码。如加号 + 编码为 %2B,星号 * 编码为 %2A%7E 编码为 ~

POST方法上传文本

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

  • URL

    协议URL方法
    HTTPSnls-gateway.cn-shanghai.aliyuncs.com/stream/v1/ttsPOST

  • HTTPS POST请求头部

    名称类型是否必选描述
    Content-TypeString必须为“application/json”。表明HTTP Body的内容为JSON格式字符串。
    X-NLS-TokenString服务鉴权Token。
    Content-LengthlongHTTP Body中内容的长度。

  • HTTPS POST请求体

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

      {
        "appkey":"31f932fb",
        "text":"今天是周一,天气挺好的。",
        "token":"45034**********3c793",
        "format":"wav"
      }
注意

  • 服务鉴权Token参数有如下两种设置方式:

    • (推荐在请求体通过参数token设置

    • 在HTTPS Headers的X-NLS-Token字段设置

  • 使用POST方法的请求,请求体中的请求参数text必须采用UTF-8编码,但是不进行urlencode编码,注意与GET方法请求的区别。

响应结果

使用HTTPS GET方法和HTTPS POST方法请求的响应是相同的,响应结果都包含在HTTPS的Body中。响应结果的成功/失败通过HTTPS Headers的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 Headers的X-NLS-RequestId字段内容为请求任务的task_id。

    • Body内容为错误信息,以JSON格式的字符串表示。如下所示:

      {
          "task_id":"8f95d0b9b6e948bc98e8d0ce64b0cf57",
          "result":"",
          "status":40000000,
          "message":"Gateway:CLIENT_ERROR:in post data, json format illegal"
      }

    • 错误信息字段如下表所示。

      名称类型描述
      task_idString32位请求任务ID,请记录该值,用于排查错误。
      resultString服务结果
      statusInteger服务状态码
      messageString服务状态描述

服务状态码

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

Java示例

依赖文件内容如下:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>
<!-- http://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.42</version>
</dependency>
<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>2.5.4</version>
</dependency>

示例代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import com.alibaba.fastjson.JSONObject;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SpeechSynthesizerRestfulDemo {
    private String accessToken;
    private String appkey;
    public SpeechSynthesizerRestfulDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }
    /**
     * HTTPS GET请求
     */
    public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice) {
        /**
         * 设置HTTPS GET请求:
         * 1.使用HTTPS协议
         * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
         * 3.语音识别接口请求路径:/stream/v1/tts
         * 4.设置必须请求参数:appkey、token、text、format、sample_rate
         * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
         */
        String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
        url = url + "?appkey=" + appkey;
        url = url + "&token=" + accessToken;
        url = url + "&text=" + text;
        url = url + "&format=" + format;
        url = url + "&voice=" + voice;
        url = url + "&sample_rate=" + String.valueOf(sampleRate);
        // voice 发音人,可选,默认是xiaoyun。
        // url = url + "&voice=" + "xiaoyun";
        // volume 音量,范围是0~100,可选,默认50。
        // url = url + "&volume=" + String.valueOf(50);
        // speech_rate 语速,范围是-500~500,可选,默认是0。
        // url = url + "&speech_rate=" + String.valueOf(0);
        // pitch_rate 语调,范围是-500~500,可选,默认是0。
        // url = url + "&pitch_rate=" + String.valueOf(0);
        System.out.println("URL: " + url);
        /**
         * 发送HTTPS GET请求,处理服务端的响应。
         */
        Request request = new Request.Builder().url(url).get().build();
        try {
            long start = System.currentTimeMillis();
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            System.out.println("total latency :" + (System.currentTimeMillis() - start) + " ms");
            System.out.println(response.headers().toString());
            String contentType = response.header("Content-Type");
            if ("audio/mpeg".equals(contentType)) {
                File f = new File(audioSaveFile);
                FileOutputStream fout = new FileOutputStream(f);
                fout.write(response.body().bytes());
                fout.close();
                System.out.println("The GET request succeed!");
            }
            else {
                // ContentType 为 null 或者为 "application/json"
                String errorMessage = response.body().string();
                System.out.println("The GET request failed: " + errorMessage);
            }
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * HTTPS POST请求
     */
    public void processPOSTRequest(String text, String audioSaveFile, String format, int sampleRate, String voice) {
        /**
         * 设置HTTPS POST请求:
         * 1.使用HTTPS协议
         * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
         * 3.语音合成接口请求路径:/stream/v1/tts
         * 4.设置必须请求参数:appkey、token、text、format、sample_rate
         * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
         */
        String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
        JSONObject taskObject = new JSONObject();
        taskObject.put("appkey", appkey);
        taskObject.put("token", accessToken);
        taskObject.put("text", text);
        taskObject.put("format", format);
        taskObject.put("voice", voice);
        taskObject.put("sample_rate", sampleRate);
        // voice 发音人,可选,默认是xiaoyun。
        // taskObject.put("voice", "xiaoyun");
        // volume 音量,范围是0~100,可选,默认50。
        // taskObject.put("volume", 50);
        // speech_rate 语速,范围是-500~500,可选,默认是0。
        // taskObject.put("speech_rate", 0);
        // pitch_rate 语调,范围是-500~500,可选,默认是0。
        // taskObject.put("pitch_rate", 0);
        String bodyContent = taskObject.toJSONString();
        System.out.println("POST Body Content: " + bodyContent);
        RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
        Request request = new Request.Builder()
            .url(url)
            .header("Content-Type", "application/json")
            .post(reqBody)
            .build();
        try {
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            String contentType = response.header("Content-Type");
            if ("audio/mpeg".equals(contentType)) {
                File f = new File(audioSaveFile);
                FileOutputStream fout = new FileOutputStream(f);
                fout.write(response.body().bytes());
                fout.close();
                System.out.println("The POST request succeed!");
            }
            else {
                // ContentType 为 null 或者为 "application/json"
                String errorMessage = response.body().string();
                System.out.println("The POST request failed: " + errorMessage);
            }
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("SpeechSynthesizerRestfulDemo need params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        SpeechSynthesizerRestfulDemo demo = new SpeechSynthesizerRestfulDemo(appkey, token);
        String text = "今天是周一,天气挺好的。";
        // 采用RFC 3986规范进行urlencode编码。
        String textUrlEncode = text;
        try {
            textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(textUrlEncode);
        String audioSaveFile = "syAudio.wav";
        String format = "wav";
        int sampleRate = 16000;
        demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "siyue");
        //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate, "siyue");
        System.out.println("### Game Over ###");
    }
}

Java(流式合成)示例代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.concurrent.CountDownLatch;
import io.netty.handler.codec.http.HttpHeaders;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.HttpResponseBodyPart;
import org.asynchttpclient.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 此示例演示了
 * 1. TTS的RESTFul接口调用。
 * 2. 启用HTTP chunked机制的处理方式(流式返回)。
 */
public class SpeechSynthesizerRestfulChunkedDemo {
    private static Logger logger = LoggerFactory.getLogger(SpeechSynthesizerRestfulChunkedDemo.class);
    private String accessToken;
    private String appkey;
    public SpeechSynthesizerRestfulChunkedDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }
    public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice, boolean chunked) {
        /**
         * 设置HTTPS GET请求:
         * 1.使用HTTPS协议
         * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
         * 3.语音识别接口请求路径:/stream/v1/tts
         * 4.设置必须请求参数:appkey、token、text、format、sample_rate
         * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
         * 6.设置参数chunk,启用http流式返回
         */
        String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
        url = url + "?appkey=" + appkey;
        url = url + "&token=" + accessToken;
        url = url + "&text=" + text;
        url = url + "&format=" + format;
        url = url + "&voice=" + voice;
        url = url + "&sample_rate=" + String.valueOf(sampleRate);
        url = url + "&chunk=" + String.valueOf(chunked);
        System.out.println("URL: " + url);
        try {
            AsyncHttpClientConfig config = new DefaultAsyncHttpClientConfig.Builder()
                .setConnectTimeout(3000)
                .setKeepAlive(true)
                .setReadTimeout(10000)
                .setRequestTimeout(50000)
                .setMaxConnections(1000)
                .setMaxConnectionsPerHost(200)
                .setPooledConnectionIdleTimeout(-1)
                .build();
            AsyncHttpClient httpClient = new DefaultAsyncHttpClient(config);
            CountDownLatch latch = new CountDownLatch(1);
            AsyncHandler<org.asynchttpclient.Response> handler = new AsyncHandler<org.asynchttpclient.Response>() {
                FileOutputStream outs;
                boolean firstRecvBinary = true;
                long startTime = System.currentTimeMillis();
                int httpCode = 200;
                @Override
                public State onStatusReceived(HttpResponseStatus httpResponseStatus) throws Exception {
                    logger.info("onStatusReceived status {}", httpResponseStatus);
                    httpCode = httpResponseStatus.getStatusCode();
                    if (httpResponseStatus.getStatusCode() != 200) {
                        logger.error("request error " +  httpResponseStatus.toString());
                    }
                    return null;
                }
                @Override
                public State onHeadersReceived(HttpHeaders httpHeaders) throws Exception {
                    outs = new FileOutputStream(new File("tts.wav"));
                    return null;
                }
                @Override
                public State onBodyPartReceived(HttpResponseBodyPart httpResponseBodyPart) throws Exception {
                    // 注意:此处一旦接收到数据流,即可向用户播放或者用于其他处理,以提升响应速度。
                    // 注意:请不要在此回调接口中执行耗时操作,可以以异步或者队列形式将二进制TTS语音流推送到另一线程中。
                    logger.info("onBodyPartReceived " + httpResponseBodyPart.getBodyPartBytes().toString());
                    if(httpCode != 200) {
                        System.err.write(httpResponseBodyPart.getBodyPartBytes());
                    }
                    if (firstRecvBinary) {
                        firstRecvBinary = false;
                        // 统计第一包数据的接收延迟。实际上接收到第一包数据后就可以进行业务处理了,比如播放或者发送给调用方。注意:这里的首包延迟也包括了网络建立链接的时间。
                        logger.info("tts first latency " + (System.currentTimeMillis() - startTime) + " ms");
                    }
                    // 此处以将语音流保存到文件为例。
                    outs.write(httpResponseBodyPart.getBodyPartBytes());
                    return null;
                }
                @Override
                public void onThrowable(Throwable throwable) {
                    logger.error("throwable {}", throwable);
                    latch.countDown();
                }
                @Override
                public org.asynchttpclient.Response onCompleted() throws Exception {
                    logger.info("completed");
                    logger.info("tts total latency " + (System.currentTimeMillis() - startTime) + " ms");
                    outs.close();
                    latch.countDown();
                    return null;
                }
            };
            httpClient.prepareGet(url).execute(handler);
            // 等待合成完成
            latch.await();
            httpClient.close();
        }catch (Exception e) {
        }
    }
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("SpeechSynthesizerRestfulDemo need params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        SpeechSynthesizerRestfulChunkedDemo demo = new SpeechSynthesizerRestfulChunkedDemo(appkey, token);
        String text = "我家的后面有一个很大的园,相传叫作百草园。现在是早已并屋子一起卖给朱文公的子孙了,连那最末次的相见也已经隔了七八年,其中似乎确凿只有一些野草;但那时却是我的乐园。";
        // 采用RFC 3986规范进行urlencode编码。
        String textUrlEncode = text;
        try {
            textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(textUrlEncode);
        String audioSaveFile = "syAudio.wav";
        String format = "wav";
        int sampleRate = 16000;
        // 最后一个参数为true表示使用http chunked机制。
        demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "aixia", true);
        System.out.println("### Game Over ###");
    }
}

C++示例

说明

  • 下载C++示例

    C++示例使用第三方函数库curl处理HTTPS的请求和响应,使用jsoncpp处理POST请求Body的JSON字符串。

  • Linux环境下,运行环境最低要求:Glibc 2.5及以上, Gcc4或Ccc5。

  • Windows下需解压lib目录下的windows.zip库编译使用。

示例目录说明如下:

  • CMakeLists.txt:示例工程的CMakeList文件。

  • demo:示例文件。

    文件名描述
    restfulTtsDemo.cpp语音合成RESTful API示例。
  • include

    目录名描述
    curlcurl库头文件目录。
    jsonjsoncpp库头文件目录。
  • lib:包含curl、jsoncpp动态库。

    根据平台不同,使用如下版本软件加载库文件:

    • linux(Glibc:2.5及以上,Gcc4或Gcc5)

    • windows(VS2013、VS2015)

  • readme.txt:说明文件。

  • release.log:更新记录。

  • version:版本号。

  • build.sh:示例编译脚本。

编译运行操作步骤:

假设示例文件已解压至path/to路径下,在Linux终端依次执行如下命令编译运行程序。

  • 支持Cmake:

    1. 确认本地系统已安装Cmake 2.4及以上版本。

    2. cd path/to/sdk/lib

    3. tar -zxvpf linux.tar.gz

    4. cd path/to/sdk

    5. ./build.sh

    6. cd path/to/sdk/demo

    7. ./restfulTtsDemo <your-token> <your-appkey>

  • 不支持Cmake:

    1. cd path/to/sdk/lib

    2. tar -zxvpf linux.tar.gz

    3. cd path/to/sdk/demo

    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

    5. export LD_LIBRARY_PATH=path/to/sdk/lib/linux/

    6. ./restfulTtsDemo <your-token> <your-appkey>

示例代码如下:

#ifdef _WIN32
#include <Windows.h>
#endif
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <sstream>
#include "curl/curl.h"
#include "json/json.h"
using namespace std;
#ifdef _WIN32
string GBKToUTF8(const string &strGBK) {
    string strOutUTF8 = "";
    WCHAR * str1;
    int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
    str1 = new WCHAR[n];
    MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
    n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    char * str2 = new char[n];
    WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
    strOutUTF8 = str2;
    delete[] str1;
    str1 = NULL;
    delete[] str2;
    str2 = NULL;
    return strOutUTF8;
}
#endif
void stringReplace(string& src, const string& s1, const string& s2) {
    string::size_type pos = 0;
    while ((pos = src.find(s1, pos)) != string::npos) {
        src.replace(pos, s1.length(), s2);
        pos += s2.length();
    }
}
string urlEncode(const string& src) {
    CURL* curl = curl_easy_init();
    char* output = curl_easy_escape(curl, src.c_str(), src.size());
    string result(output);
    curl_free(output);
    curl_easy_cleanup(curl);
    return result;
}
size_t responseHeadersCallback(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    map<string, string> *headers = (map<string, string>*)userdata;
    string line((char*)ptr);
    string::size_type pos = line.find(':');
    if (pos != line.npos)
    {
        string name = line.substr(0, pos);
        string value = line.substr(pos + 2);
        size_t p = 0;
        if ((p = value.rfind('\r')) != value.npos) {
            value = value.substr(0, p);
        }
        headers->insert(make_pair(name, value));
    }
    return size * nmemb;
}
size_t responseBodyCallback(void* ptr, size_t size, size_t nmemb, void* userData) {
    size_t len = size * nmemb;
    char* pBuf = (char*)ptr;
    string* bodyContent = (string*)userData;
    (*bodyContent).append(string(pBuf, pBuf + len));
    return len;
}
int processGETRequest(string appKey, string token, string text, 
                      string audioSaveFile, string format, int sampleRate) {
    CURL* curl = NULL;
    CURLcode res;
    curl = curl_easy_init();
    if (curl == NULL) {
        return -1;
    }
    string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * 设置HTTPS URL请求参数。
     */
    ostringstream oss;
    oss << url;
    oss << "?appkey=" << appKey;
    oss << "&token=" << token;
    oss << "&text=" << text;
    oss << "&format=" << format;
    oss << "&sample_rate=" << sampleRate;
    // voice 发音人,可选,默认是xiaoyun。
    // oss << "&voice=" << "xiaoyun";
    // volume 音量,范围是0~100,可选,默认50。
    // oss << "&volume=" << 50;
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // oss << "&speech_rate=" << 0;
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // oss << "&pitch_rate=" << 0;
    string request = oss.str();
    cout << request << endl;
    curl_easy_setopt(curl, CURLOPT_URL, request.c_str());
    /**
     * 设置获取响应的HTTPS Headers回调函数。
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * 设置获取响应的HTTPS Body回调函数。
     */
    string bodyContent = "";
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
    /**
     * 发送HTTPS GET请求。
     */
    res = curl_easy_perform(curl);
    /**
     * 释放资源。
     */
    curl_easy_cleanup(curl);
    if (res != CURLE_OK) {
        cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
        return -1;
    }
    /**
     * 处理服务端返回的响应。
     */
    map<string, string>::iterator it = responseHeaders.find("Content-Type");
    if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
        ofstream fs;
        fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
        if (!fs.is_open()) {
            cout << "The audio save file can not open!";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "The GET request succeed!" << endl;
    }
    else {
        cout << "The GET request failed: " + bodyContent << endl;
        return -1;
    }
    return 0;
}
int processPOSTRequest(string appKey, string token, string text,
                       string audioSaveFile, string format, int sampleRate) {
    CURL* curl = NULL;
    CURLcode res;
    curl = curl_easy_init();
    if (curl == NULL) {
        return -1;
    }
    string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * 设置HTTPS POST URL。
     */
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    /**
     * 设置HTTPS POST请求头部。
     */
    struct curl_slist* headers = NULL;
    // Content-Type
    headers = curl_slist_append(headers, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    /**
     * 设置HTTPS POST请求体。
     */
    Json::Value root;
    Json::FastWriter writer;
    root["appkey"] = appKey;
    root["token"] = token;
    root["text"] = text;
    root["format"] = format;
    root["sample_rate"] = sampleRate;
    // voice 发音人,可选,默认是xiaoyun。
    // root["voice"] = "xiaoyun";
    // volume 音量,范围是0~100,可选,默认50。
    // root["volume"] = 50;
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // root["speech_rate"] = 0;
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // root["pitch_rate"] = 0;
    string task = writer.write(root);
    cout << "POST request Body: " << task << endl;
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, task.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, task.length());
    /**
     * 设置获取响应的HTTPS Headers回调函数。
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * 设置获取响应的HTTPS Body回调函数。
     */
    string bodyContent = "";
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
    /**
     * 发送HTTPS POST请求。
     */
    res = curl_easy_perform(curl);
    /**
     * 释放资源。
     */
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    if (res != CURLE_OK) {
        cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
        return -1;
    }
    /**
     * 处理服务端返回的响应。
     */
    map<string, string>::iterator it = responseHeaders.find("Content-Type");
    if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
        ofstream fs;
        fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
        if (!fs.is_open()) {
            cout << "The audio save file can not open!";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "The POST request succeed!" << endl;
    }
    else {
        cout << "The POST request failed: " + bodyContent << endl;
        return -1;
    }
    return 0;
}
int main(int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "params is not valid. Usage: ./demo your_token your_appkey" << endl;
        return -1;
    }
    string token = argv[1];
    string appKey = argv[2];
    string text = "今天是周一,天气挺好的。";
#ifdef _WIN32
    text = GBKToUTF8(text);
#endif
    string textUrlEncode = urlEncode(text);
    stringReplace(textUrlEncode, "+", "%20");
    stringReplace(textUrlEncode, "*", "%2A");
    stringReplace(textUrlEncode, "%7E", "~");
    string audioSaveFile = "syAudio.wav";
    string format = "wav";
    int sampleRate = 16000;
    // 全局只初始化一次。
    curl_global_init(CURL_GLOBAL_ALL);
    processGETRequest(appKey, token, textUrlEncode, audioSaveFile, format, sampleRate);
    //processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate);
    curl_global_cleanup();
    return 0;
}

Python示例

说明
  • Python 2.x请使用httplib模块;Python 3.x请使用http.client模块。

  • 采用RFC 3986规范进行urlencode编码,Python 2.x请使用urllib模块的urllib.quote,Python 3.x请使用urllib.parse模块的urllib.parse.quote_plus。

  • 如果使用内网访问URL,请使用HTTP协议,需要替换如下函数,即将HTTPSConnection修改为HTTPConnection

        # Python 2.x 请使用httplib
        # conn = httplib.HTTPConnection(host)
    
        # Python 3.x 请使用http.client
        conn = http.client.HTTPConnection(host)
# -*- coding: UTF-8 -*-
# Python 2.x引入httplib模块。
# import httplib
# Python 3.x引入http.client模块。
import http.client
# Python 2.x引入urllib模块。
# import urllib
# Python 3.x引入urllib.parse模块。
import urllib.parse
import json
def processGETRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
    host = 'nls-gateway.cn-shanghai.aliyuncs.com'
    url = 'https://' + host + '/stream/v1/tts'
    # 设置URL请求参数
    url = url + '?appkey=' + appKey
    url = url + '&token=' + token
    url = url + '&text=' + text
    url = url + '&format=' + format
    url = url + '&sample_rate=' + str(sampleRate)
    # voice 发音人,可选,默认是xiaoyun。
    # url = url + '&voice=' + 'xiaoyun'
    # volume 音量,范围是0~100,可选,默认50。
    # url = url + '&volume=' + str(50)
    # speech_rate 语速,范围是-500~500,可选,默认是0。
    # url = url + '&speech_rate=' + str(0)
    # pitch_rate 语调,范围是-500~500,可选,默认是0。
    # url = url + '&pitch_rate=' + str(0)
    print(url)
    # Python 2.x请使用httplib。
    # conn = httplib.HTTPSConnection(host)
    # Python 3.x请使用http.client。
    conn = http.client.HTTPSConnection(host)
    conn.request(method='GET', url=url)
    # 处理服务端返回的响应。
    response = conn.getresponse()
    print('Response status and response reason:')
    print(response.status ,response.reason)
    contentType = response.getheader('Content-Type')
    print(contentType)
    body = response.read()
    if 'audio/mpeg' == contentType :
        with open(audioSaveFile, mode='wb') as f:
            f.write(body)
        print('The GET request succeed!')
    else :
        print('The GET request failed: ' + str(body))
    conn.close()
def processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
    host = 'nls-gateway.cn-shanghai.aliyuncs.com'
    url = 'https://' + host + '/stream/v1/tts'
    # 设置HTTPS Headers。
    httpHeaders = {
        'Content-Type': 'application/json'
        }
    # 设置HTTPS Body。
    body = {'appkey': appKey, 'token': token, 'text': text, 'format': format, 'sample_rate': sampleRate}
    body = json.dumps(body)
    print('The POST request body content: ' + body)
    # Python 2.x请使用httplib。
    # conn = httplib.HTTPSConnection(host)
    # Python 3.x请使用http.client。
    conn = http.client.HTTPSConnection(host)
    conn.request(method='POST', url=url, body=body, headers=httpHeaders)
    # 处理服务端返回的响应。
    response = conn.getresponse()
    print('Response status and response reason:')
    print(response.status ,response.reason)
    contentType = response.getheader('Content-Type')
    print(contentType)
    body = response.read()
    if 'audio/mpeg' == contentType :
        with open(audioSaveFile, mode='wb') as f:
            f.write(body)
        print('The POST request succeed!')
    else :
        print('The POST request failed: ' + str(body))
    conn.close()
appKey = '您的appkey'
token = '您的token'
text = '今天是周一,天气挺好的。'
# 采用RFC 3986规范进行urlencode编码。
textUrlencode = text
# Python 2.x请使用urllib.quote。
# textUrlencode = urllib.quote(textUrlencode, '')
# Python 3.x请使用urllib.parse.quote_plus。
textUrlencode = urllib.parse.quote_plus(textUrlencode)
textUrlencode = textUrlencode.replace("+", "%20")
textUrlencode = textUrlencode.replace("*", "%2A")
textUrlencode = textUrlencode.replace("%7E", "~")
print('text: ' + textUrlencode)
audioSaveFile = 'syAudio.wav'
format = 'wav'
sampleRate = 16000
# GET请求方式
processGETRequest(appKey, token, textUrlencode, audioSaveFile, format, sampleRate)
# POST请求方式
# processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate)

PHP示例

说明

PHP示例中使用了cURL函数,要求PHP版本在4.0.2以上,并且确保已安装cURL扩展。

<?php
function processGETRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
    $url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
    $url = $url . "?appkey=" . $appkey;
    $url = $url . "&token=" . $token;
    $url = $url . "&text=" . $text;
    $url = $url . "&format=" . $format;
    $url = $url . "&sample_rate=" . strval($sampleRate);
    // voice 发音人,可选,默认是xiaoyun。
    // $url = $url . "&voice=" . "xiaoyun";
    // volume 音量,范围是0~100,可选,默认50。
    // $url = $url . "&volume=" . strval(50);
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // $url = $url . "&speech_rate=" . strval(0);
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // $url = $url . "&pitch_rate=" . strval(0);
    print $url . "\n";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    /**
     * 设置HTTPS GET URL。
     */
    curl_setopt($curl, CURLOPT_URL, $url);
    /**
     * 设置返回的响应包含HTTPS头部信息。
     */
    curl_setopt($curl, CURLOPT_HEADER, TRUE);
    /**
     * 发送HTTPS GET请求。
     */
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    $response = curl_exec($curl);
    if ($response == FALSE) {
        print "curl_exec failed!\n";
        curl_close($curl);
        return ;
    }
    /**
     * 处理服务端返回的响应。
     */
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $headers = substr($response, 0, $headerSize);
    $bodyContent = substr($response, $headerSize);
    curl_close($curl);
    if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
        file_put_contents($audioSaveFile, $bodyContent);
        print "The GET request succeed!\n";
    }
    else {
        print "The GET request failed: " . $bodyContent . "\n";
    }
}
function processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
    $url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * 请求参数,以JSON格式字符串填入HTTPS POST请求的Body中。
     */
    $taskArr = array(
        "appkey" => $appkey,
        "token" => $token,
        "text" => $text,
        "format" => $format,
        "sample_rate" => $sampleRate
        // voice 发音人,可选,默认是xiaoyun。
        // "voice" => "xiaoyun",
        // volume 音量,范围是0~100,可选,默认50。
        // "volume" => 50,
        // speech_rate 语速,范围是-500~500,可选,默认是0。
        // "speech_rate" => 0,
        // pitch_rate 语调,范围是-500~500,可选,默认是0。
        // "pitch_rate" => 0
    );
    $body = json_encode($taskArr);
    print "The POST request body content: " . $body . "\n";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    /**
     * 设置HTTPS POST URL。
     */
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, TRUE);
    /**
     * 设置HTTPS POST请求头部。
     * */
    $httpHeaders = array(
        "Content-Type: application/json"
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
    /**
     * 设置HTTPS POST请求体。
     */
    curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    /**
     * 设置返回的响应包含HTTPS头部信息。
     */
    curl_setopt($curl, CURLOPT_HEADER, TRUE);
    /**
     * 发送HTTPS POST请求。
     */
    $response = curl_exec($curl);
    if ($response == FALSE) {
        print "curl_exec failed!\n";
        curl_close($curl);
        return ;
    }
    /**
     * 处理服务端返回的响应。
     */
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $headers = substr($response, 0, $headerSize);
    $bodyContent = substr($response, $headerSize);
    curl_close($curl);
    if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
        file_put_contents($audioSaveFile, $bodyContent);
        print "The POST request succeed!\n";
    }
    else {
        print "The POST request failed: " . $bodyContent . "\n";
    }
}
$appkey = "您的appkey";
$token = "您的token";
$text = "今天是周一,天气挺好的。";
$textUrlEncode = urlencode($text);
$textUrlEncode = preg_replace('/\+/', '%20', $textUrlEncode);
$textUrlEncode = preg_replace('/\*/', '%2A', $textUrlEncode);
$textUrlEncode = preg_replace('/%7E/', '~', $textUrlEncode);
$audioSaveFile = "syAudio.wav";
$format = "wav";
$sampleRate = 16000;
processGETRequest($appkey, $token, $textUrlEncode, $audioSaveFile, $format, $sampleRate);
// processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate);
?>

Node.js示例

说明

首先安装request依赖,请在您的示例文件所在目录执行如下命令:

npm install request --save
const request = require('request');
const fs = require('fs');
function processGETRequest(appkey, token, text, audioSaveFile, format, sampleRate) {
    var url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts';
    /**
     * 设置URL请求参数。
     */
    url = url + '?appkey=' + appkey;
    url = url + '&token=' + token;
    url = url + '&text=' + text;
    url = url + '&format=' + format;
    url = url + '&sample_rate=' + sampleRate;
    // voice 发音人,可选,默认是xiaoyun。
    // url = url + "&voice=" + "xiaoyun";
    // volume 音量,范围是0~100,可选,默认50。
    // url = url + "&volume=" + 50;
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // url = url + "&speech_rate=" + 0;
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // url = url + "&pitch_rate=" + 0;
    console.log(url);
    /**
     * 设置HTTPS GET请求。
     * encoding必须设置为null,HTTPS响应的Body为二进制Buffer类型。
     */
    var options = {
        url: url,
        method: 'GET',
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * 处理服务端的响应。
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log(body.toString());
                console.log('The GET request failed!');
            }
            else {
                fs.writeFileSync(audioSaveFile, body);
                console.log('The GET request is succeed!');
            }
        }
    });
}
function processPOSTRequest(appkeyValue, tokenValue, textValue, audioSaveFile, formatValue, sampleRateValue) {
    var url = 'https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts';
    /**
     * 请求参数,以JSON格式字符串填入HTTPS POST请求的Body中。
    */
    var task = {
        appkey : appkeyValue,
        token : tokenValue,
        text : textValue,
        format : formatValue,
        sample_rate : sampleRateValue
        // voice 发音人,可选,默认是xiaoyun。
        // voice : 'xiaoyun',
        // volume 音量,范围是0~100,可选,默认50。
        // volume : 50,
        // speech_rate 语速,范围是-500~500,可选,默认是0。
        // speech_rate : 0,
        // pitch_rate 语调,范围是-500~500,可选,默认是0。
        // pitch_rate : 0
    };
    var bodyContent = JSON.stringify(task);
    console.log('The POST request body content: ' + bodyContent);
    /**
     * 设置HTTPS POST请求头部。
     */
    var httpHeaders = {
        'Content-type' : 'application/json'
    }
    /**
     * 设置HTTPS POST请求。
     * encoding必须设置为null,HTTPS响应的Body为二进制Buffer类型。
     */
    var options = {
        url: url,
        method: 'POST',
        headers: httpHeaders,
        body: bodyContent,
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * 处理服务端的响应。
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log(body.toString());
                console.log('The POST request failed!');
            }
            else {
                fs.writeFileSync(audioSaveFile, body);
                console.log('The POST request is succeed!');
            }
        }
    });
}
var appkey = '您的appkey';
var token = '您的token';
var text = '今天是周一,天气挺好的。';
var textUrlEncode = encodeURIComponent(text)
                    .replace(/[!'()*]/g, function(c) {
                        return '%' + c.charCodeAt(0).toString(16);
                    });
console.log(textUrlEncode);
var audioSaveFile = 'syAudio.wav';
var format = 'wav';
var sampleRate = 16000;
processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate);
// processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate);

.Net示例

说明

示例使用依赖System.Net.Http、System.Web、Newtonsoft.Json.Linq。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Http;
using System.Web;
using Newtonsoft.Json.Linq;
namespace RESTfulAPI
{
    class SpeechSynthesizerRESTfulDemo
    {
        private string appkey;
        private string token;
        public SpeechSynthesizerRESTfulDemo(string appkey, string token)
        {
            this.appkey = appkey;
            this.token = token;
        }
        public void processGETRequest(string text, string audioSaveFile, string format, int sampleRate)
        {
            /**
             * 设置HTTPS GET请求:
             * 1.使用HTTPS协议
             * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
             * 3.语音识别接口请求路径:/stream/v1/tts
             * 4.设置必须请求参数:appkey、token、text、format、sample_rate
             * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
             */
            string url = "http://nls-gateway.aliyuncs.com/stream/v1/tts";
            url = url + "?appkey=" + appkey;
            url = url + "&token=" + token;
            url = url + "&text=" + text;
            url = url + "&format=" + format;
            url = url + "&sample_rate=" + sampleRate.ToString();
            // voice 发音人,可选,默认是xiaoyun。
            // url = url + "&voice=" + "xiaoyun";
            // volume 音量,范围是0~100,可选,默认50。
            // url = url + "&volume=" + 50;
            // speech_rate 语速,范围是-500~500,可选,默认是0。
            // url = url + "&speech_rate=" + 0;
            // pitch_rate 语调,范围是-500~500,可选,默认是0。
            // url = url + "&pitch_rate=" + 0;
            System.Console.WriteLine(url);
            /**
             * 发送HTTPS GET请求,处理服务端的响应。
             */
            HttpClient client = new HttpClient();
            HttpResponseMessage response = null;
            response = client.GetAsync(url).Result;
            string contentType = null;
            if (response.IsSuccessStatusCode)
            {
                string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
                if (typesArray.Length > 0)
                {
                    contentType = typesArray.First();
                }
            }
            if ("audio/mpeg".Equals(contentType))
            {
                byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
                FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
                fs.Write(audioBuff, 0, audioBuff.Length);
                fs.Flush();
                fs.Close();
                System.Console.WriteLine("The GET request succeed!");
            }
            else
            {
                // ContentType 为 null 或者为 "application/json"
                System.Console.WriteLine("Response status code and reason phrase: " +
                    response.StatusCode + " " + response.ReasonPhrase);
                string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                System.Console.WriteLine("The GET request failed: " + responseBodyAsText);
            }
        }
        public void processPOSTRequest(string text, string audioSaveFile, string format, int sampleRate)
        {
            /**
             * 设置HTTPS POST请求:
             * 1.使用HTTPS协议
             * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
             * 3.语音合成接口请求路径:/stream/v1/tts
             * 4.设置必须请求参数:appkey、token、text、format、sample_rate
             * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
             */
            string url = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts";
            JObject obj = new JObject();
            obj["appkey"] = appkey;
            obj["token"] = token;
            obj["text"] = text;
            obj["format"] = format;
            obj["sample_rate"] = sampleRate;
            // voice 发音人,可选,默认是xiaoyun。
            // obj["voice"] = "xiaoyun";
            // volume 音量,范围是0~100,可选,默认50。
            // obj["volume"] = 50;
            // speech_rate 语速,范围是-500~500,可选,默认是0。
            // obj["speech_rate"] = 0;
            // pitch_rate 语调,范围是-500~500,可选,默认是0。
            // obj["pitch_rate"] = 0;
            String bodyContent = obj.ToString();
            StringContent content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
            /**
             * 发送HTTPS POST请求,处理服务端的响应。
             */
            HttpClient client = new HttpClient();
            HttpResponseMessage response = client.PostAsync(url, content).Result;
            string contentType = null;
            if (response.IsSuccessStatusCode)
            {
                string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
                if (typesArray.Length > 0)
                {
                    contentType = typesArray.First();
                }
            }
            if ("audio/mpeg".Equals(contentType))
            {
                byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
                FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
                fs.Write(audioBuff, 0, audioBuff.Length);
                fs.Flush();
                fs.Close();
                System.Console.WriteLine("The POST request succeed!");
            }
            else
            {
                System.Console.WriteLine("Response status code and reason phrase: " +
                    response.StatusCode + " " + response.ReasonPhrase);
                string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                System.Console.WriteLine("The POST request failed: " + responseBodyAsText);
            }
        }
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                System.Console.WriteLine("SpeechSynthesizerRESTfulDemo need params: <token> <app-key>");
                return;
            }
            string token = args[0];
            string appkey = args[1];
            SpeechSynthesizerRESTfulDemo demo = new SpeechSynthesizerRESTfulDemo(appkey, token);
            string text = "今天是周一,天气挺好的。";
            // 采用RFC 3986规范进行urlencode编码。
            string textUrlEncode = text;
            textUrlEncode = HttpUtility.UrlEncode(textUrlEncode, Encoding.UTF8)
                .Replace("+", "%20")
                .Replace("*", "%2A")
                .Replace("%7E", "~");
            System.Console.WriteLine(textUrlEncode);
            string audioSaveFile = "syAudio.wav";
            string format = "wav";
            int sampleRate = 16000;
            demo.processGETRequest(textUrlEncode, audioSaveFile, format, sampleRate);
            //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate);
        }
    }
}

GO示例

package main
import (
    "fmt"
    "net/url"
    "net/http"
    "io/ioutil"
    "encoding/json"
    "strconv"
    "os"
    "bytes"
    "strings"
)
func processGETRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
    /**
     * 设置HTTPS GET请求:
     * 1.使用HTTPS协议
     * 2.语音识别服务域名:nls-gateway.cn-shanghai.aliyuncs.com
     * 3.语音识别接口请求路径:/stream/v1/tts
     * 4.设置必须请求参数:appkey、token、text、format、sample_rate
     * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
     */
    var url string = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts"
    url = url + "?appkey=" + appkey
    url = url + "&token=" + token
    url = url + "&text=" + text
    url = url + "&format=" + format
    url = url + "&sample_rate=" + strconv.Itoa(sampleRate)
    // voice 发音人,可选,默认是xiaoyun。
    // url = url + "&voice=" + "xiaoyun"
    // volume 音量,范围是0~100,可选,默认50。
    // url = url + "&volume=" + strconv.Itoa(50)
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // url = url + "&speech_rate=" + strconv.Itoa(0)
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // url = url + "&pitch_rate=" + strconv.Itoa(0)
    fmt.Println(url)
    /**
     * 发送HTTPS GET请求,处理服务端的响应。
     */
    response, err := http.Get(url)
    if err != nil {
        fmt.Println("The GET request failed!")
        panic(err)
    }
    defer response.Body.Close()    
    contentType := response.Header.Get("Content-Type")
    body, _ := ioutil.ReadAll(response.Body)
    if ("audio/mpeg" == contentType) {
        file, _ := os.Create(audioSaveFile)
        defer file.Close()
        file.Write([]byte(body))
        fmt.Println("The GET request succeed!")
    } else {
        // ContentType 为 null 或者为 "application/json"
        statusCode := response.StatusCode
        fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode))
        fmt.Println("The GET request failed: " + string(body))
    }
}
func processPOSTRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
    /**
     * 设置HTTPS POST请求:
     * 1.使用HTTPS协议
     * 2.语音合成服务域名:nls-gateway.cn-shanghai.aliyuncs.com
     * 3.语音合成接口请求路径:/stream/v1/tts
     * 4.设置必须请求参数:appkey、token、text、format、sample_rate
     * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate
     */
    var url string = "https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts"
    bodyContent := make(map[string]interface{})
    bodyContent["appkey"] = appkey
    bodyContent["text"] = text
    bodyContent["token"] = token
    bodyContent["format"] = format
    bodyContent["sample_rate"] = sampleRate
    // voice 发音人,可选,默认是xiaoyun。
    // bodyContent["voice"] = "xiaoyun"
    // volume 音量,范围是0~100,可选,默认50。
    // bodyContent["volume"] = 50
    // speech_rate 语速,范围是-500~500,可选,默认是0。
    // bodyContent["speech_rate"] = 0
    // pitch_rate 语调,范围是-500~500,可选,默认是0。
    // bodyContent["pitch_rate"] = 0
    bodyJson, err := json.Marshal(bodyContent)
    if err != nil {
        panic(nil)
    }
    fmt.Println(string(bodyJson))
    /**
     * 发送HTTPS POST请求,处理服务端的响应。
     */
    response, err := http.Post(url, "application/json;charset=utf-8", bytes.NewBuffer([]byte(bodyJson)))
    if err != nil {
        panic(err)
    }
    defer response.Body.Close()
    contentType := response.Header.Get("Content-Type")
    body, _ := ioutil.ReadAll(response.Body)
    if ("audio/mpeg" == contentType) {
        file, _ := os.Create(audioSaveFile)
        defer file.Close()
        file.Write([]byte(body))
        fmt.Println("The POST request succeed!")
    } else {
        // ContentType 为 null 或者为 "application/json"
        statusCode := response.StatusCode
        fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode))
        fmt.Println("The POST request failed: " + string(body))
    }    
}
func main() {
    var appkey string = "您的appkey"
    var token  string = "您的token"
    var text string = "今天是周一,天气挺好的。"
    var textUrlEncode = text
    textUrlEncode = url.QueryEscape(textUrlEncode)
    textUrlEncode = strings.Replace(textUrlEncode, "+", "%20", -1)
    textUrlEncode = strings.Replace(textUrlEncode, "*", "%2A", -1)
    textUrlEncode = strings.Replace(textUrlEncode, "%7E", "~", -1)
    fmt.Println(textUrlEncode)
    var audioSaveFile string = "syAudio.wav"
    var format string = "wav"
    var sampleRate int = 16000
    processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate)
    // processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate)
}