logo
电话400 898 2016
预约试用
开放平台
En
尊敬的开发者,您好! 标贝科技的开发文档已更换新的地址,旧版文档地址将会在2023年12月31日下线, 给您带来不便,敬请谅解! 立即查看
产品简介 产品简介
基本概念 基本概念
平台新手指引 平台新手指引
计价模式 计价模式
开发者文档下拉
开放平台计价
定制服务计价
获取访问令牌 获取访问令牌
语音合成 语音合成
开发者文档下拉
接口说明
发音人列表
短文本合成 开发者文档下拉
Android SDK
iOS SDK
C++(Linux) SDK
RESTful API
Websocket API
长文本合成 开发者文档下拉
长文本合成RESTful API
长文本合成Websocket API
离线合成 开发者文档下拉
模型文件说明
离线合成(普通版) Android SDK
离线合成(普通版) iOS SDK
离线合成(精品版) Android SDK
离线合成(精品版) iOS SDK
XML标签
SSML标签
语音合成时间戳功能
语音识别 语音识别
开发者文档下拉
音频格式说明
一句话识别 开发者文档下拉
RESTful API
Websocket API
Android SDK
iOS SDK
实时长语音识别 开发者文档下拉
Websocket API
Android SDK
iOS SDK
录音文件识别 开发者文档下拉
RESTful API
自学习工具 开发者文档下拉
热词
个性化模型
声音复刻 声音复刻
开发者文档下拉
定制模型 开发者文档下拉
RESTful API
Android SDK
iOS SDK
定制声音合成 开发者文档下拉
短文本合成RESTful API
长文本合成Websocket API
声音转换 声音转换
开发者文档下拉
发音人列表
Websocket API
Android SDK
iOS SDK
离线声音转换 离线声音转换
开发者文档下拉
发音人列表
Android SDK
iOS SDK
声纹识别 声纹识别
开发者文档下拉
RESTful API
声音理解 声音理解
开发者文档下拉
RESTful API
协议规则 协议规则
开发者文档下拉
平台服务协议
平台通用规则
法律声明及隐私政策
服务等级协议SLA
常见问题 常见问题
开发者文档下拉
语音合成
语音识别

短文本合成RESTful API

功能介绍

语音合成RESTful API支持HTTPS GET和POST两种方法的请求,将待合成的文本上传到服务端,服务端返回语音合成结果。随着TTS合成效果的不断提升,算法的复杂度也越来越高,对用户而言,可能会遇到合成耗时变长的可能。因此我们建议您使用流式合成机制。

参数设置

  • 支持设置合成音频的格式:pcm,wav,mp3,alaw,ulaw
  • 支持设置合成音频的采样率: 8000Hz,16000Hz,24000Hz
  • 支持设置多种发音人
  • 支持设置音量、语速、语调
  • 支持返回时间戳信息
  • 支持设置多种语言:中文(zh),英文(eng),粤语(cat),四川话(sch),天津话(tjh),台湾话(tai),韩语(kr),巴葡语(bra),日语(jp),西班牙西语(ESP),墨西哥西语(MEX),维吾尔语(UYG)

使用方法

1. 创建账号和应用,详见平台新手指引,通过标贝开放平台/应用/服务获取client_id,client_secret

2. 发送请求获取access_token,详见获取访问令牌

3. 发送请求:发送语音合成请求,具体参数详见 请求参数

4. 接收返回结果:检查http 响应头Content-Type判断合成请求是否成功,如返回Content-Type以audio开头说明合成成功,响应体为音频数据。如返回Content-Type: application/json说明合成出现错误,响应体为json,具体参数定义详见 响应结果说明。

服务地址

访问类型 说明 URL Host
外网访问 所有音色 https://openapi.data-baker.com/tts openapi.data-baker.com

交互流程

请求参数

