logo
产品简介 产品简介
基本概念 基本概念
平台新手指引 平台新手指引
计价模式 计价模式
开发者文档下拉
开放平台计价
定制服务计价
获取访问令牌 获取访问令牌
语音合成 语音合成
开发者文档下拉
接口说明
发音人列表
短文本合成 开发者文档下拉
Android SDK
iOS SDK
C++(Linux) SDK
RESTful API
Websocket API
长文本合成 开发者文档下拉
长文本合成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
Android SDK
iOS SDK
离线声音转换 离线声音转换
开发者文档下拉
发音人列表
Android SDK
iOS SDK
声纹识别 声纹识别
开发者文档下拉
RESTful API
语音评测 语音评测
开发者文档下拉
RESTful API
声音理解 声音理解
开发者文档下拉
RESTful API
协议规则 协议规则
开发者文档下拉
平台服务协议
平台通用规则
法律声明及隐私政策
服务等级协议SLA
常见问题 常见问题
开发者文档下拉
语音合成
语音识别

长文本合成API

功能介绍

长文本语音合成API满足用户希望一次性合成比较长的文本,例如一篇新闻稿,一篇短篇小说。长文本合成API采用异步方式支持调用,用户调用接口上传文本同时需要额外提供一个回调url,当文本上传完成后合成服务立刻响应,释放连接,当完成合成后通过事先提供的回调url将合成结果(音频链接)返回。

长文本语音合成采用异步调用(非实时),文本上传成功后进入等待队列,合成成功后通过回调的方式返回音频,返回结果时间受文本长度以及排队任务量的影响。如遇合成耗时比平时延长,大概率表示当前时间段出现合成高峰,请耐心等待。

参数设置

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

使用方法

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

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

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

4. 接收回调请求:语音生成后,会将生成音频的下载地址发送到回到地址,具体详见回调说明。

服务地址

访问类型 说明 URL Host
外网访问 支持全部音色及语言
只支持POST调用
https://openapi.data-baker.com/asynctts/synthesis/work openapi.data-baker.com

交互流程

请求参数

参数名称 参数格式 是否必填 说明
access_token String 通过client_id,client_secret调用授权服务获得见获取访问令牌
text String 需要合成的文本(注意换行符需url编码)支持一次性上传不超过10万个字节。
voiceName String 设置发音人声音名称,详见 发音人列表
notifyUrl String 该地址用于接收合成结果,该地址必须为外网可访问的url,不能携带参数。
interval Integer 是否携带interval信息:
0:不携带,默认值
1:携带
speed String 设置播放的语速,在0~9之间(支持一位浮点值),不传时默认为5
volume String 设置语音的音量,在0~9之间(只支持整型值),不传时 默认值为5
audiotype Integer 可不填
audiotype=3 :返回mp3格式
audiotype=4 :返回16K采样率的pcm格式
audiotype=6 :返回16K采样率的wav格式

请求示例

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json'
 '{ \
   "access_token": "b939b1b7-624b-4bee-b249-c1870576297c", \
   "audiotype": "3", \
   "notifyUrl": "https://openapi.data-baker.com/asynctts/synthesis/notify", \
   "speed": "5", \
   "text": "请求数据", \
   "interval": 1, \
   "voiceName": "Jiaojiao", \
   "volume": "5" \
 }' 'https://openapi.data-baker.com/asynctts/synthesis/work'

Python示例代码

代码地址:Github

Python3示例:

import argparse
import requests
import json


# 获取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 send_text(data):
    url = "https://openapi.data-baker.com/asynctts/synthesis/work"
    headers = {'content-type': 'application/json'}
    response = requests.post(url, data=data, headers=headers)
    code = json.loads(response.text).get("code")
    if code != 0:
        raise Exception(response.text)


# 获取命令行输入参数
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('-notify_url', type=str, required=True)
    parser.add_argument('--text', type=str, default=text)
    parser.add_argument('--voice_name', type=str, default='Lingling')
    parser.add_argument('--audiotype', type=str, default='6')
    args = parser.parse_args()

    return args


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

    # 新建任务
    voice_name = args.voice_name
    text = args.text
    # 回调地址
    notify_url = args.notify_url
    headers = {'access_token': access_token, 'text': text, 'voiceName': voice_name, 'notifyUrl': notify_url}
    send_text(json.dumps(headers))
    print("send text successfully!")

