您可以使用 Gemini TTS 模型(gemini-3.8-flash-tts 或 gemini-3.8-flash-lite-tts)根据文本合成自然、富有表现力的语音(音频)。使用 Firebase AI Logic 时,您可以直接从移动应用或 Web 应用(例如 Apple [Swift]、Android [Kotlin/Java]、Web [JavaScript]、Flutter [Dart] 或 Unity 应用)发出此请求。
文字转语音 (TTS) 生成是可控的,这意味着您可以提供确切的文本来合成为语音,同时使用结构化元数据和内嵌语音标签来引导语音的呈现方式,例如情感、节奏、说话者声音以及笑声或叹息等非语音声音。您可以将 TTS 视为转录(语音转文字)的反向过程。
借助此功能,您可以构建以下功能:
- 互动式讲故事和有声读物:讲述长篇故事或角色扮演游戏,其中角色会切换声音、通过重叠的反馈相互回应,并调整情感表达(例如在悬疑时低语或在讲笑话时大笑)。
- 低延迟语音代理和助理:在 LLM 生成文本后立即流式传输合成语音,在对话轮次中保持一致的语音角色。
- 多语言内容朗读者和语言导师:以 130 多种语言和地区口音朗读文章、食谱或学习资料,或在单次对话中无缝切换语言。
本指南介绍了如何生成单说话者和多说话者语音、流式传输音频回答、使用 SpeechMetadata 和内嵌标记直接进行语音传递,以及从预构建、库或自定义语音中进行选择。
TTS 与 Live API 的比较
文字转语音 (TTS) 模型和 Live API 模型都是低延迟、语音生成模型,可以针对不同的回答语音和语言进行配置。不过,两者的应用场景大不相同。
文字转语音 (TTS) 生成是一种单向请求-响应互动(文本输入,音频输出)。它专为需要精确朗读所提供文本的场景而设计,可对风格和声音进行精细控制,例如播客旁白、有声读物或朗读文章。
Live API 代支持双向流式传输,可实现实时语音对话(语音输入、语音输出)。它在动态对话场景中表现出色,模型可以根据上下文决定返回适用的语音。请注意,最新的 Live API 模型还支持视频和图片输入。
准备工作
|
点击您的 Gemini API 提供商,以查看此页面上特定于提供商的内容和代码。 |
如果您尚未完成入门指南,请先完成该指南,其中介绍了如何设置 Firebase 项目、将应用连接到 Firebase、添加 SDK、为所选的 Gemini API 提供程序初始化后端服务,以及创建 GenerativeModel 实例。
如需测试和迭代提示,我们建议使用 Google AI Studio。
支持此功能的模型
gemini-3.8-flash-ttsgemini-3.8-flash-lite-tts
TTS 模型比较
两个 Gemini 3.x TTS 模型具有相同的请求架构和提示格式。不过,以下是您可能使用每种模型的一些差异。
| 功能或工作负载 | gemini-3.8-flash-tts |
gemini-3.8-flash-lite-tts |
|---|---|---|
| 主要优势 | 录音室级语音保真度、细致入微的表演和广泛的方言覆盖 | 高吞吐量、低延迟和高成本效益 |
| 最佳应用场景 | 有声读物、录音室旁白、复杂的多人对话、频繁的语音突发标记、发音困难、区域方言 | 大批量制作、实时语音智能体级联、大声朗读界面功能、日常单人语音 |
| 支持的语言 | 132 种语言 | 103 种语言 |
根据文本生成语音
您可以根据文本输入生成单人语音或双人对话,输出格式可以是完整的 WAV 文件 (generateContent),也可以是低延迟的原始 PCM 音频串流 (generateContentStream)。
生成单人语音
|
在试用此示例之前,请先完成本指南的准备工作部分,以设置您的项目和应用。 在该部分中,您还需要点击所选 Gemini API 提供商对应的按钮,以便在此页面上查看特定于提供商的内容。 |
以下是生成单人音频的方法:
在
GenerationConfig中,将responseModalities设置为AUDIO,并使用以下内容配置SpeechConfig:(必需)语音名称或 ID。这可以是预构建的声音(例如
Kore)、扩展声音库声音 ID 或自定义声音voice_.../voicekey_...ID。(可选)BCP-47 语言代码。如果省略,模型会自动检测语言。
创建一个包含以下内容的
TextPart:(必需)要朗读的逐字转写文稿。
(可选)具有
style说明的SpeechMetadata(例如"cheerful and friendly")。
调用
generateContent。 默认情况下,一元请求会在响应的内嵌数据部分返回完整的 WAV (audio/wav) 音频文件(16 位线性 PCM、24 kHz、单声道,带有标准 44 字节 RIFF 标头)。
Swift
import FirebaseAILogic
// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())
// Set `responseModalities` to include `.audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
responseModalities: [.audio],
speechConfig: SpeechConfig(voiceName: "Kore", languageCode: "en-US")
)
// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
)
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
let prompt = TextPart(
"Have a wonderful day!",
speechMetadata: SpeechMetadata(style: "cheerful and friendly")
)
// Call `generateContent` to generate the speech output.
let response = try await model.generateContent(prompt)
// Extract the WAV audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
let wavData = part.data // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
let mimeType = part.mimeType // for example: "audio/wav"
print("Received audio data with MIME type: \(mimeType)")
// Play the WAV audio data using your own playback helper (for example, with `AVAudioPlayer(data: wavData)`).
playAudio(data: wavData)
}
Kotlin
对于 Kotlin,此 SDK 中的方法是挂起函数,需要从协程作用域中调用。
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
responseModalities = listOf(ResponseModality.AUDIO)
speechConfig = SpeechConfig(
voice = Voice("Kore"),
languageCode = "en-US"
)
}
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "gemini-3.8-flash-tts",
generationConfig = config
)
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
val prompt = content {
text(
text = "Have a wonderful day!",
speechMetadata = SpeechMetadata(style = "cheerful and friendly")
)
}
// Call `generateContent` to generate the speech output.
val response = model.generateContent(prompt)
// Extract the WAV audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
val wavData = part.inlineData // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
playAudio(wavData)
}
Java
对于 Java,此 SDK 中的流式传输方法会返回 Reactive Streams 库中的Publisher 类型。
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
.setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
.setSpeechConfig(new SpeechConfig(new Voice("Kore"), "en-US"))
.build();
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
.generativeModel("gemini-3.8-flash-tts", config);
// Use the GenerativeModelFutures Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
Content content = new Content.Builder()
.addText("Have a wonderful day!", new SpeechMetadata(null, "cheerful and friendly"))
.build();
Executor executor = Executors.newSingleThreadExecutor();
// Call `generateContent` to generate the speech output.
// Extract the WAV audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
Part part = result.getCandidates().get(0).getContent().getParts().get(0);
if (part instanceof InlineDataPart) {
byte[] wavData = ((InlineDataPart) part).getInlineData(); // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
playAudio(wavData);
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Web
import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";
// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);
// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
responseModalities: [ResponseModality.AUDIO],
speechConfig: {
voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } },
languageCode: "en-US"
}
};
// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
model: "gemini-3.8-flash-tts",
generationConfig
});
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
const prompt = [
{
type: "text",
text: "Have a wonderful day!",
speechMetadata: { style: "cheerful and friendly" }
}
];
// Call `generateContent` to generate the speech output.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();
// Extract the WAV audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
const wavBase64 = inlineDataParts[0].inlineData.data; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Decode base64 to ArrayBuffer
const wavBuffer = Uint8Array.from(atob(wavBase64), c => c.charCodeAt(0)).buffer;
// The response is a complete WAV file, so the Web Audio API can decode and play it directly.
const audioCtx = new AudioContext();
const audioBuffer = await audioCtx.decodeAudioData(wavBuffer);
const source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
source.start();
}
Dart
import 'package:firebase_ai/firebase_ai.dart';
// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
responseModalities: [ResponseModalities.audio],
speechConfig: SpeechConfig(voiceName: 'Kore', languageCode: 'en-US'),
);
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
model: 'gemini-3.8-flash-tts',
generationConfig: config,
);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
final prompt = Content.multi([
TextPart(
'Have a wonderful day!',
speechMetadata: SpeechMetadata(style: 'cheerful and friendly'),
),
]);
// Call `generateContent` to generate the speech output.
final response = await model.generateContent([prompt]);
// Extract the WAV audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
final Uint8List wavData = part.bytes; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Play the WAV audio data using your preferred audio player or helper (which you'll need to implement).
await playAudio(wavData);
}
Unity
using Firebase.AI;
// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());
// Set `responseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name and language code.
var config = new GenerationConfig(
responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
speechConfig: SpeechConfig.UsePrebuiltVoice("Kore", "en-US")
);
// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
var prompt = new ModelContent(
new ModelContent.TextPart(
"Have a wonderful day!",
new SpeechMetadata(speaker: null, style: "cheerful and friendly")
)
);
// Call `GenerateContentAsync` to generate the speech output.
var response = await model.GenerateContentAsync(prompt);
// Extract the WAV audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
foreach (var part in response.Candidates[0].Content.Parts) {
if (part is ModelContent.InlineDataPart inlineData) {
byte[] wavData = inlineData.Data; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
PlayAudio(wavData);
}
}
}
生成包含多个发言人的语音
|
在试用此示例之前,请先完成本指南的准备工作部分,以设置您的项目和应用。 在该部分中,您还需要点击所选 Gemini API 提供商对应的按钮,以便在此页面上查看特定于提供商的内容。 |
您可以在单个请求中生成自然的双人对话,方法是为每个说话者分配不同的声音,并将每行对话作为其自己的 TextPart 传递:
创建一个
MultiSpeakerVoiceConfig,将两个说话者姓名(例如"Joe"和"Jane")映射到其SpeakerVoiceConfig声音。在
GenerationConfig中,将responseModalities设置为AUDIO,并将MultiSpeakerVoiceConfig(和可选的languageCode)传递到SpeechConfig中。提供一个
TextPart对象数组或列表,具体而言,每个对话轮次对应一个TextPart。在每个TextPart上,使用以下命令设置SpeechMetadata:- (必需)与
MultiSpeakerVoiceConfig中定义的某个说话者名称匹配的speaker。 - (可选)
style说明(例如"cheerful and friendly")。
- (必需)与
调用
generateContent。 模型会合成完整对话,并返回完整的 WAV (audio/wav) 音频文件。
Swift
import FirebaseAILogic
// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
let multiSpeechConfig = SpeechConfig(
multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
speakerVoiceConfigs: [
SpeakerVoiceConfig(speaker: "Joe", voiceName: "Puck"),
SpeakerVoiceConfig(speaker: "Jane", voiceName: "Kore")
]
),
languageCode: "en-US"
)
// Set `responseModalities` to include `.audio`.
let config = GenerationConfig(
responseModalities: [.audio],
speechConfig: multiSpeechConfig
)
// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
)
// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
let prompt: [any PartsRepresentable] = [
TextPart(
"How's it going today, Jane?",
speechMetadata: SpeechMetadata(speaker: "Joe", style: "cheerful and friendly")
),
TextPart(
"Not too bad, how about you?",
speechMetadata: SpeechMetadata(speaker: "Jane", style: "calm and relaxed")
)
]
// Call `generateContent` to generate the multi-speaker speech output.
let response = try await model.generateContent(prompt)
// Extract the WAV audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
let wavData = part.data // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
let mimeType = part.mimeType // for example: "audio/wav"
print("Received audio data with MIME type: \(mimeType)")
// Play the WAV audio data using your own playback helper (for example, with `AVAudioPlayer(data: wavData)`).
playAudio(data: wavData)
}
Kotlin
对于 Kotlin,此 SDK 中的方法是挂起函数,需要从协程作用域中调用。
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
val multiSpeechConfig = SpeechConfig(
multiSpeakerVoiceConfig = MultiSpeakerVoiceConfig(
speakerVoiceConfigs = listOf(
SpeakerVoiceConfig(speaker = "Joe", voice = Voice("Puck")),
SpeakerVoiceConfig(speaker = "Jane", voice = Voice("Kore"))
)
),
languageCode = "en-US"
)
// Set `responseModalities` to include `AUDIO`.
val config = generationConfig {
responseModalities = listOf(ResponseModality.AUDIO)
speechConfig = multiSpeechConfig
}
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "gemini-3.8-flash-tts",
generationConfig = config
)
// Provide one text part per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
val prompt = content {
text(
text = "How's it going today, Jane?",
speechMetadata = SpeechMetadata(speaker = "Joe", style = "cheerful and friendly")
)
text(
text = "Not too bad, how about you?",
speechMetadata = SpeechMetadata(speaker = "Jane", style = "calm and relaxed")
)
}
// Call `generateContent` to generate the multi-speaker speech output.
val response = model.generateContent(prompt)
// Extract the WAV audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
val wavData = part.inlineData // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
playAudio(wavData)
}
Java
对于 Java,此 SDK 中的流式传输方法会返回 Reactive Streams 库中的Publisher 类型。
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
MultiSpeakerVoiceConfig multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
Arrays.asList(
new SpeakerVoiceConfig("Joe", new Voice("Puck")),
new SpeakerVoiceConfig("Jane", new Voice("Kore"))
)
);
SpeechConfig multiSpeechConfig = new SpeechConfig(multiSpeakerVoiceConfig, "en-US");
// Set `responseModalities` to include `AUDIO`.
GenerationConfig config = new GenerationConfig.Builder()
.setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
.setSpeechConfig(multiSpeechConfig)
.build();
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
.generativeModel("gemini-3.8-flash-tts", config);
// Use the `GenerativeModelFutures` Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);
// Provide one text part per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
Content content = new Content.Builder()
.addText(
"How's it going today, Jane?",
new SpeechMetadata("Joe", "cheerful and friendly"))
.addText(
"Not too bad, how about you?",
new SpeechMetadata("Jane", "calm and relaxed"))
.build();
Executor executor = Executors.newSingleThreadExecutor();
// Call `generateContent` to generate the multi-speaker speech output.
// Extract the WAV audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
Part part = result.getCandidates().get(0).getContent().getParts().get(0);
if (part instanceof InlineDataPart) {
byte[] wavData = ((InlineDataPart) part).getInlineData(); // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
playAudio(wavData);
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Web
import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";
// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);
// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
const generationConfig = {
responseModalities: [ResponseModality.AUDIO],
speechConfig: {
multiSpeakerVoiceConfig: {
speakerVoiceConfigs: [
{ speaker: "Joe", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } } },
{ speaker: "Jane", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
]
},
languageCode: "en-US"
}
};
// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
model: "gemini-3.8-flash-tts",
generationConfig
});
// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `speechMetadata`.
const prompt = [
{
type: "text",
text: "How's it going today, Jane?",
speechMetadata: { speaker: "Joe", style: "cheerful and friendly" }
},
{
type: "text",
text: "Not too bad, how about you?",
speechMetadata: { speaker: "Jane", style: "calm and relaxed" }
}
];
// Call `generateContent` to generate the multi-speaker speech output.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();
// Extract the WAV audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
const wavBase64 = inlineDataParts[0].inlineData.data; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Decode base64 to ArrayBuffer
const wavBuffer = Uint8Array.from(atob(wavBase64), c => c.charCodeAt(0)).buffer;
// The response is a complete WAV file, so the Web Audio API can decode and play it directly.
const audioCtx = new AudioContext();
const audioBuffer = await audioCtx.decodeAudioData(wavBuffer);
const source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
source.start();
}
Dart
import 'package:firebase_ai/firebase_ai.dart';
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
final multiSpeechConfig = SpeechConfig.multiSpeaker(
multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
speakerVoiceConfigs: [
SpeakerVoiceConfig(speaker: 'Joe', voiceName: 'Puck'),
SpeakerVoiceConfig(speaker: 'Jane', voiceName: 'Kore'),
],
),
languageCode: 'en-US',
);
// Set `responseModalities` to include `audio`.
final config = GenerationConfig(
responseModalities: [ResponseModalities.audio],
speechConfig: multiSpeechConfig,
);
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
model: 'gemini-3.8-flash-tts',
generationConfig: config,
);
// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
final prompt = Content.multi([
TextPart(
"How's it going today, Jane?",
speechMetadata: SpeechMetadata(speaker: 'Joe', style: 'cheerful and friendly'),
),
TextPart(
'Not too bad, how about you?',
speechMetadata: SpeechMetadata(speaker: 'Jane', style: 'calm and relaxed'),
),
]);
// Call `generateContent` to generate the multi-speaker speech output.
final response = await model.generateContent([prompt]);
// Extract the WAV audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
final Uint8List wavData = part.bytes; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Play the WAV audio data using your preferred audio player or helper (which you'll need to implement).
await playAudio(wavData);
}
Unity
using Firebase.AI;
// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
var multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
new System.Collections.Generic.List<SpeakerVoiceConfig> {
SpeakerVoiceConfig.UsePrebuiltVoice("Joe", "Puck"),
SpeakerVoiceConfig.UsePrebuiltVoice("Jane", "Kore")
}
);
var multiSpeechConfig = SpeechConfig.UseMultiSpeakerVoice(multiSpeakerVoiceConfig, "en-US");
// Set `responseModalities` to include `Audio`.
var config = new GenerationConfig(
responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
speechConfig: multiSpeechConfig
);
// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
);
// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
var prompt = new ModelContent(
new ModelContent.TextPart(
"How's it going today, Jane?",
new SpeechMetadata(speaker: "Joe", style: "cheerful and friendly")
),
new ModelContent.TextPart(
"Not too bad, how about you?",
new SpeechMetadata(speaker: "Jane", style: "calm and relaxed")
)
);
// Call `GenerateContentAsync` to generate the multi-speaker speech output.
var response = await model.GenerateContentAsync(prompt);
// Extract the WAV audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
foreach (var part in response.Candidates[0].Content.Parts) {
if (part is ModelContent.InlineDataPart inlineData) {
byte[] wavData = inlineData.Data; // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
// Pass the audio data to your audio player or playback helper (which you'll need to implement).
PlayAudio(wavData);
}
}
}
流式传输回答
|
在试用此示例之前,请先完成本指南的准备工作部分,以设置您的项目和应用。 在该部分中,您还需要点击所选 Gemini API 提供商对应的按钮,以便在此页面上查看特定于提供商的内容。 |
为了缩短第一个音频的时间 (TTFA) 并实现实时播放,您可以在生成音频回答时对其进行流式传输,而无需等待整个片段完成。流式传输适用于单说话者和多说话者配置。
如需流式传输语音,请调用 generateContentStream,而不是 generateContent。与一元请求(返回 WAV 文件)不同,流式请求会返回无标头的原始 16 位有符号小端字节序 PCM 块(audio/l16、24 kHz、单声道),因此您可以将每个块直接附加到音频输出缓冲区。
Swift
import FirebaseAILogic
// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())
// Set `responseModalities` to include `.audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
responseModalities: [.audio],
speechConfig: SpeechConfig(voiceName: "Kore")
)
// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
)
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
let prompt = TextPart(
"Tell me a story about a brave knight.",
speechMetadata: SpeechMetadata(style: "warm, engaging audiobook narrator")
)
// Call `generateContentStream` to stream the speech output as it is generated.
let responseStream = try model.generateContentStream(prompt)
// Extract the raw PCM audio chunks and queue them for playback:
for try await chunk in responseStream {
for part in chunk.inlineDataParts {
let pcmChunk = part.data // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
// Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
appendAudioChunk(pcmChunk)
}
}
Kotlin
对于 Kotlin,此 SDK 中的方法是挂起函数,需要从协程作用域中调用。
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
responseModalities = listOf(ResponseModality.AUDIO)
speechConfig = SpeechConfig(voice = Voice("Kore"))
}
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "gemini-3.8-flash-tts",
generationConfig = config
)
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
val prompt = content {
text(
text = "Tell me a story about a brave knight.",
speechMetadata = SpeechMetadata(style = "warm, engaging audiobook narrator")
)
}
// Call `generateContentStream` to stream the speech output as it is generated.
// Extract the raw PCM audio chunks and queue them for playback.
model.generateContentStream(prompt).collect { chunk ->
val part = chunk.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
val pcmChunk = part.inlineData // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
// Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
appendAudioChunk(pcmChunk)
}
}
Java
对于 Java,此 SDK 中的流式传输方法会返回 Reactive Streams 库中的Publisher 类型。
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
.setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
.setSpeechConfig(new SpeechConfig(new Voice("Kore")))
.build();
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
.generativeModel("gemini-3.8-flash-tts", config);
// Use the `GenerativeModelFutures` Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
Content content = new Content.Builder()
.addText(
"Tell me a story about a brave knight.",
new SpeechMetadata(null, "warm, engaging audiobook narrator"))
.build();
// Call `generateContentStream` to stream the speech output as it is generated.
Publisher<GenerateContentResponse> streamingResponse =
model.generateContentStream(content);
// Extract the raw PCM audio chunks and queue them for playback.
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(GenerateContentResponse chunk) {
Part part = chunk.getCandidates().get(0).getContent().getParts().get(0);
if (part instanceof InlineDataPart) {
byte[] pcmChunk = ((InlineDataPart) part).getInlineData(); // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
// Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
appendAudioChunk(pcmChunk);
}
}
@Override
public void onComplete() {
// Audio stream complete.
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
});
Web
import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";
// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);
// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });
// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
responseModalities: [ResponseModality.AUDIO],
speechConfig: {
voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } }
}
};
// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
model: "gemini-3.8-flash-tts",
generationConfig
});
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
const prompt = [
{
type: "text",
text: "Tell me a story about a brave knight.",
speechMetadata: { style: "warm, engaging audiobook narrator" }
}
];
// Call `generateContentStream` to stream the speech output as it is generated.
const result = await model.generateContentStream(prompt);
// Extract the raw PCM audio chunks and queue them for playback:
const playbackQueue = [];
for await (const chunk of result.stream) {
const inlineDataParts = chunk.inlineDataParts();
if (inlineDataParts?.[0]) {
const pcmBase64 = inlineDataParts[0].inlineData.data; // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
const pcmBuffer = Uint8Array.from(atob(pcmBase64), c => c.charCodeAt(0)).buffer;
// Append the audio chunk to your audio queue/buffer for playback.
// In a real app, start playing chunks as they arrive (rather than waiting for
// the whole stream to finish) to get the low-latency benefit of streaming.
playbackQueue.push(pcmBuffer);
}
}
// To play back an array of PCM buffers in sequence, pass them to your playback helper (which you'll need to write).
processPlaybackQueue(playbackQueue);
Dart
import 'package:firebase_ai/firebase_ai.dart';
// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
responseModalities: [ResponseModalities.audio],
speechConfig: SpeechConfig(voiceName: 'Kore'),
);
// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
model: 'gemini-3.8-flash-tts',
generationConfig: config,
);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
final prompt = Content.multi([
TextPart(
'Tell me a story about a brave knight.',
speechMetadata: SpeechMetadata(style: 'warm, engaging audiobook narrator'),
),
]);
// Call `generateContentStream` to stream the speech output as it is generated.
final responseStream = model.generateContentStream([prompt]);
// Extract the raw PCM audio chunks and queue them for playback:
await for (final chunk in responseStream) {
final part = chunk.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
final Uint8List pcmChunk = part.bytes; // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
// Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
appendAudioChunk(pcmChunk);
}
}
Unity
using System.Collections.Generic;
using System.Linq;
using Firebase.AI;
// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());
// Set `ResponseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
var config = new GenerationConfig(
responseModalities: new List<ResponseModality> { ResponseModality.Audio },
speechConfig: SpeechConfig.UsePrebuiltVoice("Kore")
);
// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
modelName: "gemini-3.8-flash-tts",
generationConfig: config
);
// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
var prompt = new ModelContent(
new ModelContent.TextPart(
"Tell me a story about a brave knight.",
new SpeechMetadata(speaker: null, style: "warm, engaging audiobook narrator")
)
);
// Call `GenerateContentStreamAsync` to stream the speech output as it is generated.
var responseStream = model.GenerateContentStreamAsync(prompt);
// Extract the raw PCM audio chunks and queue them for playback:
await foreach (var response in responseStream)
{
var audioParts = response.Candidates.FirstOrDefault().Content.Parts
.OfType<ModelContent.InlineDataPart>();
foreach (var part in audioParts)
{
byte[] pcmChunk = part.Data; // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
// Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
AppendAudioChunk(pcmChunk);
}
}
使用元数据和内嵌标记控制语音输出
Gemini 3.x TTS 模型会将每个 TextPart 内的 text 严格视为要大声朗读的逐字转写内容。请勿在文本字符串中写入叙述性指令(例如 "Say cheerfully:"),否则模型可能会大声朗读这些字词。
您可以使用以下技巧来指导语音表现:
轮次级 style 和内嵌语音标记
按范围将性能指令拆分为 SpeechMetadata 和内嵌尖括号标记 (<...>)。
| 范围 | 放置位置 | 控制的内容 | 示例 |
|---|---|---|---|
|
轮次级 (在整个轮次中持续存在) |
SpeechMetadata.style
|
情感、角色、语气、语调、音高和整体语速 |
"cheerful and friendly"、"whispered, nervous"、"speaking rapidly"、"out of breath"、"sarcastic"
|
|
时间点 (本地化为句子中的特定时刻) |
使用 <...> 在 TextPart 文本中内嵌
|
非语音的人类声音爆发、呼吸、停顿或瞬间的表达转变 |
"Wait... <short pause> did you hear that? <gasp> Someone's at the door."
|
语速、停顿、音调和强调
标点符号和省略号:在转写文稿中使用逗号、破折号 (
--) 和省略号 (...) 来营造自然的措辞和犹豫感。显式停顿标记:在说话者应停顿的确切位置内嵌插入
<short pause>或<long pause>:Hold on, let me think... <short pause> Alright, I've got it.语速和音高:在
SpeechMetadata中设置style,以控制该轮对话的整体语速、音高或语调(例如"speaking rapidly and excitedly"、"speaking slowly"或"monotone and flat")。如果情感或语速在独白中途发生变化,请将脚本拆分为单独的TextPart轮次,每个轮次都有自己的style。字词强调:将转写内容中的特定字词大写,以强调这些字词:
It was a VERY long day <sigh> ... nobody listens anymore.
语音爆发和非语音声音
使用尖括号 (<...>) 在声音应出现的确切字词边界处插入非语音人类发声。使用人类发声,而非非语言音效。以下是建议使用的标签:
<argh> |
<exhales> |
<heavy breath> |
<scream> |
<snort> |
<breath> |
<gasp> |
<hiss> |
<short pause> |
<sob> |
<cackle> |
<giggle> |
<laugh> /<laughter> |
<shout> |
<throat-clearing> |
<cheer> |
<groan> |
<long pause> |
<shriek> |
<tsk> |
<chuckle> /<chuckles> |
<growl> |
<moan> |
<sigh> /<sighs> |
<whimper> |
<cough> |
<grr> |
<pant> |
<sneeze> |
<whispers> /<whispering> |
<cry> |
<grunt> |
<pff> /<phew> |
<snicker> |
<yawn> |
附和语和语音重叠
在多说话者对话中,您可以在当前说话者的转写内容中,使用竖线字符 (|reaction|) 将听众的简短反应括起来。此时,非活跃说话者可以自然地插话,而无需单独轮到他们:
简短的倾听者反馈:
- 第 1 轮 (
speaker: "Joe"):"So the launch is Thursday |oh hmm| Are we actually ready?" - 第 2 轮 (
speaker: "Jane"):"Ready enough |oh really?| The last blocker cleared this morning."
- 第 1 轮 (
重叠语音:您可以使用多个管道片段来模拟同时说话(与
gemini-3.8-flash-tts搭配使用效果最佳),例如:- 第 1 轮 (
speaker: "Joe"):"Let's surprise him on three |ok| ready?" - 第 2 轮 (
speaker: "Jane"):"one. two. three. |happy| happy |birthday| birthday!"
- 第 1 轮 (
画面统一最佳做法
先在不使用
style的情况下进行测试,然后添加简明扼要的style调整:大多数请求在style字段为空时听起来都很自然。仅当某个回合需要特定的语气调整时,才添加简短的style短语(例如"casual, friendly"或"reflective and awe-inspired"),并在需要一致的基准时在各个回合中重复使用相同的简短字符串。撰写自然的口语转写文稿:直接在转写文稿文本中包含对话缩写和自然的不流畅(例如
"Oh, uh, yeah I think... hm, that's interesting")。避免使用旧版
[Audio Profile]代码块和元指令:长角色段落、[Director's Notes]代码块或"maintain identical timbre"等元指令会增加语音漂移。请改为从扩展语音库中选择匹配的语音,或使用语音设计创建持久的角色语音。请勿尝试替换
style中的不可变语音特征:避免使用SpeechMetadata.style更改语音的年龄、性别或永久口音。而是选择或设计具有这些特征的语音。
支持的语音
Gemini 3.x TTS 模型支持通过三种方式指定语音:
所有语音都是多语言的,这意味着您可以使用相同的语音以任何受支持的语言生成语音,同时保持一致的说话者身份。例如,如果您将声音设置为预构建的 Kore 声音,并以西班牙语、印地语和越南语发送提示,则回答都会使用这些语言的 Kore 声音。30 种核心预构建语音是通用多语言语音,而扩展语音库语音和自定义语音则锚定到主要语言区域或区域口音。这意味着,它们仍然可以讲其他语言,但在其主要语言区域中听起来最地道。
核心预构建语音
Gemini TTS 模型支持 30 种核心预构建语音(例如 Kore、Puck、Zephyr、Charon 和 Fenrir),每种语音都具有独特的语音特征。在 SpeechConfig 中传递语音名称(如本页面前面的单说话者和多说话者示例所示)。
扩展语音库中的预设语音
除了 30 种预构建的声音之外,扩展声音库还提供了 2,000 多种精选预设声音,涵盖各种语言、地区口音、年龄段、角色形象和应用场景(例如有声读物、客户支持客服人员和新闻播报员)。
以下是在应用中使用扩展语音库中任何语音的方法:
使用以下任一选项浏览和预览语音:
使用 Google AI Studio 或 Agent Studio 获取语音
id。查询 Voices API
list方法(ListVoices,带有type=prebuilt和可选的search查询),以获取语音id。如需了解详情,请参阅 Gemini Developer API 文档或 Agent Platform Gemini API (formerly Vertex AI) 文档。
将库语音的
id字符串作为SpeechConfig中的语音名称传递(类似于本页面前面的单说话者示例中所示)。
自定义语音:语音设计和语音复刻
Gemini 3.x TTS 模型还支持使用以下任一选项的自定义语音:
语音设计(预览版):根据对说话者年龄、音色、口音和角色的自然语言描述,生成独特的自定义语音(无需任何参考音频)。返回存储的语音 ID (
voice_...)。语音复刻(预览版):根据参考录音和口头同意录音,复刻说话者的声音、语调和节奏。返回项目存储的语音 ID (
voice_...) 或无状态、应用管理的语音复刻密钥 (voicekey_...)。
在 Firebase AI Logic 应用中使用自定义语音
创建和管理自定义语音是一项管理或服务器端操作,因此 Firebase AI Logic 客户端 SDK 不会直接公开语音管理端点(CreateVoice、ListVoices、DeleteVoice)。
如需使用自定义声音,您需要执行以下操作:
使用以下任一选项创建自定义语音:
使用 Google AI Studio 或 Agent Studio 获取
voice_<id>或voicekey_<id>标识符。使用 Voices API 获取
voice_<id>或voicekey_<id>标识符。如需了解详情,请参阅您所选 Gemini API 提供商的文档:
将
voice_<id>或voicekey_<id>字符串作为SpeechConfig中的语音名称传递(类似于本页面前面的单说话者示例中所示)。
使用自定义语音时,请注意以下要求:
位置 (Agent Platform Gemini API (formerly Vertex AI)):自定义语音(
voice_...和voicekey_...)仅在global位置(使用 Firebase AI Logic 时的默认位置)受支持。单说话者请求:
MultiSpeakerVoiceConfig仅支持核心预构建语音。如需在多角色对话中使用自定义设计或复制的声音,请在单独的单说话人请求中合成每个角色的对话。保留和到期:存储的自定义语音 (
voice_...) 如果 1 年未使用,则会到期(每次合成请求都会重置 1 年保留计时器);无状态语音复刻密钥 (voicekey_...) 在创建 7 天后到期。
支持的语言
Gemini 3.x TTS 模型会自动检测输入文本中的语言,包括在多说话者对话中提示在不同轮次之间切换语言的情况。
- Gemini 3.8 Flash TTS (
gemini-3.8-flash-tts):支持 132 种语言。 - Gemini 3.8 Flash‑Lite TTS (
gemini-3.8-flash-lite-tts):支持 103 种语言。
(可选)明确设置语言代码
如果您想明确将语音合成限制在特定语言区域,可以在 SpeechConfig 中传递 BCP-47 languageCode:
音频输出格式
InlineDataPart 中返回的默认音频格式取决于您发出的是一元请求还是流式请求:
| 请求方法 | 默认返回的 MIME 类型 | 音频格式详情 |
|---|---|---|
|
一元 ( generateContent)
|
audio/wav
|
完整的 WAV 文件(16 位线性 PCM、24 kHz、单声道、小端序),带有标准的 44 字节 RIFF 标头。
可由标准平台音频播放器(例如 Apple 平台上的 |
|
流式 ( generateContentStream)
|
audio/l16
|
无标头的原始 16 位有符号小端序 PCM 数据块,采样率 24 kHz,单声道。 专为低延迟缓冲区队列和串联而设计,无需每个分块文件标头。 |
限制和要求
使用 Gemini 3.x TTS 模型时,请注意以下限制和要求:
纯文本输入,纯音频输出:TTS 模型仅接受文本输入 (
TextPart),并且需要将responseModalities设置为AUDIO。仅逐字合成:模型会逐字朗读提供的转写内容,不会生成对话式文本回复。
Token 限制:每个请求的输入上限为 8,192 个 token,输出上限为 16,384 个 token。
多位说话者限制:
MultiSpeakerVoiceConfig需要 2 位说话者,并且仅支持核心预构建语音。多说话人请求中的每个TextPart都必须包含与其中一个已配置说话人匹配的SpeechMetadata.speaker。不支持的参数和方法:
- Firebase AI Logic SDK 尚不支持在
GenerationConfig中设置responseFormat以替换默认音频输出格式。 - 不支持设置
systemInstruction、temperature、topP、topK、candidateCount、presencePenalty或frequencyPenalty,这会导致请求失败并出现400 INVALID_ARGUMENT错误。 - TTS 模型不支持调用
countTokens(词元计数在响应的usageMetadata中返回)。
- Firebase AI Logic SDK 尚不支持在
位置 (Agent Platform Gemini API (formerly Vertex AI)):自定义语音(
voice_...和voicekey_...)需要global位置(使用 Firebase AI Logic 时的默认位置)。
从 gemini-3.1-flash-tts-preview 迁移
gemini-3.8-flash-tts 和 gemini-3.8-flash-lite-tts 使用相同的请求结构。查看模型对比表,选择最适合您工作负载的替代模型,并按如下方式更新代码:
| 面积 |
gemini-3.1-flash-tts-preview(旧版)
|
gemini-3.8-flash-tts和gemini-3.8-flash-lite-tts
|
|---|---|---|
| 交付方式和方向 |
嵌入在提示文本中。例如:"Say cheerfully: ..."、[Audio Profile]、[Director's Notes]
|
在每个 TextPart 上以 SpeechMetadata(style: "...") 传递
|
| 多说话者对话 |
包含内嵌 "Speaker: ..." 前缀的单个文本字符串
|
每轮对话一个 TextPart,每个 TextPart 上都有 SpeechMetadata(speaker: "...", style: "...")
|
| 内嵌语音标记 |
方括号。例如,[sigh] 或 [laughs]
|
尖括号。例如,<sigh> 或
<laugh> 或
<short pause>
直接在文本中写入 |
默认一元音频格式 (generateContent)
|
无标头的原始 16 位 PCM(audio/pcm、24 kHz、单声道)
|
完整的 WAV 文件(audio/wav、16 位 PCM、24 kHz、单声道,带有 44 字节 RIFF 标头)
Streaming ( |
| 系统指令、温度、Top-P、Top-K | 已忽略 |
请求会遭到拒绝,并显示 400 INVALID_ARGUMENT 错误。从模型配置中移除这些参数。
|
迁移核对清单
升级到最新版本的 Firebase AI Logic SDK,并将模型名称更新为
gemini-3.8-flash-tts或gemini-3.8-flash-lite-tts。将样式说明移至
SpeechMetadata.style:从提示字符串中移除"Say cheerfully:"前缀、[Audio Profile]、[Scene]和[Director's Notes]代码块,以免模型大声朗读这些内容。请改为在SpeechMetadata.style中传递简明样式说明。将多说话人脚本拆分为单独的
TextPart回合:将"Joe: ... \n Jane: ..."文本块替换为TextPart对象数组/列表,其中每个回合都设置SpeechMetadata.speaker。将
[...]标记转换为<...>标记:将方括号音频标记(例如[whispers]、[sighs]、[laughs])替换为尖括号人声标记(例如<whispers>、<sigh>、<laugh>、<short pause>)。更新一元音频播放:由于
generateContent现在会返回完整的 WAV 文件(带有 44 字节的 RIFF 标头),而不是无标头的原始 PCM,因此请移除所有手动将 WAV 标头附加到一元响应的代码(或者,如果将原始 PCM 样本馈送到 Android 的AudioTrack或 Unity 的AudioClip等低级缓冲区 API,请跳过 44 字节的标头)。移除不受支持的配置参数:从 TTS
GenerativeModel配置中移除temperature、topP、topK、candidateCount、presencePenalty、frequencyPenalty和systemInstruction。
您还可以做些什么?
-
开始考虑为正式发布做准备(请参阅正式发布核对清单):
- 尽早强制执行 Firebase App Check,以帮助保护 Gemini API 免遭未经授权的客户端滥用。
- 使用 Firebase Remote Config 或服务器提示模板,以便您可以按需更改 AI 功能的配置(例如模型名称),而无需发布应用的新版本。
试用其他功能
- 构建多轮对话(聊天)。
- 根据纯文本提示生成文本。
- 根据文本和多模态提示词生成结构化输出(例如 JSON)。
- 根据文本和多模态提示词生成和编辑图片。
- 使用 Gemini Live API 流式传输输入和输出(包括音频)。
-
使用工具(例如函数调用以及通过
Google Search 或Google Maps 进行接地)将 Gemini 模型连接到应用的其他部分以及外部系统和信息。