参数名称 是否必填 名称 说明
text 合成文本 合成的文本,使用UTF-8编码,如果用户在非浏览器上操作,则需要把合成文本转化为utf-8格式。
GET 方法一次请求最多不超过300个汉字
POST 方法一次请求最多不超过300个汉字
access_token 用户访问token 通过client_id,client_secret调用授权服务获得见获取访问令牌
domain 领域 应用所属领域如导航、客服等,以数字进行编码,目前值固定为1,必填
language 文本语言 合成请求文本的语言:
ZH(中文和中英混)
ENG(纯英文,中文部分不会合成)
CAT(粤语)
SCH(四川话)
TJH(天津话)
TAI(台湾话)
KR(韩语)
BRA(巴葡语)
JP(日语)
ESP(西班牙西语)
MEX(墨西哥西语)
UYG(维吾尔语)
speed 语速 设置播放的语速,在0~9之间(支持浮点值),不传时默认为5
volume 音量 设置语音的音量,在0~9之间(只支持整型值),不传时默认为5
pitch 音调 设置语音的音调,取值0-9,不传时默认为5中语调
audiotype 音频种类 可不填,不填时默认为3,表示mp3格式
audiotype=3 :返回16K采样率的mp3格式
audiotype=4 :返回16K采样率的pcm格式
audiotype=5 :返回8K采样率的pcm格式
audiotype=6 :返回16K采样率的wav格式
audiotype=6&rate=1 :返回8K的wav格式
audiotype=7 :返回8k8bit的alaw格式文件
audiotype=8 :返回8k8bit的ulaw格式文件
audiotype=9&rate=1 返回8K采样率的mp3
audiotype=9&rate=3,返回24k采样率的mp3格式
audiotype=6&rate=3,返回24k采样率的wav格式
audiotype=5&rate=3,返回24k采样率的pcm格式
rate 码率 可不填,不填时默认为2,取值范围1-8,2以上的值仅针对返回MP3格式,对应的码率为:
1 —— 8kbps
2 —— 16kbps
3 —— 24kbps
4 —— 32kbps
5 —— 40kbps
6 —— 48kbps
7 —— 56kbps
8 —— 64kbps
voice_name 发音人 发音人选择,直接输入英文名称 例如:Jiaojiao。详见发音人列表
spectrum 频谱 取值范围0~20;不传时默认为不调整频谱;
值为0代表使用配置文件tts_attention.conf中spec_adjust_d的值;
1代表不调整频谱;
1以上的值代表高频能量增加幅度,值越大声音的高频部分增强越多,听起来更亮和尖细
spectrum_8k 低频部分频谱 取值范围0~20;不传时默认为0,仅针对8K音频频谱的调整。
interval 音子边界时间戳 音子级别时间戳功能:
'0':关闭音子级别时间戳功能
'1':开启音子级别时间戳功能
enable_subtitles 字级别时间戳 字级别时间戳功能,同interval=”1”一起使用:
'0':关闭字级别时间戳功能
'1':开启字级别时间戳功能
详细使用方法参考语音合成时间戳
silence 标点符号静音时长 设置标点符号静音时长:
'0':默认值
'1':句中标点停顿较短,适合直播、配音解说等场景
'2':句中标点停顿较长,适合朗诵、教学等场景
emo_type string 是(请求情感音色时) 在请求情感音色时,该参数是必填项。请求情感音色不存在的情感会报错。可选值参考 发音人列表-多情感/风格音色,如:sad
emo_intensity string 设置情感强度,在1~5之间(只支持整型值),不传时默认为3。

请求示例

1. GET方法
curl  –get  --data-urlencode "text=标贝科技" "https://openapi.data-baker.com/tts?access_token=your_access_token&domain=1&language=zh&voice_name=Jiaojiao"
2. POST方法
curl -X POST https://openapi.data-baker.com/tts -d "access_token=default&domain=1&language=zh&voice_name=Jiaojiao&text=标贝科技"

Python示例代码

代码地址:Github

Python3示例:

#!/usr/bin/env python
# coding: utf-8
import requests
import json
import argparse

# 获取access_token用于鉴权
def get_access_token(client_secret, client_id):
    grant_type = "client_credentials"
    url = "https://openapi.data-baker.com/oauth/2.0/token?grant_type={}&client_secret={}&client_id={}".format(grant_type, client_secret, client_id)
    response = requests.post(url)
    access_token = json.loads(response.text).get('access_token')

    return access_token

# 获取转换后音频
def get_audio(data):
    url = "https://openapi.data-baker.com/tts?access_token={}&domain={}&language={}&voice_name={}&text={}&audiotype={}".format(data['access_domain'], data['domain'], data['language'], data['voice_name'], data['text'], data['audiotype'])
    response = requests.post(url)
    content_type = response.headers['Content-Type']
    if 'audio' not in content_type:
        raise Exception(response.text)
    return response.content

# 获取命令行输入参数
def get_args():
    text = '欢迎使用标贝开发平台。'
    parser = argparse.ArgumentParser(description='ASR')
    parser.add_argument('-client_secret', type=str, required=True)
    parser.add_argument('-client_id', type=str, required=True)
    parser.add_argument('-file_save_path', type=str, required=True)
    parser.add_argument('--text', type=str, default=text)
    parser.add_argument('--audiotype', type=str, default='6')
    parser.add_argument('--domain', type=str, default='1')
    parser.add_argument('--language', type=str, default='zh')
    parser.add_argument('--voice_name', type=str, default='Jiaojiao')
    args = parser.parse_args()

    return args

