使用百度TTS API获取合成一句话

前言

说白了就是之前有一次在某个群里帮人做了个视频,事后有人询问视频里那个可爱的声音是怎么做到的,(还莫名其妙被起了个叫什么‘萌萌萝莉音’的名字)于是拖了很久终于决定今天水一发教程好了。。。

首先先说明下这个教程并没有直接读百度 tts apidocument 来的有用,几乎可以理解为纯新手向教程,不涉及高级用法,纯粹只是一篇拿来水文章的文章。。。如果有任何云服务的 api 的使用经验的人应该都不需要阅读本文,另外本文也几乎不会做过多词语解释,最多也只会举几个伪代码和通过 shell script 的调用 api 获取音频文本的例子。

为什么是百度

简单来说。。。没有原因。。。。纯粹因为百度 tts 有几个听起来比较可爱的语音库。。。仅此而已。。。

事前准备

既然是百度 tts 。。。那么首先你需要一个百度账号,这个过程各位就自行注册吧。。。虽然咱觉得就算不是百度云服务的用户。。。至少应该也都是用过百度云的人。。。账号应该还是有的。。。

通过百度的文档可以知道。。。调用 tts api 的话需要一堆 API key 啦。。。API secret 什么的。。。如何获取需要的 key 和 secret 请直接阅读百度的这个页面

然后就是使用环境了。。。除了伪代码外。。。shell 主要只使用 bash 和 wget,环境姑且是 debian 10。。。wget 的安装或者 debian 的安装不在本文涵盖范围。。。

具体实现

首先通过阅读官方文档,我们可以知道 API key/API secret 并不是直接用来访问 TTS API 的,需要获得对应的 access_token 才可以。又根据官方文档中如何获得 access_token 的部分可知, access_token 可以通过 GET 方法从 https://openapi.baidu.com/oauth/2.0/token 处获得,需要3个参数,分别是grant_type(值固定为 client_credentials ),client_id(你的 API key ),client_secret(你的 API secret )。

综上所述可以通过访问https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=&client_secret=获取 access_token。

如果参数正确,返回值将会是下面这个样子的:

{"access_token":"24.3c7de***-16949624",
"session_key":"9mzdCKcjqot***ccjfgRQ==",
"scope":"audio_voice_assistant_get brain_enhanced_asr audio_tts_post ***",
"refresh_token":"25.f***-16949624",
"session_secret":"b52***eb85",
"expires_in":2592000}

如果不用写成完整的脚本的话。。。你大概可以选择直接手动复制需要的值并把那个值随便存到哪个变量里。。。但如果需要写成一个脚本又懒得上网 google bash 下如何处理 json 的话,后文 bash 的示例代码里随便举了一个本文正好能用的例子。

接着阅读官方文档我们可以知道想要获取语音的话可以通过使用 POST 或者 GET 方法访问 https://tsn.baidu.com/text2audio。需要的参数参考下面的表格

被挤得变形了的表格
tex 必填   合成的文本,使用UTF-8编码。小于2048个中文字或者英文数字。
(文本在百度服务器内转换为GBK后,长度必须小于4096字节)
tok 必填   开放平台获取到的开发者access_token(见上面的“鉴权认证机制”段落)
cuid 必填   用户唯一标识,用来计算UV值。
建议填写能区分用户的机器 MAC 地址或 IMEI 码,长度为60字符以内
ctp 必填   客户端类型选择,web端填写固定值1
lan 必填   固定值zh。语言选择,目前只有中英文混合模式,填写固定值zh
spd 选填   语速,取值0-15,默认为5中语速
pit 选填   音调,取值0-15,默认为5中语调
vol 选填   音量,取值0-15,默认为5中音量
per
基础音库
选填   度小宇=1,度小美=0,度逍遥=3,度丫丫=4
per
精品音库
选填   度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5
aue 选填   3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k);
注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的
自然人发音,所以识别效果会受影响。

于是参考文档,最终可以通过https://tsn.baidu.com/text2audio?tex=&lan=zh&cuid=&ctp=1&tok= 获取想要的语音

伪代码实例

#! 伪代码
创建变量 API_key,API_secret 并赋值
创建变量 Token_URL ,值为'https://openapi.baidu.com/oauth/2.0/token'
创建变量 TTS_API , 值为'https://tsn.baidu.com/text2audio'
创建变量 cuid ,随便给它赋个值

# 获取 access_token
使用 GET 方法访问 ${Token_URL}?grant_type=client_credentials&client_id=${API_key}&client_secret=${API_secret} 并将结果保存至 变量a
使用什么方法从 变量a 中获取字段 access_token 并存入变量 access_token

# 获取 文本 对应的 语音
请求用户输入想要转换的文本,并将文本存入变量 Text
使用 GET 方法访问 ${TTS_API}?tok=${access_token}&lan=zh&cuid=${cuid}&ctp=1&tex=${Text} ,并将返回内容保存至${Text}.mp3

具体一点写成shell脚本的话长这样

#!/bin/bash
# 设置 API_key,API_secret 和 cuid
API_key=""
API_secret=""
cuid=""

#后面代码中会用到的两个请求地址
Token_URL="https://openapi.baidu.com/oauth/2.0/token"
TTS_API="https://tsn.baidu.com/text2audio"

# 获取 access_token
a=$(wget "$Token_URL?grant_type=client_credentials&client_id=$API_key&client_secret=$API_secret" -O-)
# 使用 Google 到的方法对返回值的 json 进行处理并获取返回值中的 access_token
access_token=$(echo $a | sed s/'[,:]'/\\n/g | grep 'access_token' -A1 | tail -1 | sed s/'"'//g)

# 获取 文本 对应的 语音
read -p "请输入想要转换的文本:" Text
wget "$TTS_API?tok=$access_token&lan=zh&cuid=$cuid&ctp=1&tex=$Text" -O $Text.mp3

总结

只是调用百度提供的 API 进行 TTS 而已,通常来说应该没什么技术上的难度,不过既然有人想知道是怎么实现的。。咱还是姑且丢了一份示例代码出来。。。因为说实话咱也不知道该怎么详细介绍如何通过百度提供的 API 进行 TTS 。。。。总之只能希望咱的这篇水出来的blog能对一些人有帮助吧(说实话咱感觉这篇文章写的还没有百度自己的文档详细呢。。。)

咱之前使用的语音库没记错应该是 4 号,感兴趣的话可以把 per=4 附加进请求里试试呢

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注