动态

详情 返回 返回

Spring Boot快速集成MiniMax、CosyVoice實現文本轉語音 - 动态 详情

在一些需要高質量文本轉語音(TTS)的場景中(比如:有聲書配音、播客等)。之前介紹的EdgeTTS方案可能效果沒有那麼好。此時就比較推薦使用 MiniMax、CosyVoice這些提供的音色,這些音色的效果會更加擬人、逼真,接近真人發音。這裏依然通過 UnifiedTTS 的統一接口來對接,這樣我們可以在不更換客户端代碼的前提下,快速在 MiniMax、CosyVoice等引擎之間做無縫切換。本文將引導讀者從零到一把MiniMax、CosyVoice的語音合成能力整合到你的Spring Boot應用中,最後也會給出一個可複製的 Spring Boot 集成示例,

實戰

1. 構建 Spring Boot 應用

通過 start.spring.io 或其他構建基礎的Spring Boot工程,根據你構建應用的需要增加一些依賴,比如最後用接口提供服務的話,可以加入web模塊、lombok等常用依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2. 註冊 UnifiedTTS,獲取 API Key

創建API Key

  • 記錄下創建的ApiKey,後續程序配置的時候需要使用

3. 集成 UnifiedTTS API(使用 MiniMax、CosyVoice)

下面給出參考實現,包括配置、DTO、服務與控制器。與 EdgeTTS 版本相比,主要是將 modelvoice 改為 MiniMax/CosyVoice 支持的參數。

3.1 配置文件(application.properties

unified-tts.host=https://unifiedtts.com
unified-tts.api-key=${UNIFIEDTTS_API_KEY}

這裏 unified-tts.api-key 請替換為你在 UnifiedTTS 控制枱創建的 API Key。

3.2 配置加載類與請求/響應封裝

// src/main/java/com/example/tts/config/UnifiedTtsProperties.java
@Data
@ConfigurationProperties(prefix = "unified-tts")
public class UnifiedTtsProperties {
    private String host;
    private String apiKey;
}

// src/main/java/com/example/tts/dto/UnifiedTtsRequest.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UnifiedTtsRequest {
    private String model;   // 例:minimax-tts 或 cosyvoice-tts
    private String voice;   // 例:zh_female_1(按模型支持的音色選擇)
    private String text;
    private Double speed;   // 語速(可選)
    private Double pitch;   // 音高(可選)
    private Double volume;  // 音量(可選)
    private String format;  // mp3/wav/ogg
}

// src/main/java/com/example/tts/dto/UnifiedTtsResponse.java
@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;
    }
}

3.3 服務實現(RestClient 同步合成)

// src/main/java/com/example/tts/service/UnifiedTtsService.java
package com.example.tts.service;

import com.example.tts.dto.UnifiedTtsRequest;
import com.example.tts.config.UnifiedTtsProperties;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

@Service
public class UnifiedTtsService {

    private final RestClient restClient;
    private final UnifiedTtsProperties properties;

    public UnifiedTtsService(UnifiedTtsProperties properties) {
        this.properties = properties;
        this.restClient = RestClient.builder()
                .baseUrl(properties.getHost())
                .build();
    }

    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());
    }

    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 單元測試(MiniMax/CosyVoice)

// src/test/java/com/example/tts/UnifiedTtsServiceTest.java
@SpringBootTest
class UnifiedTtsServiceTest {

    @Autowired
    private UnifiedTtsService unifiedTtsService;

    @Test
    void testSynthesizeToFileWithMiniMax() throws Exception {
        UnifiedTtsRequest req = new UnifiedTtsRequest(
            "speech-02-turbo",
            "Chinese (Mandarin)_Gentle_Youth",
            "你好,歡迎使用 UnifiedTTS 的 MiniMax 模型配音。",
            1.0,
            0.0,
            1.0,
            "mp3"
        );

        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);
        assertTrue(Files.exists(written), "Output file should exist");
        assertTrue(Files.size(written) > 0, "Output file size should be > 0");
    }
}

4. 運行與驗證

執行單元測試之後,可以在工程目錄 test-result 下找到生成的音頻文件:

如果你希望拿到音頻 URL 或 Base64,可將接口 accept 改為 application/json 並解析返回結果,再做下載或解碼。

5. 常用參數與音色選擇

  • modelspeech-02-turbo(示例),不同規格以官方為準;
  • voice:示例 Chinese (Mandarin)_Gentle_Youth 等;
  • rate:語速(建議範圍 0.8–1.2);
  • pitch:音高(建議範圍 -3–+3);
  • volume:音量(建議範圍 0.8–1.2);
  • formatmp3(常用)、wav(無損但體積大)、ogg 等。

模型model與音色voice 這裏推薦使用 minimaxcosyvoice的模型和音色。

具體支持的參數可以在API文檔中的接口查詢可以填入的參數,比如:

model支持,調用一下可以看到,支持的模型有:

支持的音頻模型

每個模型下支持的voice,也可以調用接口查詢,比如這裏嘗試調用minimax支持的voice:

模型支持的音色

6. 異常處理與重試建議

  • 超時與網絡錯誤:設置 timeout-ms,在 onErrorResume 中記錄原因;
  • 4xx/5xx:區分鑑權失敗、限流、服務器錯誤並上報;
  • 重試策略:對臨時性錯誤採用指數退避(帶抖動);
  • 併發與限流:高併發場景實現隊列或令牌桶;
  • 緩存:對重複合成按 text+voice+params 做緩存,降低成本與時延。

7. 生產化建議

  • 安全:API Key 從環境變量或密鑰管理系統注入;
  • 監控:記錄合成耗時、失敗原因、重試比率;
  • 存儲:落盤或對象存儲(如 S3)並設置生命週期;
  • 規範:統一 DTO 與服務返回結構,便於多模型擴展;
  • 擴展:通過配置切換 Azure/Edge/Elevenlabs/MiniMax 等模型。

小結

通過 UnifiedTTS,我們在 Spring Boot 中僅需調整 modelvoice 即可切換到 MiniMax、CosyVoice、甚至最強的Elevenlabs,實現文本轉語音。統一接口簡化了多引擎維護成本,讓你能在成本、音色與效果間自由選擇。根據業務需求,還可進一步完善異常處理、緩存與併發控制,構建更可靠的生產級 TTS 服務。

另外,對比了官方API和UnifiedTTS的價格,後者更具備價格優勢,所以非常推薦獨立開發者或者初創產品的時候使用。不論從開發成本還是API成本角度看都是最佳選擇。

user avatar u_17513518 头像 journey_64224c9377fd5 头像 chuck1sn 头像 junxiudedoujiang 头像 lslove 头像 lvxingdefanka 头像 huangxunhui 头像 codecraft 头像 sulf 头像 jinjiedefarmer 头像 jame_5f6d5e99aea15 头像 njwutong 头像
点赞 18 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.