微软(TTS)文本转语音服务API实现

此博客实现与java实现微软文本转语音(TTS)经验总结_java tts_${简简单单}的博客-CSDN博客之上,首先感谢博客源码的提供,本人在上面添加了一些详细的注释,方便大家跟好的理解和使用,毕竟我已经用原文调试了一下午才调通,一些细节的问题给大家标注出来,免得浪费大家的时间,下面直接开始代码吧!

首先大家需要去微软官网获取到密钥,方便调用时可以使用,大家注意看下图,我们一定要注意给我们分配到的区域,我这里是分配到eastus ,就是east us(美国东部)的意思,大家一定需要注意一下,后面会使用到的,然后终结点里面的地址就是我们获取token的地址

下面我们准备几个类,方便后面使用,大家把代码都复制到自己项目中,不要有遗漏:

package com.daoversal.util;public class ByteArray {private byte[] data;private int length;public ByteArray(){length = 0;data = new byte[length];}public ByteArray(byte[] ba){data = ba;length = ba.length;}/**合并数组*/public  void cat(byte[] second, int offset, int length){if(this.length + length > data.length) {int allocatedLength = Math.max(data.length, length);byte[] allocated = new byte[allocatedLength << 1];System.arraycopy(data, 0, allocated, 0, this.length);System.arraycopy(second, offset, allocated, this.length, length);data = allocated;}else {System.arraycopy(second, offset, data, this.length, length);}this.length += length;}public  void cat(byte[] second){cat(second, 0, second.length);}public byte[] getArray(){if(length == data.length){return data;}byte[] ba = new byte[length];System.arraycopy(data, 0, ba, 0, this.length);data = ba;return ba;}public int getLength(){return length;}
}
package com.daoversal.util;import javax.net.ssl.HttpsURLConnection;
import java.net.URL;public class HttpsConnection {public static HttpsURLConnection getHttpsConnection(String connectingUrl) throws Exception {URL url = new URL(connectingUrl);return (HttpsURLConnection) url.openConnection();}
}
package com.daoversal.util;import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;@Slf4j
public class XmlDom {public static String createDom(String locale, String genderName, String voiceName, String textToSynthesize){Document doc = null;Element speak, voice;try {DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dbf.newDocumentBuilder();doc = builder.newDocument();if (doc != null){speak = doc.createElement("speak");speak.setAttribute("version", "1.0");speak.setAttribute("xml:lang", "en-US");voice = doc.createElement("voice");voice.setAttribute("xml:lang", locale);voice.setAttribute("xml:gender", genderName);voice.setAttribute("name", voiceName);voice.appendChild(doc.createTextNode(textToSynthesize));speak.appendChild(voice);doc.appendChild(speak);}} catch (ParserConfigurationException e) {log.error("Create ssml document failed: {}",e.getMessage());return null;}return transformDom(doc);}private static String transformDom(Document doc){StringWriter writer = new StringWriter();try {TransformerFactory tf = TransformerFactory.newInstance();Transformer transformer;transformer = tf.newTransformer();transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");transformer.transform(new DOMSource(doc), new StreamResult(writer));} catch (TransformerException e) {log.error("Transform ssml document failed: {}",e.getMessage());return null;}return writer.getBuffer().toString().replaceAll("\n|\r", "");}
}

 下面这个类我给大家重点讲一下,大家去下面网址看看自己的参数Text to speech API reference (REST) - Speech service - Azure AI services | Microsoft Learn

AUDIO_24KHZ_48KBITRATE_MONO_MP3 :语言类型,这个不重要,那个声音好听用那个,去下图找:

ACCESS_TOKEN_URI :就是本文章的第一张图里面,里面获取token的地址,直接将地址复制进来就好了。

API_KEY :自己的api key,就是密钥。

