OpenAI 文字轉語音 (TTS)

簡介

音訊 API 提供了一個基於 OpenAI TTS(文字轉語音)模型的語音端點,使使用者能夠

  • 朗讀一篇書面部落格文章。

  • 生成多種語言的語音。

  • 使用流式傳輸提供即時音訊輸出。

先決條件

  1. 建立 OpenAI 賬戶並獲取 API 金鑰。您可以在 OpenAI 註冊頁面 註冊,並在 API 金鑰頁面 生成 API 金鑰。

  2. spring-ai-openai 依賴項新增到專案的構建檔案中。有關更多資訊,請參閱 依賴管理 部分。

自動配置

Spring AI 自動配置、啟動模組的工件名稱發生了重大變化。請參閱 升級說明 以獲取更多資訊。

Spring AI 為 OpenAI 文字轉語音客戶端提供 Spring Boot 自動配置。要啟用它,請將以下依賴項新增到專案的 Maven pom.xml 檔案中

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

或新增到 Gradle build.gradle 構建檔案中

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}
請參閱依賴管理部分,將 Spring AI BOM 新增到您的構建檔案中。

語音屬性

連線屬性

字首 spring.ai.openai 用作屬性字首,允許您連線到 OpenAI。

財產

描述

預設值

spring.ai.openai.base-url

要連線的 URL

api.openai.com

spring.ai.openai.api-key

API 金鑰

-

spring.ai.openai.organization-id

您可以選擇指定用於 API 請求的組織。

-

spring.ai.openai.project-id

您可以選擇指定用於 API 請求的專案。

-

對於屬於多個組織(或透過其舊版使用者 API 金鑰訪問其專案)的使用者,您可以選擇指定用於 API 請求的組織和專案。這些 API 請求的使用將計入指定組織和專案的使用量。

配置屬性

音訊語音自動配置的啟用和停用現在透過字首為 spring.ai.model.audio.speech 的頂級屬性進行配置。

要啟用,請設定 spring.ai.model.audio.speech=openai(預設啟用)

要停用,請設定 spring.ai.model.audio.speech=none(或任何不匹配 openai 的值)

此更改是為了允許配置多個模型。

字首 spring.ai.openai.audio.speech 用作屬性字首,允許您配置 OpenAI 文字轉語音客戶端。

財產 描述 預設值

spring.ai.model.audio.speech

啟用音訊語音模型

openai

spring.ai.openai.audio.speech.base-url

要連線的 URL

api.openai.com

spring.ai.openai.audio.speech.api-key

API 金鑰

-

spring.ai.openai.audio.speech.organization-id

您可以選擇指定用於 API 請求的組織。

-

spring.ai.openai.audio.speech.project-id

您可以選擇指定用於 API 請求的專案。

-

spring.ai.openai.audio.speech.options.model

用於生成音訊的模型 ID。可用模型:gpt-4o-mini-tts(預設,針對速度和成本最佳化)、gpt-4o-tts(更高質量)、tts-1(舊版,針對速度最佳化)或 tts-1-hd(舊版,針對質量最佳化)。

gpt-4o-mini-tts

spring.ai.openai.audio.speech.options.voice

用於合成的語音。對於 OpenAI 的 TTS API,所選模型可用的語音之一:alloy、echo、fable、onyx、nova 和 shimmer。

alloy

spring.ai.openai.audio.speech.options.response-format

音訊輸出的格式。支援的格式有 mp3、opus、aac、flac、wav 和 pcm。

mp3

spring.ai.openai.audio.speech.options.speed

語音合成的速度。可接受範圍為 0.25(最慢)到 4.0(最快)。

1.0

您可以覆蓋常用的 spring.ai.openai.base-urlspring.ai.openai.api-keyspring.ai.openai.organization-idspring.ai.openai.project-id 屬性。如果設定了 spring.ai.openai.audio.speech.base-urlspring.ai.openai.audio.speech.api-keyspring.ai.openai.audio.speech.organization-idspring.ai.openai.audio.speech.project-id 屬性,則它們優先於常用屬性。這對於您希望為不同的模型和不同的模型端點使用不同的 OpenAI 賬戶很有用。
所有字首為 spring.ai.openai.audio.speech.options 的屬性都可以在執行時被覆蓋。