if __name__ == '__main__':
    try:
        args = get_args()

        # 获取access_token
        client_secret = args.client_secret
        client_id = args.client_id
        access_token = get_access_token(client_secret, client_id)

        # 读取参数
        audiotype = args.audiotype
        domain = args.domain
        language = args.language
        voice_name = args.voice_name
        text = args.text
        data = {'access_domain': access_token, 'audiotype': audiotype, 'domain': domain, 'language': language, 'voice_name': voice_name, 'text': text}
        content = get_audio(data)

        #保存音频文件
        with open('test.wav', 'wb') as audio:
            audio.write(content)
        print("task finished successfully")
    except Exception as e:
        print(e)
      

命令行执行

python online_tts.py -client_secret=你的client_secret -client_id=你的client_secret -file_save_path=test.wav --text=今天天气不错哦

如有需要可自行修改参数

python online_tts.py -client_secret=你的client_secret -client_id=你的client_secret -file_save_path=test.wav --text=今天天气不错哦 --audiotype=6

JAVA示例代码

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;


public class JavaTtsRestDemo {

    /**
     * 合成使用的地址信息,rate、language等参数在本demo固定,开发者如需调整,参考https://www.data-baker.com/specs/file/tts_api_restful
     */
    public static String ttsUrl = "https://openapi.data-baker.com/tts?access_token=%s&domain=1&rate=2&audiotype=%s&language=zh&voice_name=%s&speed=%s&volume=%s&text=%s";
    /**
     * 获取token的地址信息
     */
    public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s";
    public static String clientId = "YOUR_CLIENT_ID";
    public static String clientSecret = "YOUR_CLIENT_SECRET";

    /**
     * 仅作为demo示例
     * 失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成
     **/
    public static void main(String[] args) {
        String accessToken = getAccessToken();
        if (StringUtils.isNotEmpty(accessToken)) {
            doSynthesis(accessToken, "Nannan", "测试文本", 6, 5.0, 5.0, "/home/tts/test.wav");
        }
    }