 TTS_SERVICE_URI : 这个地址一定要对应分配的区域才行,不然会报权限错误

Synthesis tts speech failed Server returned HTTP response code: 401 for URL: https://.........

我这里是 east us(美国东部),所以就使用美国东部里面的地址即可。

package com.daoversal.util;public class TtsConst {/*** 音频合成类型(亲测这种效果最佳,其他的你自己去试试)* 里面有很多类型,可以去里面找自己需要的* https://learn.microsoft.com/en-us/azure/ai-services/speech-service/rest-text-to-speech?tabs=streaming*/public static final String AUDIO_24KHZ_48KBITRATE_MONO_MP3 = "audio-24khz-48kbitrate-mono-mp3";/*** 授权url   获取密钥页面 终结点 里面的地址,我们使用这个获取token*/public static final String ACCESS_TOKEN_URI = "token获取地址";/*** api key*/public static final String API_KEY = "自己的密钥";/*** tts服务url,这里一定要根据自己分配的地区找相应的地址才行*/public static final String TTS_SERVICE_URI = "https://eastus.tts.speech.microsoft.com/cognitiveservices/v1/";}

下面参数给大家讲一下:

textToSynthesize : 传入的合成语音文本内容

locale:语言类型,大家可以参考,中文在嵌入式语音里面,大家可以在两个页面找到自己需要的语言。

Embedded Speech - Speech service - Azure AI services | Microsoft Learn

Language support - Speech service - Azure AI services | Microsoft Learn

gender:为发声人性别,Male表示男性