執行時選項

OpenAiAudioSpeechOptions 類提供了在進行文字轉語音請求時使用的選項。啟動時,使用 spring.ai.openai.audio.speech 指定的選項,但您可以在執行時覆蓋這些選項。

OpenAiAudioSpeechOptions 類實現了 TextToSpeechOptions 介面,提供了可移植和 OpenAI 特定的配置選項。

例如:

OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
    .model("gpt-4o-mini-tts")
    .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
    .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
    .speed(1.0)
    .build();

TextToSpeechPrompt speechPrompt = new TextToSpeechPrompt("Hello, this is a text-to-speech example.", speechOptions);
TextToSpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);

手動配置

spring-ai-openai 依賴項新增到您的專案的 Maven pom.xml 檔案中

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai</artifactId>
</dependency>

或新增到 Gradle build.gradle 構建檔案中

dependencies {
    implementation 'org.springframework.ai:spring-ai-openai'
}
請參閱依賴管理部分,將 Spring AI BOM 新增到您的構建檔案中。

接下來,建立一個 OpenAiAudioSpeechModel

var openAiAudioApi = new OpenAiAudioApi()
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .build();

var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(openAiAudioApi);

var speechOptions = OpenAiAudioSpeechOptions.builder()
    .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
    .speed(1.0)
    .model(OpenAiAudioApi.TtsModel.GPT_4_O_MINI_TTS.value)
    .build();

var speechPrompt = new TextToSpeechPrompt("Hello, this is a text-to-speech example.", speechOptions);
TextToSpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);

// Accessing metadata (rate limit info)
OpenAiAudioSpeechResponseMetadata metadata = (OpenAiAudioSpeechResponseMetadata) response.getMetadata();

byte[] responseAsBytes = response.getResult().getOutput();

即時音訊流

語音 API 支援使用分塊傳輸編碼進行即時音訊流。這意味著在生成並可訪問完整檔案之前,音訊就可以播放。

OpenAiAudioSpeechModel 實現了 StreamingTextToSpeechModel 介面,提供了標準和流式傳輸功能。

var openAiAudioApi = new OpenAiAudioApi()
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .build();

var openAiAudioSpeechModel = new OpenAiAudioSpeechModel(openAiAudioApi);

OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
    .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
    .speed(1.0)
    .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
    .model(OpenAiAudioApi.TtsModel.GPT_4_O_MINI_TTS.value)
    .build();

TextToSpeechPrompt speechPrompt = new TextToSpeechPrompt("Today is a wonderful day to build something people love!", speechOptions);

Flux<TextToSpeechResponse> responseStream = openAiAudioSpeechModel.stream(speechPrompt);

// You can also stream raw audio bytes directly
Flux<byte[]> audioByteStream = openAiAudioSpeechModel.stream("Hello, world!");

遷移指南

如果您正在從已棄用的 SpeechModelSpeechPrompt 類升級,本指南提供了遷移到新共享介面的詳細說明。

重大變更摘要

此次遷移包括以下重大變更

  1. 已移除的類:已從 org.springframework.ai.openai.audio.speech 包中移除六個已棄用的類

  2. 包變更:核心 TTS 類已移至 org.springframework.ai.audio.tts

  3. 型別變更:所有 OpenAI TTS 元件中的 speed 引數已從 Float 更改為 Double

  4. 介面層次結構TextToSpeechModel 現在擴充套件了 StreamingTextToSpeechModel

類對映參考

已棄用(已移除) 新介面

SpeechModel

TextToSpeechModel

StreamingSpeechModel

StreamingTextToSpeechModel

SpeechPrompt

TextToSpeechPrompt

SpeechResponse

TextToSpeechResponse

SpeechMessage

TextToSpeechMessage

Speech (在 org.springframework.ai.openai.audio.speech 中)

Speech (在 org.springframework.ai.audio.tts 中)

分步遷移說明

第 1 步:更新匯入

將所有從舊的 org.springframework.ai.openai.audio.speech 包匯入的內容替換為新的共享介面

Find:    import org.springframework.ai.openai.audio.speech.SpeechModel;
Replace: import org.springframework.ai.audio.tts.TextToSpeechModel;

