语音合成RESTfulAPI 您所在的位置:网站首页 阿里云语音转文字vue 语音合成RESTfulAPI

语音合成RESTfulAPI

2023-11-21 17:11| 来源: 网络整理| 查看: 265

功能介绍

支持如下设置:

PCM、WAV、MP3音频格式。

8000 Hz、16000 Hz采样率。

多种发音人。

语速、语调、音量。

重要

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

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

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

前提条件

已准备项目Appkey,详情请参见创建项目。

已获取Access Token,详情请参见获取Token概述。

服务地址

访问类型

说明

URL

Host

外网访问(默认上海地域)

所有服务器均可使用外网访问URL。

上海:nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

北京:nls-gateway-cn-beijing.aliyuncs.com/stream/v1/tts

深圳:nls-gateway-cn-shenzhen.aliyuncs.com/stream/v1/tts

上海:nls-gateway-cn-shanghai.aliyuncs.com

北京:nls-gateway-cn-beijing.aliyuncs.com

深圳:nls-gateway-cn-shenzhen.aliyuncs.com

ECS内网访问

使用阿里云上海、北京、深圳ECS(即ECS地域为华东2(上海)、华北2(北京)、华南1(深圳)),可使用内网访问URL。 ECS的经典网络不能访问AnyTunnel,即不能在内网访问语音服务;如果希望使用AnyTunnel,需要创建专有网络在其内部访问。

说明

使用内网访问方式,将不产生ECS实例的公网流量费用。

关于ECS的网络类型请参见网络类型。

上海:nls-gateway-cn-shanghai-internal.aliyuncs.com/stream/v1/tts

北京:nls-gateway-cn-beijing-internal.aliyuncs.com/stream/v1/tts

深圳:nls-gateway-cn-shenzhen-internal.aliyuncs.com/stream/v1/tts

上海:nls-gateway-cn-shanghai-internal.aliyuncs.com

北京:nls-gateway-cn-beijing-internal.aliyuncs.com

深圳:nls-gateway-cn-shenzhen-internal.aliyuncs.com

重要

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

交互流程

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

image说明

服务端的响应除了音频流之外,都会在返回信息的header包含本次识别任务的task_id参数,是本次请求的唯一标识。

请求参数

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

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

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

名称

类型

是否必选

描述

appkey

String

项目appkey。

text

String

待合成的文本,需要为UTF-8编码。使用GET方法,需要再采用RFC 3986规范进行urlencode编码;使用POST方法不需要urlencode编码。

token

String

若不设置token参数,需要在HTTP Headers中设置X-NLS-Token字段来指定Token。

format

String

音频编码格式,支持PCM/WAV/MP3格式。默认值:pcm。

sample_rate

Integer

音频采样率,支持16000 Hz和8000 Hz,默认值:16000 Hz。

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

nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

GET

请求参数

参见上述请求参数。由URL和请求参数组成的完整请求链接如下所示(需对参数进行URL encode),在浏览器中打开该链接可直接获取语音合成结果:

# 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-Token

String

服务鉴权Token。

重要

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

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

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

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

POST方法上传文本

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

URL

协议

URL

方法

HTTPS

nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

POST

HTTPS POST请求头部

名称

类型

是否必选

描述

Content-Type

String

必须为“application/json”。表明HTTP请求体的内容为JSON格式字符串。

X-NLS-Token

String

服务鉴权Token。

Content-Length

long

HTTP请求体中内容的长度。

HTTPS POST请求体

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

{ "appkey":"31f932fb", "text":"今天是周一,天气挺好的。", "token":"450343c793aaaaaa****", "format":"wav" }重要

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

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

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

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

响应结果

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

成功响应

HTTPS Headers的Content-Type字段内容为audio/mpeg,表示合成成功,合成的语音数据在响应体中。

响应内容为合成音频的二进制数据。

失败响应

HTTPS Headers没有Content-Type字段,或者Content-Type字段内容为application/json,表示合成失败,错误信息在响应体中。

HTTPS Headers的X-NLS-RequestId字段内容为请求任务的task_id。

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

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

错误信息字段如下表

名称

类型

描述

task_id

String

32位请求任务ID,请记录该值,用于排查错误。

result

String

服务结果

status

Integer

服务状态码

message

String

服务状态描述

服务状态码

服务状态码

服务状态描述

解决办法

20000000

请求成功

无。

40000000

默认的客户端错误码

检查对应的错误消息。

40000001

身份认证失败

检查使用的令牌是否正确,是否过期。

40000002

无效的消息

检查发送的消息是否符合要求。

40000003

无效的参数

检查参数值设置是否合理。

40000004

空闲超时

确认是否长时间没有发送数据到服务端。

40000005

请求数量过多

检查是否超过了并发连接数或者每秒钟请求数。

40000010

试用期已结束,并且未开通商用版、或账户欠费。

请登录控制台确认服务开通状态以及账户余额。

50000000

默认的服务端错误

内部服务错误,需要客户端进行重试。

50000001

内部GRPC调用错误

内部服务错误,需要客户端进行重试。

Java示例

依赖文件内容如下:

com.squareup.okhttp3 okhttp 3.9.1 com.alibaba fastjson 1.2.83 org.asynchttpclient async-http-client 2.5.4

示例代码如下:

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: "); 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 */ 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); 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 handler = new AsyncHandler() { 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: "); 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请求体的JSON字符串。

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

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

示例目录说明如下:

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

demo:示例文件。

文件名

描述

restfulTtsDemo.cpp

语音合成RESTful API示例。

include

目录名

描述

curl

curl库头文件目录。

json

jsoncpp库头文件目录。

lib:包含curl、jsoncpp动态库。

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

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

windows(VS2013、VS2015)

readme.txt:说明文件。

release.log:更新记录。

version:版本号。

build.sh:示例编译脚本。

编译运行操作步骤:

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

支持Cmake:

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

cd path/to/sdk/lib。

tar -zxvpf linux.tar.gz。

cd path/to/sdk。

./build.sh。

cd path/to/sdk/demo。

./restfulTtsDemo 。

不支持Cmake:

cd path/to/sdk/lib。

tar -zxvpf linux.tar.gz。

cd path/to/sdk/demo。

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。

export LD_LIBRARY_PATH=path/to/sdk/lib/linux/。

./restfulTtsDemo 。

示例代码如下:

#ifdef _WIN32 #include #endif #include #include #include #include #include #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 *headers = (map*)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


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有