语音合成(流式版)WebAPI 文档

接口说明

语音合成流式接口将文字信息转化为声音信息,同时提供了众多极具特色的发音人(音库)供您选择,可以在 这里 在线体验发音人效果。
该语音能力是通过Websocket API的方式给开发者提供一个通用的接口。Websocket API具备流式传输能力,适用于需要流式数据传输的AI服务场景。相较于SDK,API具有轻量、跨语言的特点;相较于HTTP API,Websocket API协议有原生支持跨域的优势。

原WebAPI普通版本接口(http[s]: //api.xfyun.cn/v1/service/v1/tts) 不再对外开放,已经使用WebAPI普通版本的用户仍可使用,同时也欢迎体验新版流式接口并尽快完成迁移~

小语种及少数民族方言

  • 目前新增:韩语、日语、维吾尔语、藏语、法语、俄语、西班牙语、印地语、德语、越南语、巴西葡萄牙语、意大利语、葡萄牙语、泰语、乌尔都语;
  • 使用小语种时上传文本编码必须使用unicode编码且设置tte=unicode(unicode即utf16小端的编码方式)或者使用UTF8的编码方式;
  • 需先在控制台开启小语种发音人才可合成小语种,否则报错11200。

接口Demo

示例demo请点击 这里 下载。
目前仅提供部分开发语言的demo,其他语言请参照下方接口文档进行开发。
也欢迎热心的开发者到 讯飞开放平台社区 分享你们的demo。

接口要求

集成在线语音合成流式API时,需按照以下要求。

内容 说明
请求协议 ws[s](为提高安全性,强烈推荐wss)
请求地址 ws[s]: //tts-api.xfyun.cn/v2/tts
请求行 GET /v2/tts HTTP/1.1
接口鉴权 签名机制,详情请参照下方接口鉴权
字符编码 UTF8、GB2312、GBK、BIG5、UNICODE、GB18030
响应格式 统一采用JSON格式
开发语言 任意,只要可以向讯飞云服务发起Websocket请求的均可
操作系统 任意
音频属性 采样率16k或8k
音频格式 pcm、mp3、speex(8k)、speex-wb(16k)
文本长度 单次调用长度需小于8000字节(约2000汉字)
发音人 中英粤多语种、川豫多方言、小语种、男女声多风格,可以在 这里 在线体验发音人效果

接口调用流程

  • 通过接口密钥基于hmac-sha256计算签名,向服务器端发送Websocket协议握手请求。详见下方 接口鉴权
  • 握手成功后,客户端通过Websocket连接同时上传和接收数据。数据上传完毕,客户端需要上传一次数据结束标识。详见下方 接口数据传输与接收
  • 接收到服务器端的结果全部返回标识后断开Websocket连接。

注: Websocket使用注意事项如下

  1. 服务端支持的websocket-version 为13,请确保客户端使用的框架支持该版本。
  2. 服务端返回的所有的帧类型均为TextMessage,对应于原生websocket的协议帧中opcode=1,请确保客户端解析到的帧类型一定为该类型,如果不是,请尝试升级客户端框架版本,或者更换技术框架。
  3. 如果出现分帧问题,即一个json数据包分多帧返回给了客户端,导致客户端解析json失败。出现这种问题大部分情况是客户端的框架对websocket协议解析存在问题,如果出现请先尝试升级框架版本,或者更换技术框架。
  4. 客户端会话结束后如果需要关闭连接,尽量保证传给服务端的错误码为websocket错误码1000(如果客户端框架没有提供关闭时传错误码的接口。则无需关注本条)。

白名单

默认关闭IP白名单,即该服务不限制调用IP。
在调用该业务接口时

  • 若关闭IP白名单,接口认为IP不限,不会校验IP。
  • 若打开IP白名单,则服务端会检查调用方IP是否在讯飞开放平台配置的IP白名单中,对于没有配置到白名单中的IP发来的请求,服务端会拒绝服务。

IP白名单规则

  • 在 控制台-相应服务的IP白名单处编辑,保存后五分钟左右生效。
  • 不同Appid的不同服务都需要分别设置IP白名单。
  • IP白名单需设置为外网IP,请勿设置局域网IP;
  • 如果握手阶段返回{"message":"Your IP address is not allowed"},则表示由于IP白名单配置有误或还未生效,服务端拒绝服务。

接口鉴权

在握手阶段,请求方需要对请求进行签名,服务端通过签名来校验请求的合法性。

鉴权方法

通过在请求地址后面加上鉴权相关参数的方式。示例url:

wss://tts-api.xfyun.cn/v2/tts?authorization=aG1hYyB1c2VybmFtZT0iZGE0ZjMyOWUyZmQwMGQ1NjE4NjVjNjRkZjU3NDNiMjAiLCBhbGdvcml0aG09ImhtYWMtc2hhMjU2IiwgaGVhZGVycz0iaG9zdCBkYXRlIHJlcXVlc3QtbGluZSIsIHNpZ25hdHVyZT0ic1RtbzRobDBMdmRLWTRLRjltcGJKV0htRFFzNC8xZ2ZPdUgwZnBZbVdnbz0i&date=Thu%2C%2001%20Aug%202019%2001%3A53%3A21%20GMT&host=tts-api.xfyun.cn

鉴权参数:

参数 类型 必须 说明 示例
host string 请求主机 tts-api.xfyun.cn
date string 当前时间戳,RFC1123格式 Thu, 01 Aug 2019 01:53:21 GMT
authorization string 使用base64编码的签名相关信息(签名基于hmac-sha256计算) 参考下方authorization参数生成规则

· date参数生成规则

date必须是UTC+0或GMT时区,RFC1123格式(Thu, 01 Aug 2019 01:53:21 GMT)。
服务端会对Date进行时钟偏移检查,最大允许300秒的偏差,超出偏差的请求都将被拒绝。

· authorization参数生成规则

1)获取接口密钥APIKey 和 APISecret。
在讯飞开放平台控制台,创建应用进入语音合成(流式版)服务后即可查看,均为32位字符串。