Find:    import org.springframework.ai.openai.audio.speech.StreamingSpeechModel;
Replace: import org.springframework.ai.audio.tts.StreamingTextToSpeechModel;

Find:    import org.springframework.ai.openai.audio.speech.SpeechPrompt;
Replace: import org.springframework.ai.audio.tts.TextToSpeechPrompt;

Find:    import org.springframework.ai.openai.audio.speech.SpeechResponse;
Replace: import org.springframework.ai.audio.tts.TextToSpeechResponse;

Find:    import org.springframework.ai.openai.audio.speech.SpeechMessage;
Replace: import org.springframework.ai.audio.tts.TextToSpeechMessage;

Find:    import org.springframework.ai.openai.audio.speech.Speech;
Replace: import org.springframework.ai.audio.tts.Speech;

第 2 步:更新型別引用

替換程式碼中所有型別引用

Find:    SpeechModel
Replace: TextToSpeechModel

Find:    StreamingSpeechModel
Replace: StreamingTextToSpeechModel

Find:    SpeechPrompt
Replace: TextToSpeechPrompt

Find:    SpeechResponse
Replace: TextToSpeechResponse

Find:    SpeechMessage
Replace: TextToSpeechMessage

第 3 步:更新速度引數 (Float → Double)

speed 引數已從 Float 更改為 Double。更新所有出現之處

Find:    .speed(1.0f)
Replace: .speed(1.0)

Find:    .speed(0.5f)
Replace: .speed(0.5)

Find:    Float speed
Replace: Double speed

如果您有序列化資料或配置檔案包含 Float 值,您也需要更新它們

// Before
{
  "speed": 1.0
}

// After (no code change needed for JSON, but be aware of type change in Java)
{
  "speed": 1.0
}

第 4 步:更新 Bean 宣告

如果您有 Spring Boot 自動配置或手動 Bean 定義

// Before
@Bean
public SpeechModel speechModel(OpenAiAudioApi audioApi) {
    return new OpenAiAudioSpeechModel(audioApi);
}

// After
@Bean
public TextToSpeechModel textToSpeechModel(OpenAiAudioApi audioApi) {
    return new OpenAiAudioSpeechModel(audioApi);
}

程式碼遷移示例

示例 1:基本的文字轉語音轉換

之前(已棄用)

import org.springframework.ai.openai.audio.speech.*;

@Service
public class OldNarrationService {

    private final SpeechModel speechModel;

    public OldNarrationService(SpeechModel speechModel) {
        this.speechModel = speechModel;
    }

    public byte[] createNarration(String text) {
        SpeechPrompt prompt = new SpeechPrompt(text);
        SpeechResponse response = speechModel.call(prompt);
        return response.getResult().getOutput();
    }
}

之後(使用共享介面)

import org.springframework.ai.audio.tts.*;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;

@Service
public class NarrationService {

    private final TextToSpeechModel textToSpeechModel;

    public NarrationService(TextToSpeechModel textToSpeechModel) {
        this.textToSpeechModel = textToSpeechModel;
    }

    public byte[] createNarration(String text) {
        TextToSpeechPrompt prompt = new TextToSpeechPrompt(text);
        TextToSpeechResponse response = textToSpeechModel.call(prompt);
        return response.getResult().getOutput();
    }
}

示例 2:使用自定義選項進行文字轉語音

之前(已棄用)

import org.springframework.ai.openai.audio.speech.*;
import org.springframework.ai.openai.api.OpenAiAudioApi;

SpeechModel model = new OpenAiAudioSpeechModel(audioApi);

OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
    .model("tts-1")
    .voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA)
    .speed(1.0f)  // Float value
    .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
    .build();

SpeechPrompt prompt = new SpeechPrompt("Hello, world!", options);
SpeechResponse response = model.call(prompt);
byte[] audio = response.getResult().getOutput();

之後(使用共享介面)

import org.springframework.ai.audio.tts.*;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;
import org.springframework.ai.openai.OpenAiAudioSpeechOptions;
import org.springframework.ai.openai.api.OpenAiAudioApi;