if __name__ == '__main__':
    try:
        args = get_args()
        main(args)
    except Exception as e:
        print(e)

命令行执行

python long_tts.py -client_secret=您的client_secret -client_id=您的client_id -notify_url=您的回调地址 --text=欢迎使用标贝开放平台

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.长文本语音合成
$url = 'https://openapi.data-baker.com/asynctts/synthesis/work';

$file_path = './test.txt';
$text = file_get_contents($file_path);
$notify_url = '***/tts_async';

$post_data['access_token'] = $access_token;
$post_data['text'] = $text;
$post_data['notifyUrl'] = $notify_url;
$post_data['voiceName'] = 'Jiaojiao';
$post_data =json_encode($post_data);

$Content_Type = 'application/json; charset=utf-8';
$headers = array(
    'Content-Type:'.$Content_Type
);
$ch = curl_init();
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // 识别时长不超过原始音频
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$res = curl_exec($ch);
if(curl_errno($ch))
{
    print curl_error($ch);
}
curl_close($ch);
//var_dump($res);die;
echo(json_decode($res,1)['message']);

C示例代码

代码地址:Github

JAVA示例代码

package com.databaker.web.tts;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

/**
 * 长文本语音合成RESTFUL API接口调用示例
 * 附:长文本语音合成RESTFUL API文档 【https://www.data-baker.com/specs/file/tts_api_long_text】
 * <p>
 * 注意:仅作为demo示例,失败重试、token过期重新获取、日志打印等优化工作需要开发者自行完成
 *
 * @author data-baker
 */
public class TtsLongTextRestApiDemo {
    /**
     * 授权:需要在开放平台获取【https://ai.data-baker.com/】
     */
    private static final String clientId = "YOUR_CLIENT_ID";
    private static final String clientSecret = "YOUR_CLIENT_SECRET";

    /**
     * 获取token的地址信息
     */
    public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s";
    /**
     * 长文本合成API地址
     */
    public static String ttsLongTextUrl = "https://openapi.data-baker.com/asynctts/synthesis/work";

    public static void main(String[] args) {
        String accessToken = getAccessToken();
        if (StringUtils.isNotEmpty(accessToken)) {
            doSynthesis(accessToken, "Nannan", "测试文本", 6, 5.0, 5.0, "https://openapi.data-baker.com/asynctts/synthesis/notify");
        }
    }

    /**
     * 实际合成逻辑
     *
     * 开发者需开发一个回调接口,接口地址作为参数notifyUrl,用来接收合成的音频链接,具体写法可参考接口文档【https://www.data-baker.com/specs/file/tts_api_long_text】中的回调部分
     */
    public static void doSynthesis(String accessToken, String voiceName, String text, Integer audioType, Double speed, Double volume, String notifyUrl) {
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");
        //构造requestBody
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("access_token", accessToken);
        jsonObject.put("voiceName", voiceName);
        jsonObject.put("text", text);
        jsonObject.put("volume", volume);
        jsonObject.put("speed", speed);
        jsonObject.put("audiotype", audioType);
        jsonObject.put("notifyUrl", notifyUrl);
        RequestBody body = RequestBody.create(mediaType, jsonObject.toJSONString());
        //构造request
        Request request = new Request.Builder()
                .url(ttsLongTextUrl)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                //1.如果请求正常,会返回作品id,开发者可根据业务需要自行解析处理
                //2.实际的音频链接,会通过回调接口通知开发者
                System.out.println("调用成功,返回结果:" + response.body().string());
            } else {
                //处理错误,主要的错误类别:Token失效、文本长度过长、使用了授权范围外的音色等
                System.out.println("调用失败,返回结果:" + response.body().string());
            }
        } 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;
    }
}

响应结果

  • 正确结果示例:workId可以唯一标志一次成功的调用,通过notifyUrl回调推送合成结果时,会同时返回这个序列号以及音频下载地址。
  • {
      "code": 0,
      "message": "成功",
      "data": {
        "workId": "L0191129150400644602680"
      }
    }
  • 错误结果示例
  • {
      "code": 30000,
      "message": "鉴权错误(access_token值不正确或已经失效)",
      "data": null
    }

