131 lines
4.4 KiB
Java
131 lines
4.4 KiB
Java
package com.fuyuanshen.app.http;
|
||
|
||
import com.alibaba.nls.client.AccessToken;
|
||
import com.fuyuanshen.common.redis.utils.RedisUtils;
|
||
|
||
import java.io.*;
|
||
import java.net.HttpURLConnection;
|
||
import java.net.URL;
|
||
import java.time.Duration;
|
||
import java.util.Base64;
|
||
import javax.crypto.Mac;
|
||
import javax.crypto.spec.SecretKeySpec;
|
||
import java.security.InvalidKeyException;
|
||
import java.security.NoSuchAlgorithmException;
|
||
|
||
import static cn.dev33.satoken.SaManager.log;
|
||
|
||
public class HttpTtsClient {
|
||
|
||
private String accessKeyId;
|
||
private String accessKeySecret;
|
||
private String appKey;
|
||
/**
|
||
* 阿里云TTS服务基础URL
|
||
*/
|
||
private static final String BASE_URL = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
|
||
|
||
public HttpTtsClient(String accessKeyId, String accessKeySecret, String appKey) {
|
||
this.accessKeyId = accessKeyId;
|
||
this.accessKeySecret = accessKeySecret;
|
||
this.appKey = appKey;
|
||
}
|
||
private String refreshAccessToken() {
|
||
try {
|
||
// 调用阿里云API获取访问令牌
|
||
AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
|
||
accessToken.apply();
|
||
String token = accessToken.getToken();
|
||
log.info("访问令牌刷新成功");
|
||
|
||
return token;
|
||
} catch (Exception e) {
|
||
log.error("刷新访问令牌失败: {}", e.getMessage(), e);
|
||
return null;
|
||
}
|
||
}
|
||
/**
|
||
* 使用HTTP POST方式调用阿里云TTS服务生成MP3格式语音
|
||
*/
|
||
public byte[] synthesizeTextToMp3(String text) throws IOException {
|
||
String endpoint = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
|
||
|
||
// 构建请求体
|
||
// String requestBody = String.format(
|
||
// "{\"appkey\":\"%s\",\"text\":\"%s\",\"voice\":\"zhifeng\",\"format\":\"MP3\",\"sample_rate\":24000,\"volume\":50,\"speech_rate\":0,\"pitch_rate\":0}",
|
||
// appKey,
|
||
// text.replace("\"", "\\\"")
|
||
// );
|
||
|
||
String token = refreshAccessToken();
|
||
String requestBody = " {\n" +
|
||
" \"appkey\":\""+appKey+"\",\n" +
|
||
" \"text\":\""+text+"\",\n" +
|
||
" \"token\":\""+token+"\",\n" +
|
||
" \"format\":\"mp3\"\n" +
|
||
" }";
|
||
|
||
URL url = new URL(endpoint);
|
||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||
|
||
// 设置请求方法和头部
|
||
conn.setRequestMethod("POST");
|
||
conn.setRequestProperty("Content-Type", "application/json");
|
||
conn.setRequestProperty("Authorization", buildAuthorization());
|
||
conn.setRequestProperty("Content-Length", String.valueOf(requestBody.getBytes().length));
|
||
conn.setDoOutput(true);
|
||
|
||
// 发送请求体
|
||
try (OutputStream os = conn.getOutputStream()) {
|
||
os.write(requestBody.getBytes("UTF-8"));
|
||
}
|
||
|
||
// 读取响应
|
||
int responseCode = conn.getResponseCode();
|
||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||
// 读取音频数据
|
||
try (InputStream is = conn.getInputStream()) {
|
||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||
int nRead;
|
||
byte[] data = new byte[1024];
|
||
while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||
buffer.write(data, 0, nRead);
|
||
}
|
||
return buffer.toByteArray();
|
||
}
|
||
} else {
|
||
throw new IOException("HTTP请求失败,状态码: " + responseCode);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 构建授权头部
|
||
*/
|
||
private String buildAuthorization() {
|
||
// 实际实现需要根据阿里云API规范构建签名
|
||
// 这里是简化示例
|
||
return "Bearer " + generateAccessToken();
|
||
}
|
||
|
||
/**
|
||
* 生成访问令牌
|
||
*/
|
||
private String generateAccessToken() {
|
||
// 实际实现需要调用阿里云获取token的API
|
||
return "your-access-token";
|
||
}
|
||
|
||
/**
|
||
* 保存MP3到文件
|
||
*/
|
||
public String saveMp3ToFile(String text, String outputPath) throws IOException {
|
||
byte[] mp3Data = synthesizeTextToMp3(text);
|
||
|
||
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
|
||
fos.write(mp3Data);
|
||
}
|
||
|
||
return outputPath;
|
||
}
|
||
}
|