TextToSpeechModel model = new OpenAiAudioSpeechModel(audioApi);

OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
    .model("tts-1")
    .voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA)
    .speed(1.0)  // Double value
    .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
    .build();

TextToSpeechPrompt prompt = new TextToSpeechPrompt("Hello, world!", options);
TextToSpeechResponse response = model.call(prompt);
byte[] audio = response.getResult().getOutput();

示例 3:流式文字轉語音

之前(已棄用)

import org.springframework.ai.openai.audio.speech.*;
import reactor.core.publisher.Flux;

StreamingSpeechModel model = new OpenAiAudioSpeechModel(audioApi);
SpeechPrompt prompt = new SpeechPrompt("Stream this text");

Flux<SpeechResponse> stream = model.stream(prompt);
stream.subscribe(response -> {
    byte[] audioChunk = response.getResult().getOutput();
    // Process audio chunk
});

之後(使用共享介面)

import org.springframework.ai.audio.tts.*;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;
import reactor.core.publisher.Flux;

TextToSpeechModel model = new OpenAiAudioSpeechModel(audioApi);
TextToSpeechPrompt prompt = new TextToSpeechPrompt("Stream this text");

Flux<TextToSpeechResponse> stream = model.stream(prompt);
stream.subscribe(response -> {
    byte[] audioChunk = response.getResult().getOutput();
    // Process audio chunk
});

示例 4:使用 Spring Boot 進行依賴注入

之前(已棄用)

@RestController
public class OldSpeechController {

    private final SpeechModel speechModel;

    @Autowired
    public OldSpeechController(SpeechModel speechModel) {
        this.speechModel = speechModel;
    }

    @PostMapping("/narrate")
    public ResponseEntity<byte[]> narrate(@RequestBody String text) {
        SpeechPrompt prompt = new SpeechPrompt(text);
        SpeechResponse response = speechModel.call(prompt);
        return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType("audio/mpeg"))
            .body(response.getResult().getOutput());
    }
}

之後(使用共享介面)

@RestController
public class SpeechController {

    private final TextToSpeechModel textToSpeechModel;

    @Autowired
    public SpeechController(TextToSpeechModel textToSpeechModel) {
        this.textToSpeechModel = textToSpeechModel;
    }

    @PostMapping("/narrate")
    public ResponseEntity<byte[]> narrate(@RequestBody String text) {
        TextToSpeechPrompt prompt = new TextToSpeechPrompt(text);
        TextToSpeechResponse response = textToSpeechModel.call(prompt);
        return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType("audio/mpeg"))
            .body(response.getResult().getOutput());
    }
}

Spring Boot 配置變更

Spring Boot 自動配置屬性保持不變。您的 application.propertiesapplication.yml 檔案無需更改。

但是,如果您有顯式 Bean 引用或限定符,請更新它們

// Before
@Qualifier("speechModel")

// After
@Qualifier("textToSpeechModel")

遷移的優點

  • 可移植性:一次編寫程式碼,輕鬆在 OpenAI、ElevenLabs 或其他 TTS 提供商之間切換

  • 一致性:與 ChatModel 和其他 Spring AI 抽象採用相同的模式

  • 型別安全:透過正確的介面實現改進型別層次結構

  • 面向未來:新的 TTS 提供商將自動與您現有程式碼相容

  • 標準化:所有 TTS 提供商的速度引數均採用一致的 Double 型別

常見遷移問題及解決方案

問題 1:編譯錯誤 - 找不到符號 SpeechModel

錯誤

error: cannot find symbol SpeechModel

解決方案: 按照第 1 步所述更新您的匯入,將 SpeechModel 更改為 TextToSpeechModel

問題 2:型別不匹配 - Float 無法轉換為 Double

錯誤

error: incompatible types: float cannot be converted to Double

解決方案: 從浮點文字中刪除 f 字尾(例如,將 1.0f 更改為 1.0)。

問題 3:執行時 Bean 建立錯誤

錯誤

NoSuchBeanDefinitionException: No qualifying bean of type 'SpeechModel'

解決方案: 更新您的依賴注入以使用 TextToSpeechModel 而不是 SpeechModel

示例程式碼

© . This site is unofficial and not affiliated with VMware.