本文定位 :这是一篇基于 Spring AI 官方文档 OpenAI Text-to-Speech (TTS) 的二次创作。官方文档以英文参考手册风格编写,本文将其翻译、解读并结合项目实战代码,帮助你快速上手 Spring AI 的语音合成功能。
还是希望对大家有所帮助 ! ! !
官方文档原文链接:
目录
- [1. 官方文档说了什么?------全局概览](#1. 官方文档说了什么?——全局概览)
- [2. 什么是 TTS(文字转语音)?](#2. 什么是 TTS(文字转语音)?)
- [3. 核心类一览](#3. 核心类一览)
- [4. 前置条件(Prerequisites)](#4. 前置条件(Prerequisites))
- [5. 自动配置(Auto-configuration)](#5. 自动配置(Auto-configuration))
- [6. 配置属性详解(Speech Properties)](#6. 配置属性详解(Speech Properties))
- [6.1 连接属性(Connection Properties)](#6.1 连接属性(Connection Properties))
- [6.2 语音模型属性(Configuration Properties)](#6.2 语音模型属性(Configuration Properties))
- [7. 运行时选项(Runtime Options)](#7. 运行时选项(Runtime Options))
- [8. 实战代码讲解](#8. 实战代码讲解)
- [8.1 基础调用:文字转语音并保存文件](#8.1 基础调用:文字转语音并保存文件)
- [8.2 代码逐行解读](#8.2 代码逐行解读)
- [9. 流式实时音频(Streaming Real-time Audio)](#9. 流式实时音频(Streaming Real-time Audio))
- [10. 手动配置(Manual Configuration)](#10. 手动配置(Manual Configuration))
- [11. 可用的声音与音频格式](#11. 可用的声音与音频格式)
- [12. 与 ImageModel、ChatModel 的统一设计对比](#12. 与 ImageModel、ChatModel 的统一设计对比)
- [13. API 迁移指南:SpeechModel → TextToSpeechModel](#13. API 迁移指南:SpeechModel → TextToSpeechModel)
- [14. 常见问题与排错指南](#14. 常见问题与排错指南)
- [15. 总结](#15. 总结)
- [16. 参考资料](#16. 参考资料)
1. 官方文档说了什么?------全局概览
Spring AI 的 OpenAI TTS 官方文档结构如下:
OpenAI Text-to-Speech (TTS)
│
├── Introduction → TTS 能做什么
├── Prerequisites → 前置条件
├── Auto-configuration → 自动配置与依赖
├── Speech Properties → 配置属性
│ ├── Connection Properties → 连接属性
│ └── Configuration Properties → 语音模型属性
├── Runtime Options → 运行时选项覆盖
├── Streaming Real-time Audio → 流式音频
├── Manual Configuration → 手动配置(非 Spring Boot)
├── Migration Guide → 旧 API 迁移指南
└── Example Code → 示例代码
一句话总结 :Spring AI 将 OpenAI 的 TTS API 封装为
OpenAiAudioSpeechModel,遵循和 ChatModel、ImageModel 相同的"构建 Options → 构建 Prompt → 调用 Model → 处理 Response"的统一范式。
2. 什么是 TTS(文字转语音)?
官方原文 (Introduction):
"The Audio API provides a speech endpoint based on OpenAI's TTS (text-to-speech) model, enabling users to:
- Narrate a written blog post.
- Produce spoken audio in multiple languages.
- Give real-time audio output using streaming."
翻译:Audio API 提供了基于 OpenAI TTS 模型的语音端点,使用户能够:
- 为博客文章生成语音朗读
- 生成多种语言的语音
- 使用流式传输提供实时音频输出
简单来说,TTS 就是让 AI "说话"------你给它一段文字,它返回一段音频。
应用场景举例:
- 有声读物 / 博客文章朗读
- 语音助手的回复播报
- 视频配音
- 无障碍访问(为视障用户朗读网页内容)
- 多语言内容本地化
3. 核心类一览
| 类名 | 作用 | 通俗解释 |
|---|---|---|
OpenAiAudioSpeechModel |
语音模型实现类 | "语音引擎",负责调用 OpenAI TTS API |
OpenAiAudioSpeechOptions |
语音选项配置类 | 控制用哪个模型、什么声音、什么格式、语速等 |
SpeechPrompt |
语音请求类(旧版) | 封装"要说的文字"和"选项",传给引擎 |
TextToSpeechPrompt |
语音请求类(新版) | 同上,新版 API 推荐使用 |
SpeechResponse |
语音响应类(旧版) | 引擎返回的结果,包含音频数据 |
TextToSpeechResponse |
语音响应类(新版) | 同上,新版 API 推荐使用 |
OpenAiAudioApi |
底层 API 客户端 | 封装 HTTP 请求细节 |
注意 :
SpeechPrompt/SpeechResponse是旧版类名,新版 Spring AI 已迁移为TextToSpeechPrompt/TextToSpeechResponse。目前旧版仍可使用(向后兼容),但官方推荐逐步迁移到新版。详见第 13 节。
调用流程图
┌──────────────────────────────────────────────────────────────┐
│ 你的代码 │
│ │
│ 1. 构建 Options OpenAiAudioSpeechOptions │
│ ↓ .model("tts-1") │
│ ↓ .voice(NOVA) │
│ ↓ .responseFormat(OPUS) │
│ ↓ .speed(1.0) │
│ │
│ 2. 构建 Prompt SpeechPrompt("要说的文字", options) │
│ ↓ │
│ 3. 调用模型 speechModel.call(prompt) │
│ ↓ │
│ 4. 处理响应 response.getResult().getOutput() │
│ → byte[] 音频数据 │
│ ↓ │
│ 5. 输出 写入文件 / 返回给浏览器 / 流式播放 │
└──────────────────────────────────────────────────────────────┘
4. 前置条件(Prerequisites)
官方原文 :
"1. Create an OpenAI account and obtain an API key. You can sign up at the OpenAI signup page and generate an API key on the API Keys page."
"2. Add the spring-ai-openai dependency to your project's build file."
4.1 获取 API Key
- 打开 OpenAI 官网 注册账号
- 进入 API Keys 页面
- 点击 "Create new secret key" 生成密钥
- 妥善保存密钥
4.2 配置 API Key
推荐通过环境变量配置(和 ChatModel、ImageModel 完全一样):
yaml
# application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
bash
# 设置环境变量
# Linux / macOS
export OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
# Windows PowerShell
$env:OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxx"
5. 自动配置(Auto-configuration)
官方原文 :
"Spring AI provides Spring Boot auto-configuration for the OpenAI Text-to-Speech Client. To enable it add the following dependency to your project's Maven pom.xml file."
添加依赖
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
和 ChatModel、ImageModel 用同一个依赖!
spring-ai-starter-model-openai是 OpenAI 的"全家桶" Starter,同时激活 ChatModel、ImageModel、SpeechModel 的自动配置。加了这一个依赖,所有 OpenAI 模型都可以直接注入使用。
加了这个依赖后,Spring Boot 会自动创建 OpenAiAudioSpeechModel Bean,你可以直接通过 @Autowired 注入。
启用/禁用语音模型
官方原文 :
"Enabling and disabling of the audio speech auto-configurations are now configured via top level properties with the prefixspring.ai.model.audio.speech."
yaml
# 启用(默认就是开启的)
spring.ai.model.audio.speech=openai
# 禁用
spring.ai.model.audio.speech=none
6. 配置属性详解(Speech Properties)
6.1 连接属性(Connection Properties)
官方原文 :
"The prefixspring.ai.openaiis used as the property prefix that lets you connect to OpenAI."
连接属性和 ChatModel、ImageModel 完全共用:
| 属性 | 说明 | 默认值 |
|---|---|---|
spring.ai.openai.base-url |
API 服务器地址 | https://api.openai.com |
spring.ai.openai.api-key |
API 密钥 | 无(必填) |
spring.ai.openai.organization-id |
组织 ID | 无 |
spring.ai.openai.project-id |
项目 ID | 无 |
6.2 语音模型属性(Configuration Properties)
官方原文 :
"The prefixspring.ai.openai.audio.speechis used as the property prefix that lets you configure the OpenAI Text-to-Speech client."
这些是语音合成的核心配置,直接决定生成的语音效果:
| 属性 | 说明 | 默认值 | 详细解释 |
|---|---|---|---|
spring.ai.openai.audio.speech.options.model |
TTS 模型 | gpt-4o-mini-tts |
可选值见下方模型对比表 |
spring.ai.openai.audio.speech.options.voice |
声音 | alloy |
6 种预置声音可选 |
spring.ai.openai.audio.speech.options.response-format |
音频格式 | mp3 |
支持 mp3、opus、aac、flac、wav、pcm |
spring.ai.openai.audio.speech.options.speed |
语速 | 1.0 |
范围 0.25(最慢)~ 4.0(最快) |
语音模型也可以单独覆盖连接属性:
spring.ai.openai.audio.speech.base-urlspring.ai.openai.audio.speech.api-key
TTS 模型对比
| 模型 | 特点 | 适用场景 |
|---|---|---|
gpt-4o-mini-tts(默认) |
速度快、成本低、质量好 | 大多数场景推荐使用 |
gpt-4o-tts |
更高质量 | 对语音质量有更高要求 |
tts-1(旧版) |
速度优化 | 实时应用,延迟敏感 |
tts-1-hd(旧版) |
质量优化 | 音频内容制作,对质量要求高 |
6 种可选声音
| 声音名称 | 特点描述 |
|---|---|
| alloy(默认) | 中性、平衡 |
| echo | 低沉、稳重 |
| fable | 温柔、叙事感 |
| onyx | 深沉、权威 |
| nova | 活泼、年轻 |
| shimmer | 明亮、清晰 |
建议在正式使用前,用同一段文字试听不同声音,选择最适合你应用场景的一种。
音频格式对比
| 格式 | 特点 | 适用场景 |
|---|---|---|
| mp3 | 通用,兼容性最好 | 大多数场景默认选择 |
| opus | 压缩率高,延迟低 | 实时流媒体、网络传输 |
| aac | 苹果生态常用 | iOS / macOS 应用 |
| flac | 无损压缩 | 高质量音频归档 |
| wav | 无压缩,体积大 | 音频后处理、专业编辑 |
| pcm | 原始音频数据 | 需要自定义处理的场景 |
配置文件完整示例
yaml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
audio:
speech:
options:
model: gpt-4o-mini-tts # 使用新版模型
voice: nova # 活泼的声音
response-format: mp3 # MP3 格式
speed: 1.0 # 正常语速
7. 运行时选项(Runtime Options)
官方原文 :
"The OpenAiAudioSpeechOptions class provides the options to use when making a text-to-speech request. On start-up, the options specified byspring.ai.openai.audio.speechare used but you can override these at runtime."翻译:
OpenAiAudioSpeechOptions类提供了发送 TTS 请求时使用的选项。启动时使用配置文件中的值,但你可以在运行时覆盖它们。
和 ChatModel、ImageModel 完全一样的两层配置机制:
配置文件(application.yml) → 默认值(全局生效)
↕ 运行时覆盖
代码中 OpenAiAudioSpeechOptions → 当次请求生效
官方示例:
javaOpenAiAudioSpeechOptions 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);
例如配置文件中默认用 alloy 声音,但某次请求想用 nova:
java
OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
.voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA) // 这次用 nova
.speed(1.5) // 这次语速加快
.build();
SpeechPrompt prompt = new SpeechPrompt("你好,世界!", options);
SpeechResponse response = speechModel.call(prompt);
8. 实战代码讲解
8.1 基础调用:文字转语音并保存文件
以下是项目中 OpenaiSpeechControlelr.java 的完整代码:
java
@Slf4j
@RequestMapping("/speech")
@RestController
public class OpenaiSpeechControlelr {
@Autowired
private OpenAiAudioSpeechModel openAiAudioSpeechModel;
@RequestMapping("/tts")
public void tts(){
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.model("tts-1")
.voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.OPUS)
.speed(1.0f)
.build();
SpeechPrompt speechPrompt = new SpeechPrompt(
"小池, 泉眼无声惜细流, 树阴照水爱晴柔. 小荷才露尖尖角, 早有蜻蜓立上头",
speechOptions);
SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
//输出到文件
File file = new File(System.getProperty("user.dir") +"/output.opus");
try(FileOutputStream fos = new FileOutputStream(file)) {
fos.write(response.getResult().getOutput());
}catch (IOException e){
log.error("文件写入失败, e:", e);
}
}
}
8.2 代码逐行解读
第 1 步:注入语音模型
java
@Autowired
private OpenAiAudioSpeechModel openAiAudioSpeechModel;
通过 @Autowired 注入由 Spring Boot 自动配置创建的 OpenAiAudioSpeechModel Bean。和注入 OpenAiChatModel、OpenAiImageModel 完全一样的方式。
第 2 步:构建语音选项(Options)
java
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.model("tts-1") // 使用 tts-1 模型
.voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA) // 使用 nova 声音
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.OPUS) // 输出 OPUS 格式
.speed(1.0f) // 正常语速
.build();
各参数解读:
| 参数 | 本例中的值 | 含义 |
|---|---|---|
model |
"tts-1" |
使用旧版速度优先模型(新版推荐 gpt-4o-mini-tts) |
voice |
Voice.NOVA |
选择活泼、年轻的 nova 声音 |
responseFormat |
AudioResponseFormat.OPUS |
输出 OPUS 格式(压缩率高,适合网络传输) |
speed |
1.0f |
正常语速(范围 0.25~4.0) |
Voice和AudioResponseFormat都是OpenAiAudioApi.SpeechRequest中定义的枚举,通过枚举选择避免拼写错误。
第 3 步:构建 Prompt 并调用模型
java
SpeechPrompt speechPrompt = new SpeechPrompt(
"小池, 泉眼无声惜细流, 树阴照水爱晴柔. 小荷才露尖尖角, 早有蜻蜓立上头",
speechOptions);
SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
SpeechPrompt 封装了两部分信息:
- 要转换的文本:"小池, 泉眼无声惜细流..."
- 语音选项:用什么模型、什么声音、什么格式
然后调用 speechModel.call(prompt) 发送请求,得到 SpeechResponse。
第 4 步:处理响应------保存为音频文件
java
File file = new File(System.getProperty("user.dir") + "/output.opus");
try(FileOutputStream fos = new FileOutputStream(file)) {
fos.write(response.getResult().getOutput());
} catch (IOException e) {
log.error("文件写入失败, e:", e);
}
调用链解读:
response
.getResult() ← 获取第一个生成结果
.getOutput() ← 获取输出:byte[] 音频字节数组
getOutput() 返回的是 byte[](字节数组),就是音频文件的原始数据。写入文件后就可以用音频播放器打开收听。
与 ImageModel 的对比 :ImageModel 返回的是图片 URL 或 Base64 字符串,而 SpeechModel 返回的是音频字节数组。这是因为图片可以通过 URL 在浏览器中直接展示,而音频通常需要下载或流式播放。
9. 流式实时音频(Streaming Real-time Audio)
官方原文 :
"The Speech API provides support for real-time audio streaming using chunk transfer encoding. This means that the audio is able to be played before the full file has been generated and made accessible."翻译:Speech API 支持使用分块传输编码进行实时音频流式传输。这意味着音频在完整文件生成之前就可以开始播放。
官方原文 :
"The OpenAiAudioSpeechModel implements the StreamingTextToSpeechModel interface, providing both standard and streaming capabilities."
流式传输非常适合长文本朗读的场景------不用等整段音频全部生成完毕,生成一段就播放一段:
java
// 构建选项
OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
.voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
.speed(1.0)
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.model("gpt-4o-mini-tts")
.build();
// 构建 Prompt
TextToSpeechPrompt speechPrompt = new TextToSpeechPrompt(
"Today is a wonderful day to build something people love!",
speechOptions);
// 流式调用------返回 Flux(响应式流)
Flux<TextToSpeechResponse> responseStream = openAiAudioSpeechModel.stream(speechPrompt);
// 也可以直接流式获取原始音频字节
Flux<byte[]> audioByteStream = openAiAudioSpeechModel.stream("Hello, world!");
同步 vs 流式对比:
call()(同步) |
stream()(流式) |
|
|---|---|---|
| 返回类型 | SpeechResponse / TextToSpeechResponse |
Flux<TextToSpeechResponse> / Flux<byte[]> |
| 等待方式 | 等全部音频生成完才返回 | 生成一段返回一段 |
| 用户体验 | 等待时间长,一次性获取 | 边生成边播放,延迟低 |
| 适用场景 | 短文本、后台处理 | 长文本朗读、实时播报 |
10. 手动配置(Manual Configuration)
官方原文 :
"Add thespring-ai-openaidependency to your project's Maven pom.xml file."
如果你不使用 Spring Boot 自动配置,可以手动创建 OpenAiAudioSpeechModel:
xml
<!-- 注意:手动配置使用 spring-ai-openai(不带 starter) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai</artifactId>
</dependency>
java
// 手动创建 API 客户端
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("gpt-4o-mini-tts")
.build();
var speechPrompt = new TextToSpeechPrompt("Hello, this is a text-to-speech example.", speechOptions);
TextToSpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
// 获取音频数据
byte[] audioBytes = response.getResult().getOutput();
// 获取元数据(如速率限制信息)
OpenAiAudioSpeechResponseMetadata metadata =
(OpenAiAudioSpeechResponseMetadata) response.getMetadata();
自动配置 vs 手动配置:
- 自动配置 :加
spring-ai-starter-model-openai依赖 +application.yml配置,Spring Boot 自动创建 Bean- 手动配置 :加
spring-ai-openai依赖,在代码中手动创建 API 客户端和模型对象- 一般用自动配置即可,手动配置适合非 Spring Boot 项目或需要完全自定义的场景
11. 可用的声音与音频格式
声音枚举值
在代码中通过 OpenAiAudioApi.SpeechRequest.Voice 枚举选择:
java
Voice.ALLOY // 中性、平衡
Voice.ECHO // 低沉、稳重
Voice.FABLE // 温柔、叙事感
Voice.ONYX // 深沉、权威
Voice.NOVA // 活泼、年轻
Voice.SHIMMER // 明亮、清晰
音频格式枚举值
通过 OpenAiAudioApi.SpeechRequest.AudioResponseFormat 枚举选择:
java
AudioResponseFormat.MP3 // 最通用
AudioResponseFormat.OPUS // 压缩率高,延迟低
AudioResponseFormat.AAC // 苹果生态
AudioResponseFormat.FLAC // 无损
AudioResponseFormat.WAV // 无压缩
AudioResponseFormat.PCM // 原始数据
语速范围
java
.speed(0.25) // 最慢(4 倍慢速)
.speed(0.5) // 半速
.speed(1.0) // 正常速度
.speed(2.0) // 2 倍速
.speed(4.0) // 最快(4 倍速)
12. 与 ImageModel、ChatModel 的统一设计对比
Spring AI 最优雅的设计之一就是所有模型遵循相同的调用范式。学会一个,触类旁通:
| 步骤 | ChatModel(聊天) | ImageModel(图像) | SpeechModel(语音) |
|---|---|---|---|
| 模型类 | OpenAiChatModel |
OpenAiImageModel |
OpenAiAudioSpeechModel |
| 选项类 | OpenAiChatOptions |
OpenAiImageOptions |
OpenAiAudioSpeechOptions |
| 请求类 | Prompt |
ImagePrompt |
SpeechPrompt / TextToSpeechPrompt |
| 响应类 | ChatResponse |
ImageResponse |
SpeechResponse / TextToSpeechResponse |
| 输出类型 | 文本(String) |
图片 URL / Base64 | 音频字节数组(byte[]) |
| 同步调用 | chatModel.call(prompt) |
imageModel.call(prompt) |
speechModel.call(prompt) |
| 流式调用 | chatModel.stream(prompt) |
--- | speechModel.stream(prompt) |
统一模式:
1. 构建 Options(选项) → XxxOptions.builder()...build()
2. 构建 Prompt(请求) → new XxxPrompt(内容, options)
3. 调用 Model(模型) → model.call(prompt)
4. 处理 Response(响应) → response.getResult().getOutput()
代码层面的一致性------ChatModel 的调用方式:
java
ChatResponse response = chatModel.call(new Prompt("你好",
OpenAiChatOptions.builder().model("gpt-4o").temperature(0.7).build()));
String text = response.getResult().getOutput().getText();
ImageModel 的调用方式:
java
ImageResponse response = imageModel.call(new ImagePrompt("一只猫",
OpenAiImageOptions.builder().quality("hd").N(1).build()));
String imageUrl = response.getResult().getOutput().getUrl();
SpeechModel 的调用方式:
java
SpeechResponse response = speechModel.call(new SpeechPrompt("你好",
OpenAiAudioSpeechOptions.builder().model("tts-1").voice(Voice.NOVA).build()));
byte[] audio = response.getResult().getOutput();
结构完全一致,只是输入/输出的具体类型不同。
13. API 迁移指南:SpeechModel → TextToSpeechModel
官方原文 (Migration Guide):
"If you're upgrading from the deprecated SpeechModel and SpeechPrompt classes, this guide provides detailed instructions for migrating to the new shared interfaces."
Spring AI 在新版本中对语音 API 进行了重构,将旧的类名迁移为更统一的命名。如果你目前使用的是旧版 API(如项目中的 SpeechPrompt、SpeechResponse),未来升级时需要注意。
类名映射表
| 旧版(已废弃) | 新版(推荐) |
|---|---|
SpeechModel |
TextToSpeechModel |
StreamingSpeechModel |
StreamingTextToSpeechModel |
SpeechPrompt |
TextToSpeechPrompt |
SpeechResponse |
TextToSpeechResponse |
SpeechMessage |
TextToSpeechMessage |
包路径变化
旧版:org.springframework.ai.openai.audio.speech.*
新版:org.springframework.ai.audio.tts.*
类型变化
官方原文 :
"The speed parameter changed from Float to Double across all OpenAI TTS components."
java
// 旧版
.speed(1.0f) // Float
// 新版
.speed(1.0) // Double
迁移前后代码对比
旧版代码(项目中当前使用的写法):
java
import org.springframework.ai.openai.audio.speech.SpeechPrompt;
import org.springframework.ai.openai.audio.speech.SpeechResponse;
SpeechPrompt prompt = new SpeechPrompt("你好", options);
SpeechResponse response = speechModel.call(prompt);
byte[] audio = response.getResult().getOutput();
新版代码(官方推荐的写法):
java
import org.springframework.ai.audio.tts.TextToSpeechPrompt;
import org.springframework.ai.audio.tts.TextToSpeechResponse;
TextToSpeechPrompt prompt = new TextToSpeechPrompt("你好", options);
TextToSpeechResponse response = speechModel.call(prompt);
byte[] audio = response.getResult().getOutput();
实际影响:如果你当前使用旧版 API 且项目运行正常,暂时不需要立即迁移。但建议在后续版本升级时逐步切换到新版 API,因为旧版类可能在未来版本中被移除。
14. 常见问题与排错指南
Q1:生成的音频文件无法播放?
可能原因 :文件后缀与实际音频格式不匹配。
解决 :确保文件后缀与 responseFormat 一致。如设置了 AudioResponseFormat.OPUS,文件名就应该是 .opus;设置了 MP3,文件名就应该是 .mp3。
Q2:中文朗读效果不自然?
建议:
- 尝试不同的声音(
Voice.ALLOY、Voice.NOVA等),不同声音对中文的支持效果不同 - 尝试使用新版模型
gpt-4o-mini-tts或gpt-4o-tts,通常比旧版tts-1对中文支持更好 - 在文本中适当添加标点符号,帮助模型理解语句的断句和语气
Q3:音频文件为空(0 字节)?
可能原因:
- API Key 无效或余额不足
- 网络连接问题
- 文本内容为空
排查方法:检查日志中是否有异常信息,确认 API Key 有效且有余额。
Q4:如何控制文件输出路径?
项目代码中使用了 System.getProperty("user.dir"),这会输出到项目的运行目录。你可以改为任意路径:
java
// 输出到指定目录
File file = new File("D:/audio/output.mp3");
// 输出到系统临时目录
File file = new File(System.getProperty("java.io.tmpdir") + "/output.mp3");
Q5:如何将音频直接返回给浏览器?
可以参考 ImageModel 博客中的方式,通过 HttpServletResponse 输出:
java
@RequestMapping("/tts-play")
public void ttsPlay(HttpServletResponse response) {
SpeechResponse speechResponse = openAiAudioSpeechModel.call(
new SpeechPrompt("你好,世界!",
OpenAiAudioSpeechOptions.builder()
.responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
.build()));
byte[] audio = speechResponse.getResult().getOutput();
response.setHeader("Content-Type", "audio/mpeg");
try {
response.getOutputStream().write(audio);
response.getOutputStream().flush();
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
Q6:speed 参数用 Float 还是 Double?
取决于你使用的 Spring AI 版本:
- 旧版 API (
SpeechPrompt):使用Float,如.speed(1.0f) - 新版 API (
TextToSpeechPrompt):使用Double,如.speed(1.0)
15. 总结
本文沿着官方文档的脉络,对 Spring AI 的 OpenAI TTS 功能进行了完整解读:
| 官方文档章节 | 本文对应 | 核心要点 |
|---|---|---|
| Introduction | 第 2 章 | TTS 就是让 AI "说话",文字转音频 |
| Prerequisites | 第 4 章 | 获取 API Key,通过环境变量安全配置 |
| Auto-configuration | 第 5 章 | 一个 Starter 依赖自动注入 SpeechModel |
| Speech Properties | 第 6 章 | 模型、声音、格式、语速四大核心配置 |
| Runtime Options | 第 7 章 | 配置文件设默认 + 代码运行时覆盖 |
| Streaming Real-time Audio | 第 9 章 | stream() 实现边生成边播放 |
| Manual Configuration | 第 10 章 | 非 Spring Boot 项目的手动配置方式 |
| Migration Guide | 第 13 章 | SpeechPrompt → TextToSpeechPrompt 迁移路径 |
核心认知:
- Spring AI 的语音合成与聊天模型、图像生成遵循完全相同的调用范式 :
构建 Options → 构建 Prompt → 调用 call()/stream() → 处理 Response - 输出结果是
byte[]音频字节数组,可以保存为文件或直接返回给前端播放 - 6 种预置声音 + 6 种音频格式 + 灵活的语速控制,满足大部分 TTS 需求
- 新版 API 已将
SpeechModel重构为TextToSpeechModel,建议新项目直接使用新版 API
16. 参考资料
Spring AI 官方文档
- OpenAI Text-to-Speech (TTS) --- 本文主要参考
- Text-To-Speech (TTS) API --- TTS 通用接口文档
- OpenAI Chat --- 聊天模型(类比理解)
- OpenAI Image --- 图像模型(类比理解)
OpenAI 官方文档
- OpenAI TTS API Reference --- TTS API 参考
- OpenAI TTS Guide --- TTS 使用指南
- OpenAI Models --- 模型列表
其他
- Spring AI GitHub 仓库
- OpenAiSpeechModelIT.java --- 官方测试用例