百度合成语音接口,文字内容长度限制,纯汉字不得超过2048个(不包含任何其他字符,否则报错)
百度语音合成接口使用,就不再累赘,去参考这个博主的文章
https://blog.csdn.net/belonghuang157405/article/details/81707858
2048个汉字不够用?那我就自己封装一个语音Util类,该类将字符串的文字长度进行一个判断,如果超出2000个字的内容,我就对内容进行分割。
分别发送多个请求去获取已转成的语音内容,再拼接成一整串MP3语音文件,该Util类判断文字长度最长支持6000个汉字,如需加长,请自行改装。
package com.shinemi.realiart.util;
import static com.shinemi.realiart.util.ServletUtil.sendGet;
import com.baidu.aip.speech.AipSpeech;
import com.baidu.aip.speech.TtsResponse;
import com.shinemi.common.bean.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
@Component
public class SpeechUtil {
private final static String API_KEY = "你自己百度账号里的API_KEY";
private final static String SECRET_KEY = "你自己百度账号里的SECRET_KEY";
private final static String TOKEN_URL = "https://openapi.baidu.com/oauth/2.0/token";
private final static String AUDIO_URL = "http://tsn.baidu.com/text2audio";
private final static int OUT_TIME = 2160000;
private static AipSpeech client;
@Autowired
private RedisUtil ru;
public String getAccessToken() {
String param = "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY;
String at = sendGet(TOKEN_URL, param);
JSONObject jToken = JSON.parseObject(at);
String token = jToken.getString("access_token");
ru.putString("speech_token", token, OUT_TIME);
return token;
}
public String getToken() {
String token = ru.getString("speech_token");
if (token == null)
token = getAccessToken();
return token;
}
/**
* 单例 懒加载模式 返回实例
* @return
*/
public static AipSpeech getInstance(){
if (client==null){
synchronized (AipSpeech.class){
if (client==null) {
client = new AipSpeech(Constants.BaiDu_APP_ID, Constants.BaiDu_API_KEY, Constants.BaiDu_SECRET_KEY);
}
}
}
return client;
}
public SpeechUtil() {
}
/**
* 根据内容长度作出对应处理,并返回拼接好的音频字节数据数组
* @param content
* @return
*/
public byte[] speechSynthesizer(String content){
Integer contentLength = content.length(); //获取文字内容长度
if (contentLength <= 2000)
return requestBaiduSpeechCloud(content);
// 内容字数大于两千,小于四千,从字符中间开始分割内容一次,获取到两段内容并转成语音,将语音合并为一条语音。
if (contentLength >= 2000 && contentLength <= 4000){
String substring01 = content.substring(0, (contentLength - 1) / 2); //获取前段内容
String substring02 = content.substring((contentLength - 1) / 2); //获取后段内容
//请求百度云Api 语音合成接口
byte[] bytes01 = requestBaiduSpeechCloud(substring01);
byte[] bytes02 = requestBaiduSpeechCloud(substring02);
//拼接两段byte数组内容
byte[] data = new byte[bytes01.length + bytes02.length];
System.arraycopy(bytes01, 0, data, 0, bytes01.length);
System.arraycopy(bytes02, 0, data, bytes01.length, bytes02.length);
return data;
}
// 内容字数大于四千,小于六千,从字符内容平均分割内容两次,获取到三段内容并转成语音,将语音合并为一条语音。
if (contentLength > 4000 && contentLength <= 6000){
String substring01 = content.substring(0, contentLength / 3);
String substring02 = content.substring(contentLength / 3, 2 * contentLength / 3);
String substring03 = content.substring(2 * contentLength / 3);
//请求百度云Api 语音合成接口
byte[] bytes01 = requestBaiduSpeechCloud(substring01);
byte[] bytes02 = requestBaiduSpeechCloud(substring02);
byte[] bytes03 = requestBaiduSpeechCloud(substring03);
//拼接两段byte数组内容
byte[] data = new byte[bytes01.length + bytes02.length + bytes03.length];
System.arraycopy(bytes01, 0, data, 0, bytes01.length);
System.arraycopy(bytes02, 0, data, bytes01.length, bytes02.length);
System.arraycopy(bytes03, 0, data, bytes01.length + bytes02.length, bytes03.length);
return data;
}
return null;
}
/**
* 请求百度云Api 语音合成接口
* content 文字内容长度限制,纯汉字不得超过2048个(不包含任何字符,否则报错)
* @param content
* @return
*/
public byte[] requestBaiduSpeechCloud(String content){
// 初始化一个AipSpeech
client = getInstance();
/* //可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);*/
// 设置可选参数
HashMap<String, Object> options = new HashMap<String, Object>();
// options.put("vol", "4"); //vol (String 音量,取值0-15,默认为5中音量)
options.put("spd", "4"); //spd (String 语速,取值0-9,默认为5中语速)
options.put("pit", "5"); //pit (String 音调,取值0-9,默认为5中语调)
//per (String 发音人选择, 基础音库:0为度小美,1为度小宇,3为度逍遥,4为度丫丫,默认为普通女)
//精品音库:5为度小娇,103为度米朵,106为度博文,110为度小童,111为度小萌,默认为基础音库的度小美
options.put("per", "0");
/* //可选:设置代理服务器地址, http和socket二选一,或者均不设置
client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理*/
// 调用百度云语音合成请求接口
TtsResponse res = client.synthesis(content, "zh", 1, options);
byte[] data = res.getData();
org.json.JSONObject res1 = res.getResult();
return data;
}
}
测试将合成语音文件写出本地
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@Slf4j
public class SpeechDemoTest {
@Test
public void test02(){
String content = "Hello, mother fucker, Deal lay low mo chao hey. 你好,靓仔,你妈妈说你超级帅。";
//使用工具类请求语音合成方法,返回byte字节。
byte[] data = speechUtil.speechSynthesizer(content);
//创建文件对象,将字节数组写出路径到 电脑本地桌面(自行修改路径),生成的文件叫做 datatata.mp3"
File file = new File("/Users/edz/Desktop/", "datatata.mp3");
if (data != null) {
try {
if (!file.exists()) { //如果文件不存在则新建文件
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(data);
fileOutputStream.close();
System.out.println("语音合成 成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}