SpringBoot集成免費(fèi)的EdgeTTS實(shí)現(xiàn)文本轉(zhuǎn)語音
引言
在需要文本轉(zhuǎn)語音(TTS)的應(yīng)用場景中(如語音助手、語音通知、內(nèi)容播報(bào)等),Java生態(tài)缺少類似Python生態(tài)的Edge TTS 客戶端庫。不過沒關(guān)系,現(xiàn)在可以通過 UnifiedTTS 提供的 API 來調(diào)用免費(fèi)的 EdgeTTS 能力。同時(shí),UnifiedTTS 還支持 Azure TTS、MiniMax TTS、Elevenlabs TTS 等多種模型,通過對請求接口的抽象封裝,用戶可以方便在不同模型與音色之間靈活切換。
下面我們以調(diào)用免費(fèi)的EdgeTTS為目標(biāo),構(gòu)建一個(gè)包含文本轉(zhuǎn)語音功能的Spring Boot應(yīng)用。
實(shí)戰(zhàn)
1. 構(gòu)建 Spring Boot 應(yīng)用
通過 start.spring.io 或其他構(gòu)建基礎(chǔ)的Spring Boot工程,根據(jù)你構(gòu)建應(yīng)用的需要增加一些依賴,比如最后用接口提供服務(wù)的話,可以加入web模塊:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2. 注冊 UnifiedTTS,獲取 API Key
- 前往 UnifiedTTS 官網(wǎng)注冊賬號(直接GitHub登錄即可)
- 從左側(cè)菜單進(jìn)入“API密鑰”頁面,創(chuàng)建 API Key;

- 存好API Key,后續(xù)需要使用
3. 集成 UnifiedTTS API
下面根據(jù)API 文檔:https://unifiedtts.com/zh/api-docs/tts-sync 實(shí)現(xiàn)一個(gè)可運(yùn)行的參考實(shí)現(xiàn),包括配置文件、請求模型、服務(wù)類與控制器。
3.1 配置文件(application.properties)
unified-tts.host=https://unifiedtts.com unified-tts.api-key=your-api-key-here
這里unifiedtts.api-key參數(shù)記得替換成之前創(chuàng)建的ApiKey。
3.2 配置加載類
@Data
@ConfigurationProperties(prefix = "unified-tts")
public class UnifiedTtsProperties {
private String host;
private String apiKey;
}
3.3 請求封裝和響應(yīng)封裝
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UnifiedTtsRequest {
private String model;
private String voice;
private String text;
private Double speed;
private Double pitch;
private Double volume;
private String format;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UnifiedTtsResponse {
private boolean success;
private String message;
private long timestamp;
private UnifiedTtsResponseData data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class UnifiedTtsResponseData {
@JsonProperty("request_id")
private String requestId;
@JsonProperty("audio_url")
private String audioUrl;
@JsonProperty("file_size")
private long fileSize;
}
}
UnifiedTTS 抽象了不同模型的請求,這樣用戶可以用同一套請求參數(shù)標(biāo)準(zhǔn)來實(shí)現(xiàn)對不同TTS模型的調(diào)用,這個(gè)非常方便。所以,為了簡化TTS的客戶端調(diào)用,非常推薦使用 UnifiedTTS。
3.3 服務(wù)實(shí)現(xiàn)(調(diào)用 UnifiedTTS)
使用 Spring Boot自帶的RestClient HTTP客戶端來實(shí)現(xiàn)UnifiedTTS的功能實(shí)現(xiàn)類,提供兩個(gè)實(shí)現(xiàn):
- 接收音頻字節(jié)并返回。
@Service
public class UnifiedTtsService {
private final RestClient restClient;
private final UnifiedTtsProperties properties;
public UnifiedTtsService(RestClient restClient, UnifiedTtsProperties properties) {
this.restClient = restClient;
this.properties = properties;
}
/**
* 調(diào)用 UnifiedTTS 同步 TTS 接口,返回音頻字節(jié)數(shù)據(jù)。
*
* <p>請求頭:
* <ul>
* <li>Content-Type: application/json</li>
* <li>X-API-Key: 來自配置的 API Key</li>
* <li>Accept: 接受二進(jìn)制流或常見 mp3/mpeg 音頻類型</li>
* </ul>
*
* @param request 模型、音色、文本、速度/音調(diào)/音量、輸出格式等參數(shù)
* @return 音頻二進(jìn)制字節(jié)(例如 mp3)
* @throws IllegalStateException 當(dāng)服務(wù)端返回非 2xx 或無內(nèi)容時(shí)拋出
*/
public byte[] synthesize(UnifiedTtsRequest request) {
ResponseEntity<byte[]> response = restClient
.post()
.uri("/api/v1/common/tts-sync")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_OCTET_STREAM, MediaType.valueOf("audio/mpeg"), MediaType.valueOf("audio/mp3"))
.header("X-API-Key", properties.getApiKey())
.body(request)
.retrieve()
.toEntity(byte[].class);
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
return response.getBody();
}
throw new IllegalStateException("UnifiedTTS synthesize failed: " + response.getStatusCode());
}
/**
* 調(diào)用合成并將音頻寫入指定文件。
*
* <p>若輸出路徑的父目錄不存在,會(huì)自動(dòng)創(chuàng)建;失敗時(shí)拋出運(yùn)行時(shí)異常。
*
* @param request TTS 請求參數(shù)
* @param outputPath 目標(biāo)文件路徑(例如 output.mp3)
* @return 實(shí)際寫入的文件路徑
*/
public Path synthesizeToFile(UnifiedTtsRequest request, Path outputPath) {
byte[] data = synthesize(request);
try {
if (outputPath.getParent() != null) {
Files.createDirectories(outputPath.getParent());
}
Files.write(outputPath, data);
return outputPath;
} catch (IOException e) {
throw new RuntimeException("Failed to write TTS output to file: " + outputPath, e);
}
}
}
3.4 單元測試
@SpringBootTest
class UnifiedTtsServiceTest {
@Autowired
private UnifiedTtsService unifiedTtsService;
@Test
void testRealSynthesizeAndDownloadToFile() throws Exception {
UnifiedTtsRequest req = new UnifiedTtsRequest(
"edge-tts",
"en-US-JennyNeural",
"Hello, this is a test of text to speech synthesis.",
1.0,
1.0,
1.0,
"mp3"
);
// 調(diào)用真實(shí)接口,斷言返回結(jié)構(gòu)
UnifiedTtsResponse resp = unifiedTtsService.synthesize(req);
assertNotNull(resp);
assertTrue(resp.isSuccess(), "Response should be success");
assertNotNull(resp.getData(), "Response data should not be null");
assertNotNull(resp.getData().getAudioUrl(), "audio_url should be present");
// 在當(dāng)前工程目錄下生成測試結(jié)果目錄并寫入文件
Path projectDir = Paths.get(System.getProperty("user.dir"));
Path resultDir = projectDir.resolve("test-result");
Files.createDirectories(resultDir);
Path out = resultDir.resolve(System.currentTimeMillis() + ".mp3");
Path written = unifiedTtsService.synthesizeToFile(req, out);
System.out.println("UnifiedTTS test output: " + written.toAbsolutePath());
assertTrue(Files.exists(written), "Output file should exist");
assertTrue(Files.size(written) > 0, "Output file size should be > 0");
}
}
4. 運(yùn)行與驗(yàn)證
執(zhí)行單元測試之后,可以在工程目錄test-result下找到生成的音頻文件:

5. 常用參數(shù)與音色選擇
目前支持的常用參數(shù)如下圖所示:

小結(jié)
本文展示了如何在 Spring Boot 中集成 UnifiedTTS 的 EdgeTTS 能力,實(shí)現(xiàn)文本轉(zhuǎn)語音并輸出為 mp3。UnifiedTTS 通過統(tǒng)一的 API 屏蔽了不同 TTS 模型的差異,使你無需維護(hù)多個(gè) SDK,即可在成本與效果之間自由切換。根據(jù)業(yè)務(wù)需求,你可以進(jìn)一步完善異常處理、緩存與并發(fā)控制,實(shí)現(xiàn)更可靠的生產(chǎn)級 TTS 服務(wù)。
以上就是SpringBoot集成免費(fèi)的EdgeTTS實(shí)現(xiàn)文本轉(zhuǎn)語音的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot EdgeTTS文本轉(zhuǎn)語音的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
spring?boot對敏感信息進(jìn)行加解密的項(xiàng)目實(shí)現(xiàn)
本文主要介紹了spring?boot對敏感信息進(jìn)行加解密的項(xiàng)目實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
詳解Spring Data JPA動(dòng)態(tài)條件查詢的寫法
本篇文章主要介紹了Spring Data JPA動(dòng)態(tài)條件查詢的寫法 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Java實(shí)現(xiàn)開箱即用的redis分布式鎖
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)開箱即用的基于redis的分布式鎖,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以收藏一下2022-12-12
rocketmq的AclClientRPCHook權(quán)限控制使用技巧示例詳解
這篇文章主要為大家介紹了rocketmq的AclClientRPCHook使用技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)粒子跟隨效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)粒子跟隨效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
java-RGB調(diào)色面板的實(shí)現(xiàn)(事件監(jiān)聽器之匿名內(nèi)部類)
這篇文章主要介紹了java-RGB調(diào)色面板的實(shí)現(xiàn)(事件監(jiān)聽器之匿名內(nèi)部類),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
String類下compareTo()與compare()方法比較
這篇文章主要介紹了String類下compareTo()與compare()方法比較的相關(guān)資料,需要的朋友可以參考下2017-05-05
使用JDBC實(shí)現(xiàn)數(shù)據(jù)訪問對象層(DAO)代碼示例
這篇文章主要介紹了使用JDBC實(shí)現(xiàn)數(shù)據(jù)訪問對象層(DAO)代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10