    public static void doSynthesis(String accessToken, String voiceName, String originText, Integer audioType, Double speed, Double volume, String filePath) {
        //在非浏览器上操作,需要把合成文本转化为utf-8格式
        try {
            originText = URLEncoder.encode(originText, "utf-8");
            String synthesisUrl = String.format(ttsUrl, accessToken, audioType, voiceName, speed, volume, originText);
            fetchTtsResponse(synthesisUrl, filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 请求并获取音频流保存至本地文件:这里filePath为全路径
     *
     * @param url
     * @param filePath
     * @throws IOException
     */
    public static void fetchTtsResponse(String url, String filePath) throws IOException {
        OkHttpClient client = new OkHttpClient();
        //request 默认是get请求
        Request request = new Request.Builder().url(url).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                if (response.body() != null
                        && response.body().contentType().toString().startsWith("audio")) {
                    //写入文件
                    File targetFile = new File(filePath);
                    Files.write(targetFile.toPath(), response.body().bytes());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getAccessToken() {
        String accessToken = "";
        OkHttpClient client = new OkHttpClient();
        //request 默认是get请求
        String url = String.format(tokenUrl, clientSecret, clientId);
        Request request = new Request.Builder().url(url).build();
        JSONObject jsonObject;
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                //解析
                String resultJson = response.body().string();
                jsonObject = JSON.parseObject(resultJson);
                accessToken = jsonObject.getString("access_token");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return accessToken;
    }
}

PHP示例代码

<?php
//获取访问令牌
$client_secret = '***'; //应用secret
$client_id = '***'; //应用id
$grant_type = 'client_credentials'; //固定格式

//1.获取token
$url = 'https://openapi.data-baker.com/oauth/2.0/token?grant_type='.$grant_type.'&client_id='.$client_id.'&client_secret='.$client_secret;

//curl get请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 检查证书中是否设置域名,0不验证
$token_res = curl_exec($ch);

//如果错误 查看错误信息
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);

//进行token信息解析
$token_info = json_decode($token_res,1);
$access_token = $token_info['access_token'];    //获取到的token信息
//var_dump($access_token);die;
//$access_token = '***';

//2.短文本合成 说明(支持get post方式,本demo使用get方式)
$url = 'https://openapi.data-baker.com/tts?access_token='.$access_token.'&text="PHP是世界上最好的语言,不接受任何反驳"&domain=1&language=zh&voice_name=Jiaojiao';

//curl get请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$audio_info = curl_exec($ch);

//获取请求链接响应头信息
$response_header = curl_getinfo($ch);
if(stripos($response_header['content_type'],'audio') ===false){
    var_dump('合成内容失败');die;
}
//进行合成内容保存
$file_name = './test.mp3';
$res = file_put_contents($file_name,$audio_info);
if($res){
    var_dump('文件保存成功');die;
}

GO示例代码

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
)

type AuthInfo struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
	Scope       string `json:"scope"`
}
type ReqTtsParams struct {
	Domain      string `json:"domain"`
	Interval    string `json:"interval,omitempty"`
	Language    string `json:"language"`
	VoiceName   string `json:"voice_name"`
	Text        string `json:"text"`
	Audiotype   string `json:"audiotype"`
	Version     string `json:"version"`
	Rate        string `json:"rate,omitempty"`
	AccessToken string `json:"access_token"`
}

const grantType string = "client_credentials"

func GetToken(reqUrl, clientId, clientSecret string) (string, error) {
	// 超时时间:60秒
	client := &http.Client{Timeout: 60 * time.Second}
	urlParams := url.Values{}
	urlParams.Add("grant_type", grantType)
	urlParams.Add("client_id", clientId)
	urlParams.Add("client_secret", clientSecret)
	httpUrl := reqUrl
	httpUrl += "?"
	httpUrl += urlParams.Encode()
	fmt.Printf("httpUrl: %s\n\n", httpUrl)
	resp, err := client.Get(httpUrl)
	if err != nil {
		fmt.Printf("send http get token request failed, err: %s\n", err)
		return "", err
	}
	defer resp.Body.Close()
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("http get token request, readall body failed, err: %s\n", err)
		return "", err
	}
	authInfo := AuthInfo{}
	err = json.Unmarshal(result, &authInfo)
	if err != nil {
		fmt.Printf("auth info json.Unmarshal err: %s \n", err)
		return "", err
	}
	if len(authInfo.AccessToken) <= 0 {
		return "", errors.New("access token is null")
	}
	fmt.Printf("get token success. info: %#v \n", authInfo)
	return authInfo.AccessToken, nil
}

func SendTts(URL string, reqParam ReqTtsParams) (string, error) {
	// 超时时间:60秒
	client := &http.Client{Timeout: 60 * time.Second}
	reqUrl := URL
	fmt.Printf("reqUrl: %s\n\n", reqUrl)
	var resp *http.Response
	var err error
	if 0 == strings.Compare("2", reqParam.Version) {
		jsonData, _ := json.Marshal(&reqParam)
		resp, err = client.Post(reqUrl, "application/json", bytes.NewReader(jsonData))
	} else {
		urls := url.Values{}
		urls.Add("text", reqParam.Text)
		urls.Add("voice_name", reqParam.VoiceName)
		urls.Add("access_token", reqParam.AccessToken)
		urls.Add("domain", "1")
		urls.Add("language", "zh")
		urls.Add("interval", reqParam.Interval)
		if strings.Contains(reqParam.VoiceName, "cc") {
			urls.Add("audiotype", "6")
			urls.Add("rate", "1")
		} else {
			if len(reqParam.Audiotype) > 0 {
				urls.Add("audiotype", reqParam.Audiotype)
			}
			if len(reqParam.Rate) > 0 {
				urls.Add("rate", reqParam.Rate)
			}
		}
		reqUrl += "?"
		reqUrl += urls.Encode()
		resp, err = client.Get(reqUrl)
	}
	if err != nil {
		fmt.Printf("send http tts request failed, err: %s \n", err)
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Printf("send http tts request return status code != 200\n")
		return "", errors.New("status code is not 200")
	}
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("readall http body failed, err: %s \n", err)
		return "", err
	}
	contentType := resp.Header.Get("Content-Type")
	if strings.Contains(contentType, "audio/") {
		logid := resp.Header.Get("logid")
		intervalInfo := resp.Header.Get("interval-info")
		intervalInfoX := resp.Header.Get("interval-info-x")
		fmt.Printf("interval:\t%s\ninterval_x:\t%s\n", intervalInfo, intervalInfoX)
		filename := reqParam.VoiceName + "_"
		filename += logid
		filename += "."
		filename += strings.TrimLeft(contentType, "audio/")
		fmt.Printf("output:\t\t%s\n", filename)
		_ = ioutil.WriteFile(filename, result, 0755)
		return "", nil
	}

