OpenAI 文字轉語音 (TTS)
先決條件
-
建立 OpenAI 賬戶並獲取 API 金鑰。您可以在 OpenAI 註冊頁面 註冊,並在 API 金鑰頁面 生成 API 金鑰。
-
將
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 |
|
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=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 |
|
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 |
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-url、spring.ai.openai.api-key、spring.ai.openai.organization-id 和 spring.ai.openai.project-id 屬性。如果設定了 spring.ai.openai.audio.speech.base-url、spring.ai.openai.audio.speech.api-key、spring.ai.openai.audio.speech.organization-id 和 spring.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!");
遷移指南
如果您正在從已棄用的 SpeechModel 和 SpeechPrompt 類升級,本指南提供了遷移到新共享介面的詳細說明。
重大變更摘要
此次遷移包括以下重大變更
-
已移除的類:已從
org.springframework.ai.openai.audio.speech包中移除六個已棄用的類 -
包變更:核心 TTS 類已移至
org.springframework.ai.audio.tts包 -
型別變更:所有 OpenAI TTS 元件中的
speed引數已從Float更改為Double -
介面層次結構:
TextToSpeechModel現在擴充套件了StreamingTextToSpeechModel
類對映參考
| 已棄用(已移除) | 新介面 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
分步遷移說明
第 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.properties 或 application.yml 檔案無需更改。
但是,如果您有顯式 Bean 引用或限定符,請更新它們
// Before
@Qualifier("speechModel")
// After
@Qualifier("textToSpeechModel")
遷移的優點
-
可移植性:一次編寫程式碼,輕鬆在 OpenAI、ElevenLabs 或其他 TTS 提供商之間切換
-
一致性:與 ChatModel 和其他 Spring AI 抽象採用相同的模式
-
型別安全:透過正確的介面實現改進型別層次結構
-
面向未來:新的 TTS 提供商將自動與您現有程式碼相容
-
標準化:所有 TTS 提供商的速度引數均採用一致的
Double型別
示例程式碼
-
OpenAiSpeechModelIT.java 測試提供了一些如何使用該庫的通用示例。