2)参数authorization base64编码前(authorization_origin)的格式如下。

api_key="$api_key",algorithm="hmac-sha256",headers="host date request-line",signature="$signature"

其中 api_key 是在控制台获取的APIKey,algorithm 是加密算法(仅支持hmac-sha256),headers 是参与签名的参数(见下方注释)。
signature 是使用加密算法对参与签名的参数签名后并使用base64编码的字符串,详见下方。

注: headers是参与签名的参数,请注意是固定的参数名("host date request-line"),而非这些参数的值。

3)signature的原始字段(signature_origin)规则如下。

signature原始字段由 host,date,request-line三个参数按照格式拼接成,
拼接的格式为(\n为换行符,’:’后面有一个空格):

host: $host\ndate: $date\n$request-line

假设

请求url = wss://tts-api.xfyun.cn/v2/tts
date = Thu, 01 Aug 2019 01:53:21 GMT

那么 signature原始字段(signature_origin)则为:

host: tts-api.xfyun.cn
date: Thu, 01 Aug 2019 01:53:21 GMT
GET /v2/tts HTTP/1.1

4)使用hmac-sha256算法结合apiSecret对signature_origin签名,获得签名后的摘要signature_sha。

signature_sha=hmac-sha256(signature_origin,$apiSecret)

其中 apiSecret 是在控制台获取的APISecret

5)使用base64编码对signature_sha进行编码获得最终的signature。

signature=base64(signature_sha)

假设

APISecret = secretxxxxxxxx2df7900c09xxxxxxxx	
date = Thu, 01 Aug 2019 01:53:21 GMT

则signature为

signature=sTmo4hl0LvdKY4KF9mpbJWHmDQs4/1gfOuH0fpYmWgo=

6)根据以上信息拼接authorization base64编码前(authorization_origin)的字符串,示例如下。

api_key="keyxxxxxxxx8ee279348519exxxxxxxx", algorithm="hmac-sha256", headers="host date request-line", signature="sTmo4hl0LvdKY4KF9mpbJWHmDQs4/1gfOuH0fpYmWgo="

注: headers是参与签名的参数,请注意是固定的参数名("host date request-line"),而非这些参数的值。

7)最后再对authorization_origin进行base64编码获得最终的authorization参数。