回调说明

  • 长文本异步合成接口收到请求后,首先对请求参数进行初步校验,并马上返回。如果成功,返回的结果“code”是0,会同时返回此次合成对应的workId,然后进入异步合成和回调逻辑;如果校验失败,返回的错误码提示错误,丢弃当前合成文本放弃合成。
  • 长文本异步合成接口在回调时,请求的body中会包含workId和audioUrl字段,如果指定参数interval=1,则body中会增加一个参数:intervalInfo,保存音频对应的interval信息(注:当前粤语不支持返回interval信息)。回调的请求方式示例如下
  • curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
       "audioUrl": "string",
       "workId": "3",
       "intervalInfo":"h=0.083746&e=0.175807(仅interval=1时返回该字段)"
     }' 'https://openapi.data-baker.com/asynctts/synthesis/notify'
  • 建议处理方式:收到回调请求后,提取需要的信息,并在body中返回固定字符串
  • <xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>
  • 回调如果不成功,目前每隔5秒重试一次,总共重试4次(该策略可能会有变动)

回调示例代码

Python3示例

from flask import Flask, request
import json
import wget

app = Flask(__name__)


@app.route("/", methods=['GET', 'POST'])
def get_audio():
    url = json.loads(request.get_data())['audioUrl']
    wget.download(url)
    print("task finished successfully")

    return "finished"

将上述代码保存为server.py

命令行执行

export FLASK_APP=server
flask run -p 端口号 --host=服务器IP

Java示例

@ApiOperation(value = "测试用回调接口", notes = "该链接由参数notifyUrl设置,如果链接无法访问,将无法接收到回调的push信息。")
@PostMapping("/notify")
public void synthesisNotify(HttpServletRequest request, HttpServletResponse response) {
    String resXml = "";
    InputStream inStream;
    try {
        inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        // 获取asyncTts调用notifyUrl的返回信息
        String result = new String(outSteam.toByteArray(), "utf-8");
        log.info("dataBaker:长文本tts返回结果 ----result---- =" + result);
        // 关闭流
        outSteam.close();
        inStream.close();
        // String转换为json对象,然后业务处理
        JSONObject jsonObject = JSON.parseObject(result);
        String workId = jsonObject.getString("workId");
        String audioUrl = jsonObject.getString("audioUrl");
        //具体业务处理,例如转存音频等(可先返回结果,然后异步去完成业务逻辑)
        //todo
        //根据情况,向结果中赋值:正常情况下,选择下面的resSuccess;如果选择resFail,将会视为推送失败,标贝服务端将重新推送一次相同的内容
        //     * 返回成功xml
        //     */
        //    String resSuccess = "<xml$gt;<return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
        //    /**
        //     * 返回失败xml
        //     */
        //    String resFail = "<xml><return_code>FAIL</return_code><return_msg>报文为空</return_msg></xml>";resXml = Constant.resSuccess;
        //记录日志
        log.info("dataBaker:长文本tts回调返回作品  {}  的下载链接为:--->{}", workId, audioUrl);
        } catch (Exception e) {
            log.error("dataBaker:长文本tts回调异常:", e);
        } finally {
            try {
                // 处理业务完毕
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                log.error("dataBaker:长文本tts回调异常:out:", e);
            }
        }
    }

PHP示例

<?php
//官网在线合成长文本语音合成API SDK 回调接口
public function tts_async(){
    $audio_info = file_get_contents("php://input");
    $audio_arr = json_decode($audio_info,1);
    //对返回结果进行判断
    if(isset($audio_arr['audioUrl'])){
        //1.建议返回信息存储到日志文件 或者 本地文件,自行完成
        //2.对音频链接进行读取写入文件操作,自行完成(请求合成接口不设置audiotype参数,默认返回mp3格式)
        //3.对回调接口返回成功信息 return "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
    }
}

错误码

错误码 含义
10001 access_token参数获取失败
10002 domain参数值错误
10003 language参数错误
10004 voice_name参数错误
10005 audiotype参数错误
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 任务队列错误
40001 请求不是json结构
40002 缺少必须字段
40003 版本错误
40004 字段值类型错误
40005 参数错误
50001 处理超时
50002 内部rpc调用失败
50004 其他内部错误