 voiceName :发声者名称,大家可以去下图找出对应的,比如中文的话:

package com.daoversal.util;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.net.ssl.HttpsURLConnection;
import java.io.DataOutputStream;
import java.io.InputStream;@Slf4j
@Component
public class TtsService {@Resourceprivate Authentication authentication;/*** 合成音频* @param textToSynthesize 传入需要翻译的文本* @param locale    要合成的语言类型* @param gender    性别* @param voiceName 发音者名称* @return*/public byte[] genAudioBytes(String textToSynthesize, String locale, String gender, String voiceName) {String accessToken = authentication.genAccessToken();if (StringUtils.isEmpty(accessToken)) {return new byte[0];}try {HttpsURLConnection webRequest = HttpsConnection.getHttpsConnection(TtsConst.TTS_SERVICE_URI);webRequest.setRequestProperty("Host", "eastus.tts.speech.microsoft.com");webRequest.setRequestProperty("Content-Type", "application/ssml+xml");webRequest.setRequestProperty("X-Microsoft-OutputFormat", TtsConst.AUDIO_24KHZ_48KBITRATE_MONO_MP3);webRequest.setRequestProperty("Authorization", "Bearer " + accessToken);webRequest.setRequestProperty("Ocp-Apim-Subscription-Key", TtsConst.API_KEY);webRequest.setRequestProperty("User-Agent", "Mozilla/5.0");webRequest.setRequestProperty("Accept", "*/*");webRequest.setDoInput(true);webRequest.setDoOutput(true);webRequest.setConnectTimeout(5000);webRequest.setReadTimeout(300000);webRequest.setRequestMethod("POST");String body = XmlDom.createDom(locale, gender, voiceName, textToSynthesize);if (StringUtils.isEmpty(body)) {return new byte[0];}byte[] bytes = body.getBytes();webRequest.setRequestProperty("content-length", String.valueOf(bytes.length));webRequest.connect();DataOutputStream dop = new DataOutputStream(webRequest.getOutputStream());dop.write(bytes);dop.flush();dop.close();InputStream inSt = webRequest.getInputStream();ByteArray ba = new ByteArray();int rn2 = 0;int bufferLength = 4096;byte[] buf2 = new byte[bufferLength];while ((rn2 = inSt.read(buf2, 0, bufferLength)) > 0) {ba.cat(buf2, 0, rn2);}inSt.close();webRequest.disconnect();return ba.getArray();} catch (Exception e) {log.error("Synthesis tts speech failed {}", e.getMessage());}return null;}}

最后就是调用了,大家可以测试了:

package com.daoversal.web;import com.daoversal.framework.http.Response;
import com.daoversal.task.DvWeekCountTask;
import com.daoversal.task.RechargeTask;
import com.daoversal.task.UserGradeCountTask;
import com.daoversal.task.WindControlMsgTask;
import com.daoversal.util.TtsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import okhttp3.*;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;/*** <p>* 套餐价值释放记录表 前端控制器* </p>** @author HayDen* @since 03 22 10:44:13*/
@RestController
@RequestMapping("/test")
@Api(value = "test")
public class TestController {@Resourceprivate TtsService testService;@PostMapping("/ttsService")@ApiOperation(value = "获取ttsService", httpMethod = "POST" )public void ttsService(String text) {// byte[] bte = testService.genAudioBytes(res,"en-US","Male","en-US-JennyNeural");byte[] bte = testService.genAudioBytes(text,"zh-CN","Male","zh-CN-YunxiNeural");String value = "hllo.mp3";convertByteArrayToFile(bte,value);System.out.println("213213123");}/*** 此文件是将byte[] 转换成文件存储到指定路径的* @param arr* @param value*/public static void convertByteArrayToFile(byte[] arr,String value) {try (BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(arr));//这里是转换以后的文件存储的路径FileOutputStream fileOutputStream = new FileOutputStream("/Users/recovery/Downloads/"+value);BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream)) {int data;while ((data = bis.read()) != -1) {bos.write(data);}bos.flush();} catch (IOException e) {e.printStackTrace();}}}

最后大家需要注意一下就是如果你选的是英文en-US,但是输入的文本是中文的话他是不会翻译的,所以大家一定要注意自己的语言类型不要弄错了,如果有疑问可以留言哦,我看到肯定会毫无保留的给大家说明的。

​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/138341.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云原生Kubernetes:pod进阶之资源管理与探针

目录 一、理论 1.pod的资源限制 2.健康检查&#xff08;探针Probe) 3.示例 二、实验 1.pod的资源限制 2.健康检查&#xff08;探针Probe) 三、问题 1.生成资源报错 2.api版本错误 3.echo N>/proc/sys/vm/drop_caches如何实现清理缓存 4.生成启动退出容器报错 5…

java版Spring Cloud+Mybatis+Oauth2+分布式+微服务+实现工程管理系统

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

python教程:使用gevent实现高并发并限制最大并发数

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 import time import gevent from gevent.pool import Pool from gevent import monkey # 一&#xff0c;定义最大并发数 p Pool(20) # 二&#xff0c;导入gevent…

【Docker】华为云服务器安装 Docker 容器

简介 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱机…

知识图谱基本工具Neo4j使用笔记 五 :APOC插件安装及简单应用

文章目录 一、使用场景二、系统说明三、配置安装1. 插件下载2. 文件下载说明3. 版本对应4. 安装位置5. 修改配置文件6. 注意问题7. web端启动&#xff1a;测试 四、简单应用1. 编辑距离2. 基于编辑距离的相似度3. 模糊匹配 一、使用场景 APOC&#xff08;Awesome Procedures o…

基于movie lens-100k数据集的协同过滤算法实现

基于movie lens-100k数据集的协同过滤算法实现 数据集处理 基于用户的协同过滤算法的实现 基于物品的协同过滤算法的实现 数据集处理 import pandas as pdu_data pd.read_csv(D:/PyCharmWorkSpace/ml-100k/ml-100k/u.data) u_genre pd.read_csv(D:/PyCharmWorkSpace/ml-10…

如何批量为文件夹命名

如果你想要命名一些这样名字具有规律性的文件夹&#xff0c;当文件的数量增多&#xff0c;一个一个命名是非常耗费时间的。很容易想到&#xff0c;如果使用EXCEL&#xff0c;只需往下拉&#xff0c;就能很轻松的拉出1到5。那么&#xff0c;我们如何利用EXCEL来对文件夹进行快速…

LazadaAPI接口解析,实现获得lazada商品评论列表

Lazada是一个流行的跨境电商平台&#xff0c;它提供了API接口供开发者使用。要获取Lazada商品评论列表&#xff0c;您需要使用Lazada API接口并进行相应的请求。 以下是使用Lazada API接口获取商品评论列表的示例代码&#xff08;使用Python编写&#xff09;&#xff1a; pyth…

【Linux】系统编程线程互斥与同步(C++)

目录 【1】线程互斥 【1.1】进程线程间的互斥相关背景概念 【1.2】互斥量mutex 【1.3】互斥量实现原理探究 【1.4】RAII的加锁风格 【2】可重入VS线程安全 【2.1】概念 【2.2】常见的线程不安全的情况 【2.3】常见的线程安全的情况 【2.4】常见不可重入的情况 【2.5…

无线定位中TDOA时延估计算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................figure; plot(P1x,P1y…

【Graph Net学习】LINE实现Graph Embedding

一、简介 LINE (Large-scale Information Network Embedding,2015) 是一种设计用于处理大规模信息网络的算法。它主要的目标是在给定的大规模信息网络中学习高质量的节点嵌入&#xff0c;并尽量保留网络中信息的丰富性。其具体的表现为在一个低 维空间里以向量形式表示网络中的…

华为云云耀云服务器L实例评测|华为云上安装监控服务Prometheus三件套安装

文章目录 华为云云耀云服务器L实例评测&#xff5c;华为云上试用监控服务Prometheus一、监控服务Prometheus三件套介绍二、华为云主机准备三、Prometheus安装四、Grafana安装五、alertmanager安装六、三个服务的启停管理1. Prometheus、Alertmanager 和 Grafana 启动顺序2. 使用…

mysql workbench常用操作

1、No database selected Select the default DB to be used by double-clicking its name in the SCHEMAS list in the sidebar 方法一&#xff1a;双击你要使用的库 方法二&#xff1a;USE 数据库名 2、复制表名&#xff0c;字段名 3、保存链接

折线图geom_line()参数选项

往期折线图教程 图形复现| 使用R语言绘制折线图折线图指定位置标记折线图形状更改 | 绘制动态折线图跟着NC学作图 | 使用python绘制折线图 前言 我们折线的专栏推出一段时间&#xff0c;但是由于个人的原因&#xff0c;一直未进行更新。那么今天&#xff0c;我们也参考《R语…

Kafka-UI

有多款kafka管理应用&#xff0c;目前选择的是github上star最多的UI for Apache Kafka。 关于 To run UI for Apache Kafka, you can use either a pre-built Docker image or build it (or a jar file) yourself. UI for Apache Kafka is a versatile, fast, and lightweight…

关于ABB机器人的IO创建和设置

首先要链接网线&#xff0c;请求写权限 关于ABB机器人的默认地址位10有的是63.31看你硬接线 ABB机器人分配好信号机器人控制柜要重启 可以把机器人分配的信号导出为EIO 类似与发那科机器人IO

Spring底层原理之 BeanFactory 与 ApplicationContext

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Spring底层原理 一、 BeanFactory 与 Appli…

ChatGPT追祖寻宗:GPT-3技术报告要点解读

论文地址&#xff1a;https://arxiv.org/abs/2005.14165 往期相关文章&#xff1a; ChatGPT追祖寻宗&#xff1a;GPT-1论文要点解读_五点钟科技的博客-CSDN博客ChatGPT追祖寻宗&#xff1a;GPT-2论文要点解读_五点钟科技的博客-CSDN博客 本文的标题之所以取名技术报告而不是论文…

无法删除目录(设备或资源忙)

文章目录 无法删除目录&#xff08;设备或资源忙&#xff09;问题原因解决方案步骤一&#xff1a;首先找到挂载的位置步骤二&#xff1a;取消挂载步骤三&#xff1a;查看挂在情况 无法删除目录&#xff08;设备或资源忙&#xff09; 问题 原因 网络共享挂载导致无法删除 解决…

C++实现观察者模式(包含源码)

文章目录 观察者模式一、基本概念二、实现方式三、角色四、过程五、结构图六、构建思路七、完整代码 观察者模式 一、基本概念 观察者模式&#xff08;又被称为模型&#xff08;Model&#xff09;-视图&#xff08;View&#xff09;模式&#xff09;是软件设计模式的一种。在…