	return string(result), fmt.Errorf("tts work failed")
}

func main() {
	var (
		clientId, clientSecret, text, voiceName string
		audioType, rate                         int
		interval                                bool
	)
	flag.StringVar(&clientId, "cid", "", "client id")
	flag.StringVar(&clientSecret, "cs", "", "client secret")
	flag.StringVar(&text, "t", "标贝科技", "合成文本")
	flag.StringVar(&voiceName, "v", "Jingjing", "发音人")
	flag.IntVar(&audioType, "audiotype", 6, "audiotype")
	flag.IntVar(&rate, "rate", 0, "rate")
	flag.BoolVar(&interval, "interval", false, "interval")
	flag.Parse()
	if len(os.Args) < 2 {
		flag.Usage()
		return
	}
	if len(clientId) <= 0 || len(clientSecret) <= 0 || len(text) <= 0 || len(voiceName) <= 0 {
		fmt.Println("parameter error!!!")
		return
	}
	accessToken, err := GetToken("https://openapi.data-baker.com/oauth/2.0/token",
		clientId,
		clientSecret,
	)
	if err != nil {
		fmt.Println("get access token failed!!!! please check your client_id and client_secret.")
		return
	}
	param := ReqTtsParams{
		AccessToken: accessToken,
		Text:        text,
		Language:    "ZH",
		Domain:      "1",
		VoiceName:   voiceName,
		Audiotype:   strconv.Itoa(audioType),
		Rate:        strconv.Itoa(rate),
	}
	if interval {
		param.Interval = "1"
	}
	body, err := SendTts("https://openapi.data-baker.com/tts", param)
	if err != nil {
		fmt.Printf("send tts http request failed. result: %s \n", body)
		return
	}
	fmt.Println("send http request success.")
}

C示例代码

代码地址:Github

响应结果

检查http 响应头Content-Type判断合成请求是否成功,如返回Content-Type以audio开头说明合成成功,响应体为音频数据。如返回Content-Type:application/json说明合成出现错误,响应体为json。

1. 成功请求Content-Type示例

a) audiotype=3,返回16K采样率的mp3格式的音频字符串,可根据参数表中的rate参数设置返回的码率,具体header信息 Content-Type: audio/mp3;

b) audiotype=4,返回16K采样率的PCM格式音频,Content-Type: audio/pcm;

c) audiotype=5,返回8K采样率的PCM格式音频,Content-Type: audio/pcm;

d) audiotype=6,返回16K采样率的wav格式音频,Content-Type: audio/wav;

e) audiotype=6&rate=1,返回为8K采样率的wav格式的音频,Content-Type: audio/wav;

f) audiotype=7,返回8K采样率的alaw格式音频,Content-Type: audio/alaw;

g) audiotype=8,返回8K采样率的ulaw格式音频, Content-Type: audio/ulaw;

h) audiotype=9&rate=1,返回8K采样率的mp3格式音频, Content-Type: audio/mp3;

2. interval=1时返回响应头增加interval-info 返回边界音子时间戳

音素类型:

interval-info-x: L=1&T=1,L=1&T=2,L=1&T=1,L=1&T=2,L=1&T=5 L表示语言种类,目前支持1:纯中文,5:中英混 T表示interval类型,0:默认值,1:声母,2:韵母,3:儿化韵母,4:英文,5:#3静音
3. 合成出错请求Content-Type示例:
Content-Type: application/json
{
	"err_msg": "parameter error",
	"err_no": -6101,
	"log_id": 955891560,
	"sn": "914313d3-c9cf-493d-820d-b0e81fdb8bd4"
}

错误码

错误码 含义
10001 access_token参数获取失败或未传输
10002 domain参数值错误
10003 language参数错误
10004 voice_name参数错误
10005 audiotype参数错误
10006 rate参数错误
10007 idx错误
10008 single错误
10009 text参数错误
10010 文本太长
20000 获取资源错误
20001 断句失败
20002 分段数错误
20003 分段后的文本长度错误
20004 获取引擎链接错误
20005 RPC链接失败错误
20006 引擎内部错误
20007 操作redis错误
20008 音频编码错误
30000 鉴权错误(access_token值不正确或已经失效)
30001 并发错误
30002 内部配置错误
30003 json串解析错误
30004 获取url失败
30005 获取客户IP地址失败
30006 任务队列错误