authorization = base64(authorization_origin)
示例:
authorization=aG1hYyB1c2VybmFtZT0iZGE0ZjMyOWUyZmQwMGQ1NjE4NjVjNjRkZjU3NDNiMjAiLCBhbGdvcml0aG09ImhtYWMtc2hhMjU2IiwgaGVhZGVycz0iaG9zdCBkYXRlIHJlcXVlc3QtbGluZSIsIHNpZ25hdHVyZT0ic1RtbzRobDBMdmRLWTRLRjltcGJKV0htRFFzNC8xZ2ZPdUgwZnBZbVdnbz0i

鉴权url示例(golang)

    //@hosturl :  like  wss://tts-api.xfyun.cn/v2/tts
    //@apikey : apiKey
    //@apiSecret : apiSecret
    func assembleAuthUrl(hosturl string, apiKey, apiSecret string) string {
        ul, err := url.Parse(hosturl)
        if err != nil {
            fmt.Println(err)
        }
        //签名时间
        date := time.Now().UTC().Format(time.RFC1123)
        //参与签名的字段 host ,date, request-line
        signString := []string{"host: " + ul.Host, "date: " + date, "GET " + ul.Path + " HTTP/1.1"}
        //拼接签名字符串
        sgin := strings.Join(signString, "\n")
        //签名结果
        sha := HmacWithShaTobase64("hmac-sha256", sgin, apiSecret)
        //构建请求参数 此时不需要urlencoding
        authUrl := fmt.Sprintf("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey,
            "hmac-sha256", "host date request-line", sha)
        //将请求参数使用base64编码
        authorization:= base64.StdEncoding.EncodeToString([]byte(authUrl))
        v := url.Values{}
        v.Add("host", ul.Host)
        v.Add("date", date)
        v.Add("authorization", authorization)
        //将编码后的字符串url encode后添加到url后面
        callurl := hosturl + "?" + v.Encode()
        return callurl
    }

鉴权结果

如果握手成功,会返回HTTP 101状态码,表示协议升级成功;如果握手失败,则根据不同错误类型返回不同HTTP Code状态码,同时携带错误描述信息,详细错误说明如下:

HTTP Code 说明 错误描述信息 解决方法
401 缺少authorization参数 {“message”:”Unauthorized”} 检查是否有authorization参数,详情见authorization参数详细生成规则
401 签名参数解析失败 {“message”:”HMAC signature cannot be verified”} 检查签名的各个参数是否有缺失是否正确,特别确认下复制的api_key是否正确
401 签名校验失败 {“message”:”HMAC signature does not match”} 签名验证失败,可能原因有很多。
1. 检查api_key,api_secret 是否正确。
2.检查计算签名的参数host,date,request-line是否按照协议要求拼接。
3. 检查signature签名的base64长度是否正常(正常44个字节)。
403 时钟偏移校验失败 {“message”:”HMAC signature cannot be verified, a valid date or x-date header is required for HMAC Authentication”} 检查服务器时间是否标准,相差5分钟以上会报此错误
403 IP白名单校验失败 {"message":"Your IP address is not allowed"} 可在控制台关闭IP白名单,或者检查IP白名单设置的IP地址是否为本机外网IP地址

握手失败返回示例:

    HTTP/1.1 401 Forbidden
    Date: Thu, 06 Dec 2018 07:55:16 GMT
    Content-Length: 116
    Content-Type: text/plain; charset=utf-8
    {
        "message": "HMAC signature does not match"
    }

接口数据传输与接收

握手成功后客户端和服务端会建立websocket连接,客户端通过websocket连接可以同时上传和接收数据。

客户端每次会话只用发送一次文本数据和参数,引擎有合成结果时会推送给客户端。当引擎的数据合成完毕时,会返回结束标识,具体为:

{
  "data":{
      ....#其他参数
      "status":2
  }  
}

请求参数

请求数据均为json字符串

参数名 类型 必传 描述
common object 公共参数,详见下方
business object 业务参数,详见下方
data object 业务数据流参数,详见下方

公共参数说明(common)

参数名 类型 必传 描述
app_id string 在平台申请的APPID信息

业务参数说明(business)

参数名 类型 必传 描述 示例
aue string 音频编码,可选值:
raw:未压缩的pcm
lame:mp3 (当aue=lame时需传参sfl=1)
speex-org-wb;7: 标准开源speex(for speex_wideband,即16k)数字代表指定压缩等级(默认等级为8)
speex-org-nb;7: 标准开源speex(for speex_narrowband,即8k)数字代表指定压缩等级(默认等级为8)
speex;7:压缩格式,压缩等级1~10,默认为7(8k讯飞定制speex)
speex-wb;7:压缩格式,压缩等级1~10,默认为7(16k讯飞定制speex)
"raw"
"speex-org-wb;7" 数字代表指定压缩等级(默认等级为8),数字必传
标准开源speex编码以及讯飞定制speex说明请参考音频格式说明
sfl int 需要配合aue=lame使用,开启流式返回
mp3格式音频
取值:1 开启
1
auf string 音频采样率,可选值:
audio/L16;rate=8000:合成8K 的音频
audio/L16;rate=16000:合成16K 的音频
auf不传值:合成16K 的音频
"audio/L16;rate=16000"
vcn string 发音人,可选值:请到控制台添加试用或购买发音人,添加后即显示发音人参数值 "xiaoyan"
speed int 语速,可选值:[0-100],默认为50 50
volume int 音量,可选值:[0-100],默认为50 50
pitch int 音高,可选值:[0-100],默认为50 50
bgs int 合成音频的背景音
0:无背景音(默认值)
1:有背景音
0
tte string 文本编码格式
GB2312
GBK
BIG5
UNICODE(小语种必须使用UNICODE编码,合成的文本需使用utf16小端的编码方式,详见java示例demo)
GB18030
UTF8(小语种)
"UTF8"
reg string 设置英文发音方式:
0:自动判断处理,如果不确定将按照英文词语拼写处理(缺省)
1:所有英文按字母发音
2:自动判断处理,如果不确定将按照字母朗读
默认按英文单词发音
"2"
rdn string 合成音频数字发音方式
0:自动判断(默认值)
1:完全数值
2:完全字符串
3:字符串优先
"0"

业务参数说明(data)

参数名 类型 必传 描述
text string 文本内容,需进行base64编码;
base64编码前最大长度需小于8000字节,约2000汉字
status int 数据状态,固定为2
:由于流式合成的文本只能一次性传输,不支持多次分段传输,此处status必须为2。

请求参数示例:

{
  "common": {
    "app_id": "12345678"
  },
  "business": {
    "aue": "raw",
    "vcn": "xiaoyan",
    "pitch": 50,
    "speed": 50
  },
  "data": {
    "status": 2,
    "text": "5q2j5Zyo5Li65oKo5p+l6K+i5ZCI6..."
  }
}

数据上传结束标识示例:

    {
    "data":{
      "status":2
        }
    }

返回参数说明:

参数名 类型 描述
code int 返回码,0表示成功,其它表示异常,详情请参考错误码
message string 描述信息
data object data可能返回为null,参考示例代码时,注意进行非空判断
data.audio string 合成后的音频片段,采用base64编码
data.status int 当前音频流状态,1表示合成中,2表示合成结束
data.ced string 合成进度,指当前合成文本的字节数
:请注意合成是以句为单位切割的,若文本只有一句话,则每次返回结果的ced是相同的。
sid string 本次会话的id,只在第一帧请求时返回

返回参数示例

    {
        "code":0,
        "message":"success",
        "sid":"ttsxxxxxxxxxxx",
        "data":{
            "audio":"QAfe..........",
            "ced":"14",
            "status":2
        }
    }

注意事项

1.服务端可能返回data为空的帧,并且错误码为0,这种帧客户端可以直接忽略,不解析。
2.合成返回的帧长度较大,服务端是可能会出现一个消息分为多个websocket 帧返回给客户端。这个时候客户端需要合并这些帧,当然这些大多数框架已经实现的这个逻辑,不排除少部分框架没有做这个逻辑,导致解析失败。
3.合成的音频是无意义的音频,这种情况大多是客户端用的字符编码格式和参数中传的不一致。请确保tte传的值和文本编码格式保持一致
4.合成的音频效果不是期望的效果,可以通过更换发音人解决,(部分发音人需要开通权限!)
5.小语种文本须使用Unicode编码,且tte=Unicode或者UTF8编码。

错误码

备注:如出现下述列表中没有的错误码,可到 这里 查询。

错误码 错误描述 说明 处理方式
10005 licc fail appid授权失败 确认appid是否正确,是否开通了合成服务
10006 Get audio rate fail 请求缺失必要参数 检查报错信息中的参数是否正确上传
10007 get invalid rate 请求的参数值无效 检查报错信息中的参数值是否在取值范围内
10010 AIGES_ERROR_NO_LICENSE 引擎授权不足 请到控制台提交工单联系技术人员
10109 AIGES_ERROR_INVALID_DATA 请求文本长度非法 检查是否文本长度超出了限制
10019 service read buffer timeout, session timeout session超时 检查是否数据发送完毕但未关闭连接
10101 engine inavtive 引擎会话已结束 检查是否引擎已结束会话但客户端还在发送数据,比如音频数据虽然发送完毕但并未关闭websocket连接,还在发送空的音频等
10313 appid cannot be empty appid不能为空 检查common参数是否正确上传,或common中的app_id参数是否正确上传或是否为空
10317 invalid version 版本非法 联系技术人员
11200 auth no license 没有权限 检查是否使用了未授权的发音人,或者总的调用次数已超越上限
11201 auth no enough license 日流控超限 可联系商务提高每日调用次数
10160 parse request json error 请求数据格式非法 检查请求数据是否是合法的json
10161 parse base64 string error base64解码失败 检查发送的数据是否使用了base64编码
10163 param validate error:... 缺少必传参数,或者参数不合法,具体原因见详细的描述 1)检查报错信息中的参数是否正确上传
2)检查上传的文本是不是已超过最大限制
10200 read data timeout 读取数据超时 检查是否累计10s未发送数据并且未关闭连接
10222 context deadline exceeded 网络异常 1)检查网络是否异常
2)调用超时,如果使用的是mp3格式的话,要传sfl=1来开启流式返回mp3的功能,否则文本长度过长就可能会超时。

调用示例

注: demo只是一个简单的调用示例,不适合直接放在复杂多变的生产环境使用

语音合成流式API demo java语言

语音合成流式API demo python3语言

语音合成流式API demo js语言

语音合成流式API demo nodejs语言

讯飞开放平台AI能力-JAVASDK: Github地址

讯飞开放平台AI能力-PHPSDK: Github地址

注: 其他开发语言请参照 接口调用流程 进行开发,也欢迎热心的开发者到 讯飞开放平台社区 分享你们的demo。

视频教程

在线语音合成-WebAPI

常见问题

在线合成背景音乐可以替换吗?

答:合成的背景音乐是不能替换的,只能通过BGS参数来控制是否播放背景音乐。

WebAPI在线合成报11200授权错误

答:这个问题一般是使用了未授权的发音人,请到控制台检查是否所用发音人未添加,或授权已到期;另外,若总合成交互量超过上限也会报错11200。

WebAPI在线合成支持保存的音频的格式

答:支持保存pcm、mp3、speex格式的音频。

错误码及相应解决方案查询网址

答:错误码及相应解决方案查询

在线语音合成的字节有什么限制要求?

答:WebAPI接口一次限制8000字节,超长文本按照自然段切分,分多次合成请求进行。

在线语音合成如何在指定的文本处标记静音停顿?

答:有如下两种设置方式,详细可以参考论坛说明
cssml方法:
(1)对于发音人xiaoyan、xiaoyu、xiaofeng、xiaoqi、catherine、mary需使用cssml方法进行静音标记,并且不支持unicode文本编码。
(2)在business中添加参数ttp值为cssml。
(3)在指定文本位置添加静音标记,如:风<break time="500ms"/>轻轻摇着树梢。
简单标记方法:
(1)“除去”cssml方法列举的发音人以外,均可以使用简单标记法。
(2)在指定文本位置添加静音标记,如:你好[p500]科大讯飞。