Gemini API สามารถเปลี่ยนข้อความที่ป้อนให้เป็นเสียงของผู้พูดคนเดียวหรือหลายคนได้โดยใช้ความสามารถในการสร้างการอ่านออกเสียงข้อความ (TTS) ของ Gemini
การอ่านออกเสียงข้อความควบคุมได้ ซึ่งหมายความว่าคุณสามารถรวมข้อมูลเมตาของเทิร์นที่มีโครงสร้าง (speech_metadata) และแท็กเสียงร้องในบรรทัดเพื่อกำหนดรูปแบบ สำเนียง จังหวะ และโทนเสียงของเสียงได้
ความสามารถ TTS แตกต่างจากการสร้างเสียงพูดที่ให้บริการผ่าน Live API ซึ่งออกแบบมาสำหรับเสียงแบบอินเทอร์แอกทีฟที่ไม่มีโครงสร้าง รวมถึงอินพุตและเอาต์พุตแบบหลายรูปแบบ แม้ว่า Live API จะโดดเด่นในบริบทการสนทนาแบบไดนามิก แต่ TTS ผ่าน Gemini API ได้รับการปรับแต่งมาสำหรับสถานการณ์ที่ต้องมีการอ่านข้อความที่ถูกต้องพร้อมการควบคุมสไตล์และเสียงอย่างละเอียด เช่น การสร้างพอดแคสต์หรือหนังสือเสียง
คู่มือนี้จะแสดงวิธีสร้างเสียงแบบผู้พูดคนเดียวและผู้พูดหลายคนจากข้อความโดยใช้ Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) และ Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts)
ก่อนเริ่มต้น
ตรวจสอบว่าคุณใช้โมเดล TTS ของ Gemini ที่ระบุไว้ในส่วนโมเดลที่รองรับ
และอัปเกรดเป็น Google GenAI SDK เวอร์ชันล่าสุด (google-genai >= 2.25.0 สำหรับ Python
หรือ @google/genai >= 2.24.0 สำหรับ JavaScript/TypeScript) หรือใช้ REST API
เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด โปรดดูหัวข้อควรใช้โมเดลใดเมื่อใดเพื่อเลือกโมเดลที่เหมาะกับภาระงานของคุณมากที่สุด
คุณอาจพบว่าการทดสอบโมเดล TTS ของ Gemini ใน AI Studio มีประโยชน์ก่อนที่จะเริ่มสร้าง
TTS แบบผู้พูดคนเดียว
หากต้องการแปลงข้อความเป็นเสียงแบบลำโพงเดียวด้วยโมเดล TTS ของ Gemini 3.8 ให้ส่ง
ข้อความถอดเสียงตามคำพูดใน input แนบการจัดรูปแบบระดับการพูดโดยใช้คำอธิบายประกอบ speech_metadata
และกำหนดค่าเสียงใน generation_config.speech_config
คุณสามารถเลือกเสียงจากตัวเลือกเสียงที่สร้างไว้ล่วงหน้า, คลังเสียงเพิ่มเติม (GET /v1beta/voices), รหัสการออกแบบเสียงที่กำหนดเอง (voice_...) หรือรหัสการจำลองเสียง (voice_... หรือ voicekey_... แบบไม่เก็บสถานะที่ไม่บังคับ)
ตัวอย่างนี้จะบันทึกเสียงเอาต์พุต WAV เริ่มต้น (audio/wav) จากโมเดลลงในไฟล์โดยตรง
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
}
}' | jq -r '[.steps[] | select(.type=="model_output") | .content[] | select(.type=="audio")] | last | .data' | base64 --decode > out.wav
ใน SDK ของ Python และ JavaScript คุณสามารถดึงข้อมูลเสียงที่สร้างขึ้นได้โดย
ใช้interaction.output_audioพร็อพเพอร์ตี้อำนวยความสะดวก ซึ่งจะแสดง
บล็อกเสียงที่สร้างล่าสุด (ในการตอบกลับ REST JSON แบบดิบ ระบบจะจัดเก็บเสียงที่เข้ารหัส Base64
ไว้ใน steps[].content[].data) ดูรายละเอียดเกี่ยวกับพร็อพเพอร์ตี้อำนวยความสะดวกได้ที่
ภาพรวมของการโต้ตอบ
TTS แบบผู้พูดหลายคน
สำหรับบทพูดที่มีผู้พูดหลายคน ให้กำหนดค่าผู้พูด 2 คนใน speech_config.speakers
และส่งแต่ละเทิร์นเป็นรายการข้อความแยกกันพร้อมคำอธิบายประกอบ speech_metadata
ที่ระบุ speaker และ style ระดับเทิร์น (ไม่บังคับ) โปรดทราบว่า speech_config ยอมรับอาร์เรย์ ([{"voice": "..."}]) สำหรับการสร้างเสียงผู้พูดคนเดียวและออบเจ็กต์ ({"speakers": [...]}) สำหรับการสร้างเสียงผู้พูดหลายคน
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [
{
"type": "text",
"text": "How's it going today Jane?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Joe",
"style": "cheerful and friendly",
}],
},
{
"type": "text",
"text": "Not too bad, how about you? Ready to test these new voices?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Jane",
"style": "calm and relaxed",
}],
},
],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": {
"speakers": [
{"speaker": "Joe", "voice": "Puck"},
{"speaker": "Jane", "voice": "Kore"},
],
}
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [
{
type: 'text',
text: "How's it going today Jane?",
annotations: [{
type: 'speech_metadata',
speaker: 'Joe',
style: 'cheerful and friendly',
}],
},
{
type: 'text',
text: 'Not too bad, how about you? Ready to test these new voices?',
annotations: [{
type: 'speech_metadata',
speaker: 'Jane',
style: 'calm and relaxed',
}],
},
],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: {
speakers: [
{ speaker: 'Joe', voice: 'Puck' },
{ speaker: 'Jane', voice: 'Kore' },
],
},
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [
{
"type": "text",
"text": "How'\''s it going today Jane?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Joe",
"style": "cheerful and friendly"
}]
},
{
"type": "text",
"text": "Not too bad, how about you? Ready to test these new voices?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Jane",
"style": "calm and relaxed"
}]
}
]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": {
"mode": "conversational",
"speakers": [
{ "speaker": "Joe", "voice": "Puck" },
{ "speaker": "Jane", "voice": "Kore" }
]
}
}
}'
ควบคุมรูปแบบคำพูดด้วยข้อมูลเมตาและแท็ก
TTS ของ Gemini 3.8 จะถือว่าช่อง text เป็นข้อความถอดเสียงแบบคำต่อคำอย่างเคร่งครัด หากต้องการควบคุมการแสดงออกโดยไม่ต้องอ่านคำสั่งฉากออกเสียง ให้แบ่งคำสั่งตามขอบเขตดังนี้
- การแสดงออกที่คงที่ในระดับเทิร์น (
speech_metadata.style): ใส่อารมณ์ รูปแบบการแสดงออก ท่วงทำนอง จังหวะ และระดับเสียงที่ใช้ตลอดทั้งเทิร์นในช่องstyle(เช่น"style": "whispered urgently","style": "out of breath"หรือ"style": "warm and enthusiastic") - เหตุการณ์ ณ จุดใดจุดหนึ่ง (แท็กในบรรทัด): วางเสียงร้องที่ไม่มีคำพูดหรือหยุดชั่วคราวไว้ในข้อความถอดเสียงโดยตรงโดยใช้เครื่องหมายวงเล็บมุม (เช่น
"Wait... <short pause> did you hear that? <sigh>"หรือ"Excuse me <cough> as I was saying...")
ดูแนวทางปฏิบัติแนะนำที่ครอบคลุมได้ในคู่มือการใช้พรอมต์
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [
{
"type": "text",
"text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Dr. Anya",
"style": "whispered urgently",
}],
},
{
"type": "text",
"text": "<gasp> No way! <laugh> We've been searching for this species all season!",
"annotations": [{
"type": "speech_metadata",
"speaker": "Liam",
"style": "warm and enthusiastic",
}],
},
],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": {
"speakers": [
{"speaker": "Dr. Anya", "voice": "Kore"},
{"speaker": "Liam", "voice": "Puck"},
],
}
},
)
with open("out.wav", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [
{
type: 'text',
text: 'Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?',
annotations: [{
type: 'speech_metadata',
speaker: 'Dr. Anya',
style: 'whispered urgently',
}],
},
{
type: 'text',
text: "<gasp> No way! <laugh> We've been searching for this species all season!",
annotations: [{
type: 'speech_metadata',
speaker: 'Liam',
style: 'warm and enthusiastic',
}],
},
],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: {
speakers: [
{ speaker: 'Dr. Anya', voice: 'Kore' },
{ speaker: 'Liam', voice: 'Puck' },
],
},
},
});
if (interaction.output_audio?.data) {
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.wav', audioBuffer);
}
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [
{
"type": "text",
"text": "Wait... <short pause> look under that fallen log! Is that a blue-spotted salamander?",
"annotations": [{
"type": "speech_metadata",
"speaker": "Dr. Anya",
"style": "whispered urgently"
}]
},
{
"type": "text",
"text": "<gasp> No way! <laugh> We'\''ve been searching for this species all season!",
"annotations": [{
"type": "speech_metadata",
"speaker": "Liam",
"style": "warm and enthusiastic"
}]
}
]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": {
"speakers": [
{ "speaker": "Dr. Anya", "voice": "Kore" },
{ "speaker": "Liam", "voice": "Puck" }
]
}
}
}'
การสร้างคำพูดแบบสตรีมมิง
คุณสามารถสตรีมเสียงที่สร้างขึ้นขณะที่กำลังสังเคราะห์ได้โดยตั้งค่า stream: true ต่างจากคำขอแบบยูนารี (ซึ่งแสดงผลไฟล์ WAV ที่สมบูรณ์พร้อมส่วนหัว RIFF) คำขอสตรีมมิงจะแสดงผลกลุ่ม PCM เชิงเส้นแบบ Little-Endian แบบมีเครื่องหมาย 16 บิตดิบที่ไม่มีส่วนหัว (audio/l16, 24 kHz, โมโน) โดยค่าเริ่มต้น เพื่อให้สามารถเล่นหรือเชื่อมโยงกลุ่มเสียงได้อย่างต่อเนื่องโดยไม่ต้องมีส่วนหัวของคอนเทนเนอร์
Python
import base64
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={"type": "audio"},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
stream=True,
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "audio":
audio_data = base64.b64decode(event.delta.data)
# Process the audio chunk (e.g. play it or write to a file)
JavaScript
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: { type: 'audio' },
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
stream: true,
});
for await (const event of stream) {
if (event.event_type === 'step.delta') {
if (event.delta.type === 'audio') {
const audioBuffer = Buffer.from(event.delta.data, 'base64');
// Process the audio buffer
}
}
}
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
--no-buffer \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio"
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
},
"stream": true
}'
รูปแบบเอาต์พุตเสียง
โมเดล TTS ของ Gemini 3.8 ใช้รูปแบบเสียงเริ่มต้นที่แตกต่างกัน โดยขึ้นอยู่กับว่าคำขอเป็นแบบ Unary หรือสตรีมมิง
- คำขอแบบ Unary (
stream=False): แสดงผลเสียง WAV (audio/wav) ที่สมบูรณ์พร้อมส่วนหัว RIFF มาตรฐาน (24 kHz, โมโน, 16 บิตแบบ Signed Little-Endian PCM) คุณสามารถบันทึกไบต์เสียงที่ถอดรหัสแล้วลงในไฟล์.wavได้โดยตรงโดยไม่ต้อง เพิ่มส่วนหัว WAV ด้วยตนเอง - คำขอสตรีมมิง (
stream=True): แสดงผลกลุ่ม Linear PCM ดิบแบบไม่มีส่วนหัว (audio/l16) (24 kHz, โมโน, PCM แบบ Little-Endian ที่มีเครื่องหมาย 16 บิต) โดยค่าเริ่มต้นเพื่อให้สามารถสตรีมหรือเชื่อมโยงกลุ่มได้อย่างต่อเนื่องโดยไม่มีส่วนหัวของคอนเทนเนอร์ในแต่ละกลุ่ม
หากต้องการขอการเข้ารหัสเสียงหรืออัตราการสุ่มตัวอย่างอื่น ให้กำหนดค่า mime_type และ sample_rate (ไม่บังคับ) ภายใน response_format ดังนี้
| รูปแบบ | ค่า mime_type |
คำอธิบาย |
|---|---|---|
| WAV (ค่าเริ่มต้นแบบ Unary) | "audio/wav" |
ไฟล์ WAV ที่ไม่ได้บีบอัดซึ่งมีส่วนหัว RIFF (PCM แบบ little-endian ที่มีเครื่องหมาย 16 บิต, โมโน, 24 kHz โดยค่าเริ่มต้น) ค่าเริ่มต้นสำหรับคำขอแบบ Unary |
| Raw PCM (L16) (ค่าเริ่มต้นของสตรีมมิง) | "audio/l16" |
เสียง PCM เชิงเส้นแบบ Little-Endian แบบมีเครื่องหมาย 16 บิตที่ไม่มีส่วนหัวและไม่มีการบีบอัด (24 kHz, โมโน) ค่าเริ่มต้นสำหรับคำขอสตรีมมิง |
| Mu-law | "audio/mulaw" |
เสียงที่เข้ารหัส G.711 mu-law แบบ 8 บิต (ใช้กันโดยทั่วไปในระบบโทรศัพท์/IVR ของอเมริกาเหนือและญี่ปุ่น) |
| A-law | "audio/alaw" |
เสียงที่เข้ารหัส G.711 A-law แบบ 8 บิต (มักใช้ในระบบโทรศัพท์ของยุโรปและระบบโทรศัพท์ระหว่างประเทศ) |
คุณยังระบุ sample_rate ในหน่วยเฮิรตซ์ได้ด้วย (เช่น 24000, 16000 หรือ 8000)
Python
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash-tts",
input=[{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly",
}],
}],
}],
response_format={
"type": "audio",
"mime_type": "audio/l16", # "audio/wav" (default), "audio/l16", "audio/mulaw", or "audio/alaw"
"sample_rate": 24000,
},
generation_config={
"speech_config": [
{"voice": "Kore"},
]
},
)
with open("out.pcm", "wb") as f:
f.write(base64.b64decode(interaction.output_audio.data))
JavaScript
import * as fs from 'node:fs';
import {GoogleGenAI} from '@google/genai';
async function main() {
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash-tts',
input: [{
type: 'user_input',
content: [{
type: 'text',
text: 'Have a wonderful day!',
annotations: [{
type: 'speech_metadata',
style: 'cheerful and friendly',
}],
}],
}],
response_format: {
type: 'audio',
mime_type: 'audio/l16', // 'audio/wav' (default), 'audio/l16', 'audio/mulaw', or 'audio/alaw'
sample_rate: 24000,
},
generation_config: {
speech_config: [
{ voice: 'Kore' },
],
},
});
const audioBuffer = Buffer.from(interaction.output_audio.data, 'base64');
fs.writeFileSync('out.pcm', audioBuffer);
}
await main();
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"input": [{
"type": "user_input",
"content": [{
"type": "text",
"text": "Have a wonderful day!",
"annotations": [{
"type": "speech_metadata",
"style": "cheerful and friendly"
}]
}]
}],
"response_format": {
"type": "audio",
"mime_type": "audio/l16",
"sample_rate": 24000
},
"generation_config": {
"speech_config": [
{ "voice": "Kore" }
]
}
}'
ตัวเลือกเสียง
TTS ของ Gemini 3.8 รองรับการเลือกหรือสร้างเสียง 4 วิธีดังนี้
- เสียงของ Studio ที่สร้างไว้ล่วงหน้า: เสียงที่คัดสรรแล้ว 30 เสียงซึ่งแสดงอยู่ในตารางต่อไปนี้
- คลังเสียงเพิ่มเติม: เสียงเพิ่มเติมหลายร้อยเสียงในภาษา สำเนียง และต้นแบบตัวละครต่างๆ ที่เข้าถึงได้โดยใช้
client.voices.list()(GET /v1beta/voices) - การออกแบบเสียง: สร้างตัวตนเสียงที่กำหนดเองจากคำอธิบายภาษาธรรมชาติใน Google AI Studio หรือใช้
POST /v1beta/voices(type="prompted"ซึ่งจะแสดงผลรหัสvoice_...แบบถาวรและตัวอย่างไฟล์ WAVsample_audioในCreateVoiceและGetVoice) - การจำลองเสียง: จำลองเสียงของผู้พูดจากเสียงอ้างอิงและเสียงที่ได้รับความยินยอมใน Google AI Studio หรือใช้
POST /v1beta/voices(type="replicated",store=Trueแบบถาวรโดยค่าเริ่มต้น หรือstore=Falseแบบไม่เก็บสถานะ (Stateless) ที่ไม่บังคับ)
ขีดจำกัดของเสียงที่กำหนดเองและ TTL
| พิมพ์ด้วยเสียง | โหมดจัดเก็บ | โควต้า / ขีดจำกัด | การเก็บรักษา (TTL) |
|---|---|---|---|
เสียงที่มีสถานะ (voice_..., พรอมต์หรือจำลอง) |
store=True |
200 เสียงต่อโปรเจ็กต์ (ใช้ร่วมกันระหว่างเสียงที่สร้างจากพรอมต์และเสียงที่จำลอง) | 1 ปีนับจากวันที่ใช้งานครั้งล่าสุด* |
คีย์เสียงแบบไม่เก็บสถานะ (voicekey_..., ทำซ้ำ) |
store=False |
จัดการโดยลูกค้า | 7 วัน |
* การขยาย TTL: หน้าต่างการเก็บรักษา 1 ปีจะรีเซ็ตทุกครั้งที่มีการใช้เสียงอย่างต่อเนื่อง (ไม่ว่าจะโดยการสังเคราะห์เสียงพูดด้วยเสียงนั้นหรือใช้เป็นเสียงฐานสำหรับการรีมิกซ์) ระบบจะลบเสียงที่ไม่มีกิจกรรมเป็นเวลา 1 ปีโดยอัตโนมัติ
เสียงที่สร้างไว้ล่วงหน้า
| Zephyr -- Bright | Puck -- สนุกสนาน | Charon -- มีสาระประโยชน์ |
| Kore -- Firm | Fenrir -- ตื่นเต้นง่าย | Leda -- วัยรุ่น |
| Orus -- บริษัท | Aoede -- Breezy | Callirrhoe -- สบายๆ |
| Autonoe -- สว่าง | Enceladus -- Breathy | Iapetus -- สีใส |
| Umbriel -- สบายๆ | Algieba -- ราบรื่น | Despina -- ราบรื่น |
| Erinome -- ชัดเจน | Algenib -- Gravelly | Rasalgethi -- มีสาระประโยชน์ |
| Laomedeia -- Upbeat | Achernar -- นุ่มนวล | Alnilam -- Firm |
| Schedar -- Even | Gacrux -- ผู้ใหญ่ | Pulcherrima -- มั่นใจ |
| Achird -- เป็นมิตร | Zubenelgenubi - สบายๆ | Vindemiatrix -- อ่อนโยน |
| Sadachbia -- มีชีวิตชีวา | Sadaltager -- มีความรู้ | Sulafat -- อบอุ่น |
คลังเสียงและการกรองที่ครอบคลุมมากขึ้น
นอกเหนือจากเสียงในสตูดิโอที่แนะนำ 30 เสียงในตารางก่อนหน้า คลังเสียงเพิ่มเติมยังมีเสียงอื่นๆ อีกหลายร้อยเสียงในภาษาต่างๆ สำเนียงตามภูมิภาค บุคลิกของตัวละคร และโดเมน คุณสามารถเรียกดู กรอง และ
ทดลองใช้คลังเสียงทั้งหมดแบบอินเทอร์แอกทีฟใน Google AI Studio หรือค้นหาแบบเป็นโปรแกรมโดยใช้ client.voices.list() (GET /v1beta/voices โดยใช้
google-genai 2.25.0 ขึ้นไป / @google/genai 2.24.0 ขึ้นไป)
ListVoices จะแสดงเสียงที่จัดเก็บไว้แบบกำหนดเอง (เรียงลำดับจากใหม่ที่สุดก่อน) ตามด้วยเสียงในแคตตาล็อกที่สร้างไว้ล่วงหน้าซึ่งตรงกับเกณฑ์ตัวกรองของคุณ เมื่อมีการส่งค่าหลายค่าสำหรับตัวกรองรายการ ระบบจะแสดงผลเสียงที่ตรงกับค่าใดก็ได้ในตัวกรองนั้น (OR) ขณะที่พารามิเตอร์ตัวกรองที่แตกต่างกันจะรวมกับ AND:
| พารามิเตอร์ | ประเภท | คำอธิบาย |
|---|---|---|
language_code |
list[str] |
แท็กภาษา BCP-47 (เช่น ["en-US", "en-GB"]) การทำงานแบบตรงทั้งหมดโดยไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ |
region_code |
list[str] |
รหัสภูมิภาค ISO 3166-1 alpha-2 หรือ UN M.49 (เช่น ["US", "GB"]) |
accent |
list[str] |
ข้อบ่งชี้สำเนียงระดับภูมิภาค (เช่น ["American", "British"]) |
gender |
list[str] |
การแสดงออกทางเพศที่รับรู้ ("female", "male" หรือ "neutral") |
pitch |
list[str] |
การจัดประเภทระดับเสียงร้อง ("low", "medium" หรือ "high") |
persona |
list[str] |
บุคลิกหรือต้นแบบตัวละครที่มีเสียงร้อง (เช่น ["Warm, Friendly"], ["Narrator"]) |
contexts (context ใน REST) |
list[str] |
โดเมนการใช้งานที่เหมาะสม (เช่น ["Audiobook", "Conversational", "News"]) |
type (type_ ใน Python) |
list[str] |
กรองตามแหล่งที่มาของเสียง: "prebuilt", "prompted" (การออกแบบเสียง) หรือ "replicated" (การจำลองเสียง) |
search |
str |
การค้นหาสตริงย่อยแบบข้อความอิสระที่ตรงกันโดยไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่กับทั้ง display_name และ description |
page_size |
int |
จำนวนเสียงสูงสุดที่แสดงต่อหน้า (ค่าเริ่มต้น 50, สูงสุด 1000) |
page_token |
str |
โทเค็นจาก response.next_page_token เพื่อดึงข้อมูลผลการค้นหาหน้าถัดไป |
Python
from google import genai
client = genai.Client()
# Filter the Voice Library by language, gender, pitch, domain context, and keyword
response = client.voices.list(
language_code=["en-US", "en-GB"],
gender=["female"],
pitch=["medium", "low"],
contexts=["Audiobook", "Conversational"],
type_=["prebuilt"],
search="warm",
page_size=50,
)
for voice in response.voices or []:
print(
f"{voice.id} | {voice.display_name} ({voice.language_code},"
f" {voice.accent}, {voice.gender}, pitch={voice.pitch}):"
f" {voice.description}"
)
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI();
// Filter the Voice Library by language, gender, pitch, domain context, and keyword
const response = await ai.voices.list({
language_code: ["en-US", "en-GB"],
gender: ["female"],
pitch: ["medium", "low"],
contexts: ["Audiobook", "Conversational"],
type: ["prebuilt"],
search: "warm",
page_size: 50,
});
for (const voice of response.voices ?? []) {
console.log(
`${voice.id} | ${voice.display_name} (${voice.language_code}, ${voice.accent}, ${voice.gender}, pitch=${voice.pitch}): ${voice.description}`
);
}
REST
curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
--data-urlencode "language_code=en-US" \
--data-urlencode "language_code=en-GB" \
--data-urlencode "gender=female" \
--data-urlencode "pitch=medium" \
--data-urlencode "context=Audiobook" \
--data-urlencode "type=prebuilt" \
--data-urlencode "search=warm" \
--data-urlencode "page_size=50"
ภาษาที่รองรับ
โมเดล TTS จะตรวจหาภาษาที่ป้อนโดยอัตโนมัติ
Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) รองรับมากกว่า 130 ภาษา และ Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts) รองรับมากกว่า 100 ภาษา ดังนี้
| ภาษา | Gemini 3.8 Flash TTS | Gemini 3.8 Flash-Lite TTS |
|---|---|---|
| อาเจะฮ์ (อักษรอาหรับ) | ✔️ | ✔️ |
| อาฟรีกานส์ | ✔️ | ✔️ |
| อะคัน | ✔️ | ✔️ |
| อัมฮาริก | ✔️ | ✔️ |
| อาร์เมเนีย | ✔️ | ✔️ |
| อัสสัม | ✔️ | ✔️ |
| อวธี | ✔️ | ✔️ |
| บาหลี | ✔️ | ✔️ |
| เบงกอล | ✔️ | ✔️ |
| บันจาร์ (อักษรอาหรับ) | ✔️ | — |
| บันจาร์ (สคริปต์ละติน) | ✔️ | ✔️ |
| แบชเคียร์ | ✔️ | — |
| บาสก์ | ✔️ | ✔️ |
| Belarusian | ✔️ | ✔️ |
| เบมบา | ✔️ | — |
| โภชปุระ | ✔️ | ✔️ |
| บอสเนีย | ✔️ | ✔️ |
| บูกิส | ✔️ | ✔️ |
| บัลแกเรีย | ✔️ | ✔️ |
| พม่า | ✔️ | — |
| จีนกวางตุ้ง | ✔️ | ✔️ |
| คาตาลัน | ✔️ | ✔️ |
| ซีบัวโน | ✔️ | ✔️ |
| เคิร์ดตอนกลาง | ✔️ | ✔️ |
| ฉัตติสครห์ | ✔️ | ✔️ |
| จีน (อักษรฮั่น) | ✔️ | ✔️ |
| จีน (อักษร Hant) | ✔️ | ✔️ |
| ตาตาร์ไครเมีย | ✔️ | — |
| โครเอเชีย | ✔️ | ✔️ |
| เช็ก | ✔️ | ✔️ |
| เดนมาร์ก | ✔️ | ✔️ |
| ดัตช์ | ✔️ | ✔️ |
| ดิวลา | ✔️ | — |
| ซองคา | ✔️ | — |
| อาหรับอียิปต์ | ✔️ | ✔️ |
| อังกฤษ | ✔️ | ✔️ |
| เอสโตเนีย | ✔️ | ✔️ |
| ฟิลิปปินส์ | ✔️ | ✔️ |
| ฟินแลนด์ | ✔️ | — |
| ฝรั่งเศส | ✔️ | ✔️ |
| กาลิเชียน | ✔️ | ✔️ |
| กันดา | ✔️ | ✔️ |
| จอร์เจีย | ✔️ | ✔️ |
| เยอรมัน | ✔️ | ✔️ |
| กรีก | ✔️ | ✔️ |
| กวารานี | ✔️ | — |
| คุชราต | ✔️ | ✔️ |
| เฮติครีโอล | ✔️ | ✔️ |
| มองโกเลียคาลคา | ✔️ | ✔️ |
| เฮาซา | ✔️ | ✔️ |
| ฮีบรู | ✔️ | ✔️ |
| ฮินดี | ✔️ | ✔️ |
| ฮังการี | ✔️ | ✔️ |
| ไอซ์แลนด์ | ✔️ | ✔️ |
| อิกโบ | ✔️ | — |
| อีโลโก | ✔️ | ✔️ |
| อินโดนีเซีย | ✔️ | ✔️ |
| เปอร์เซีย (อิหร่าน) | ✔️ | ✔️ |
| อิตาลี | ✔️ | ✔️ |
| ญี่ปุ่น | ✔️ | ✔️ |
| ชวา | ✔️ | ✔️ |
| คาไบล์ | ✔️ | — |
| คัมบา | ✔️ | ✔️ |
| กันนาดา | ✔️ | ✔️ |
| แคชเมียร์ (อักษรอาหรับ) | ✔️ | ✔️ |
| แคชเมียร์ (สคริปต์เทวา) | ✔️ | ✔️ |
| คาซัค | ✔️ | ✔️ |
| เขมร | ✔️ | ✔️ |
| คิคูยู | ✔️ | ✔️ |
| คินยารวันดา | ✔️ | ✔️ |
| คองโก | ✔️ | ✔️ |
| เกาหลี | ✔️ | ✔️ |
| คีร์กิซ | ✔️ | ✔️ |
| ภาษาลาว | ✔️ | ✔️ |
| ลัตกาเรียน | ✔️ | — |
| ลิงกาลา | ✔️ | ✔️ |
| ลิทัวเนีย | ✔️ | — |
| ลักเซมเบิร์ก | ✔️ | — |
| มาซีโดเนีย | ✔️ | ✔️ |
| มคธี | ✔️ | ✔️ |
| ไมถิลี | ✔️ | ✔️ |
| มาลายาลัม | ✔️ | ✔️ |
| มอลตา | ✔️ | ✔️ |
| มานิพูรี | ✔️ | ✔️ |
| มราฐี | ✔️ | ✔️ |
| มินังกาเบา (อักษรอาหรับ) | ✔️ | ✔️ |
| มินังกาเบา (สคริปต์ละติน) | ✔️ | — |
| มิโซ | ✔️ | ✔️ |
| เนปาล (ภาษาเดี่ยว) | ✔️ | ✔️ |
| ฟุลฟุลเดไนจีเรีย | ✔️ | ✔️ |
| อาเซอร์ไบจานเหนือ | ✔️ | ✔️ |
| โซโทเหนือ | ✔️ | ✔️ |
| อุซเบกเหนือ | ✔️ | ✔️ |
| นอร์เวย์บุคมอล | ✔️ | ✔️ |
| นีนอสก์ของนอร์เวย์ | ✔️ | ✔️ |
| เนียนจา | ✔️ | ✔️ |
| ออกซิแทน | ✔️ | — |
| โอเดีย (ภาษาเดี่ยว) | ✔️ | ✔️ |
| ปังกาซินัน | ✔️ | — |
| เปอร์เซีย (อัฟกานิสถาน) | ✔️ | ✔️ |
| โปแลนด์ | ✔️ | ✔️ |
| โปรตุเกส | ✔️ | ✔️ |
| ปัญจาบ | ✔️ | ✔️ |
| โรมาเนีย | ✔️ | ✔️ |
| รัสเซีย | ✔️ | ✔️ |
| สันถาลี | ✔️ | ✔️ |
| เซอร์เบีย | ✔️ | ✔️ |
| สินธี | ✔️ | — |
| สิงหล | ✔️ | ✔️ |
| สโลวัก | ✔️ | ✔️ |
| สโลวีเนีย | ✔️ | — |
| โซมาลี | ✔️ | — |
| อาเซอร์ไบจานใต้ | ✔️ | ✔️ |
| ภาษาปาทานใต้ | ✔️ | ✔️ |
| โซโทใต้ | ✔️ | — |
| สเปน | ✔️ | ✔️ |
| อาหรับมาตรฐาน (อักษรอาหรับ) | ✔️ | ✔️ |
| อาหรับมาตรฐาน (สคริปต์ Latn) | ✔️ | ✔️ |
| ลัตเวียมาตรฐาน | ✔️ | ✔️ |
| ภาษามลายูมาตรฐาน | ✔️ | ✔️ |
| สวาฮีลี (ภาษาเดี่ยว) | ✔️ | — |
| สวาติ | ✔️ | — |
| สวีเดน | ✔️ | — |
| ทาจิก | ✔️ | — |
| ทมิฬ | ✔️ | ✔️ |
| เตลูกู | ✔️ | ✔️ |
| ไทย | ✔️ | — |
| ทิกรินยา | ✔️ | — |
| แอลบาเนียนแบบทอสก์ | ✔️ | — |
| ตุรกี | ✔️ | ✔️ |
| อุยกูร์ | ✔️ | — |
| เวียดนาม | ✔️ | ✔️ |
โมเดลที่รองรับ
| รุ่น | ผู้พูดคนเดียว | ผู้พูดหลายคน | การออกแบบเสียง | การจำลองเสียง |
|---|---|---|---|---|
Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) |
✔️ | ✔️ | ✔️ | ✔️ |
TTS ของ Gemini 3.8 Flash-Lite (gemini-3.8-flash-lite-tts) |
✔️ | ✔️ | ✔️ | ✔️ |
| ตัวอย่าง TTS ของ Gemini 3.1 Flash | ✔️ | ✔️ | — | — |
| TTS เวอร์ชันตัวอย่างของ Gemini 2.5 Pro | ✔️ | ✔️ | — | — |
ควรใช้โมเดลใดเมื่อใด
โมเดล TTS ของ Gemini 3.8 ทั้ง 2 โมเดลใช้สคีมา API และรูปแบบพรอมต์เดียวกันทุกประการ ซึ่งช่วยให้คุณสลับไปมาระหว่างโมเดลได้ด้วยการเปลี่ยนพารามิเตอร์เพียงรายการเดียว ดังนี้
- ใช้ Gemini 3.8 Flash TTS
(
gemini-3.8-flash-tts) เมื่อความเที่ยงตรงของเสียงสูงสุด การแสดงที่ละเอียดอ่อน และการควบคุมการแสดงออกเป็นสิ่งสำคัญที่สุด เหมาะสำหรับงานสร้างสรรค์ระดับสตูดิโอ บทสนทนาที่มีผู้พูดหลายคนและซับซ้อน แท็กเสียงร้องที่หนักหน่วง การออกเสียงที่ยาก ภาษาถิ่นหรือภาษาของชนกลุ่มน้อย และการบรรยายแบบยาวที่ต้องการเสียงที่หนักแน่นและความเสถียรของเสียงในห้อง - ใช้ TTS ของ Gemini 3.8 Flash-Lite
(
gemini-3.8-flash-lite-tts) เป็นเครื่องมือที่รวดเร็วและคุ้มค่า แทนgemini-3.1-flash-tts-previewโดยได้รับการเพิ่มประสิทธิภาพสำหรับ การผลิตจำนวนมาก การส่งต่อตัวแทนเสียงสนทนา ฟีเจอร์อ่านออกเสียง การจำลองเสียงที่เชื่อถือได้ และเสียงพูดแบบลำโพงเดี่ยวในชีวิตประจำวัน ในภาษาหลักๆ
คำแนะนำในการย้ายข้อมูล
หากคุณย้ายข้อมูลจากโมเดล TTS ของ Gemini gemini-3.1-flash-tts-preview หรือรุ่นก่อนหน้าไปยัง TTS ของ Gemini 3.8 ให้ทำดังนี้
- ย้ายคำสั่งระดับเลี้ยวไปยัง
speech_metadata: TTS ของ Gemini 3.8 จะถือว่า ข้อความที่ป้อนเป็นสำเนาที่ตรงตามต้นฉบับอย่างเคร่งครัด ย้ายวิธีการแสดงที่ต่อเนื่อง (styleเช่น"whispering","out of breath"หรือ"speaking slowly") และป้ายกำกับผู้พูด (speaker) ไปไว้ในคำอธิบายประกอบspeech_metadataที่มีโครงสร้าง แทนที่จะฝังวิธีการแสดงไว้ในข้อความถอดเสียง - ใช้แท็กในบรรทัดที่มีวงเล็บมุมสำหรับเหตุการณ์เสียงพูด ณ จุดใดจุดหนึ่งเท่านั้น: เก็บเสียงพูดที่ไม่ใช่คำพูดและหยุดชั่วคราวไว้ในบรรทัดในข้อความถอดเสียงโดยใช้วงเล็บมุม (เช่น
<laugh>,<sigh>,<cough>,<breath>หรือ<short pause>) หลีกเลี่ยงแท็กเอฟเฟกต์เสียง (เช่น เสียงปรบมือหรือเสียงตุบ) และใส่รูปแบบการนำส่งในspeech_metadata.style - ระบุ
speakerในทุกๆ เทิร์นในคำขอแบบหลายผู้พูด: ทุกๆ เทิร์นในคำขอแบบหลายผู้พูดต้องมีspeakerอยู่ภายในspeech_metadataที่ตรงกับผู้พูดที่กำหนดค่าไว้ - ออกแบบลักษณะตัวตนล่วงหน้าด้วยการออกแบบเสียง: แทนที่บล็อกหลายย่อหน้า
"Audio Profile"หรือ"Director's Notes"ด้วยเสียงที่กำหนดเองซึ่งสร้างขึ้น ในการออกแบบเสียง จากนั้นส่งvoice_...รหัสนั้นผ่านคำขอ TTS โดยมีสตริงstyleที่ว่างเปล่าหรือมีข้อมูลน้อยที่สุด - พิจารณาเอาต์พุต WAV (
audio/wav) เริ่มต้นในคำขอแบบเอกภาค: โมเดล TTS ของ Gemini 3.8 จะแสดงผลเสียง WAV (audio/wav) พร้อมส่วนหัว RIFF มาตรฐานโดยค่าเริ่มต้นสำหรับคำขอแบบเอกภาค ซึ่งแตกต่างจากโมเดล TTS ของgemini-3.1-flash-tts-previewและรุ่นก่อนหน้า (ซึ่งแสดงผล PCM ดิบแบบไม่มีส่วนหัวaudio/l16โดยค่าเริ่มต้น)- หากก่อนหน้านี้โค้ดของคุณรวมไบต์ PCM ดิบไว้ในส่วนหัว WAV (เช่น ใช้โมดูล
waveของ Python หรือffmpeg) ให้นำ Wrapper ส่วนหัวที่สร้างด้วยตนเองออก แล้วเขียนไบต์ที่แสดงผลลงในไฟล์.wavโดยตรง - หากไปป์ไลน์ของคุณต้องใช้เสียง PCM, mu-law หรือ A-law แบบดิบที่ไม่มีส่วนหัว ให้ตั้งค่า
response_format.mime_typeเป็น"audio/l16","audio/mulaw"หรือ"audio/alaw"อย่างชัดเจน (เช่น{"response_format": {"type": "audio", "mime_type": "audio/l16"}}ใน Interactions API หรือAUDIO_L16ในgenerateContent) ดูรูปแบบเอาต์พุตเสียง
- หากก่อนหน้านี้โค้ดของคุณรวมไบต์ PCM ดิบไว้ในส่วนหัว WAV (เช่น ใช้โมดูล
คู่มือการเขียนพรอมต์
โมเดล TTS ของ Gemini 3.8 จะถือว่าข้อความอินพุตเป็นข้อความถอดเสียงตามคำพูดอย่างเคร่งครัด
TTS ของ Gemini 3.8 แตกต่างจากโมเดลเวอร์ชันตัวอย่างก่อนหน้านี้ที่ฝังคำสั่งบนเวทีไว้ในข้อความธรรมดา
โดยจะแยกคำสั่งระดับการพูดที่ต่อเนื่อง (speech_metadata)
ออกจากแท็กเสียงในบรรทัด ณ จุดใดจุดหนึ่ง
ฟิลด์รูปแบบเทียบกับแท็กในบรรทัด
แยกคำสั่งประสิทธิภาพตามขอบเขต
- การแสดงอารมณ์ระดับเทิร์น (
speech_metadata.style): ใส่แอตทริบิวต์การแสดงอารมณ์ที่ต่อเนื่อง เช่น อารมณ์ ฉันทลักษณ์ ความเร็วโดยรวม หรือสไตล์การแสดงอารมณ์ (เช่น"whispering","out of breath","muttering"หรือ"sarcastic") ลงในช่องstyleของspeech_metadataหากต้องการสร้างตัวละครและ การแสดงที่สม่ำเสมอตลอดการสนทนา ให้ออกแบบบุคลิกภาพล่วงหน้าในการออกแบบเสียง และใช้styleเฉพาะสำหรับการปรับแต่งระดับเทิร์นที่ไม่บังคับ - เหตุการณ์ที่เกิดขึ้น ณ จุดใดจุดหนึ่ง (แท็กในบรรทัด): ใส่เสียงที่ไม่ใช่คำพูดชั่วขณะ เสียงหายใจ หรือการหยุดชั่วคราวในบรรทัดภายในข้อความถอดเสียงโดยใช้วงเล็บมุม (
<cough>,<breath>,<sigh>,<short pause>) ใช้วงเล็บมุม (<...>) เพื่อคุณภาพเสียงสูงสุด และใช้การเปล่งเสียงของมนุษย์แทนเอฟเฟกต์เสียงที่ไม่ใช่เสียงพูด
| ขอบเขต | ตำแหน่งที่ควรวาง | ตัวอย่าง |
|---|---|---|
| ระดับการเลี้ยว (คงที่ตลอดการเลี้ยว) | speech_metadata.style |
"angry tone" "speaking rapidly" "out of breath" "whispers" "sarcastic" |
| ช่วงเวลา (เกิดขึ้นที่คำที่เฉพาะเจาะจง) | แทรกในบรรทัดใน text (<...>) |
"<cough> Thank you all for coming tonight! <throat-clearing> As I was saying..." |
จังหวะและการหยุดชั่วคราว
คุณควบคุมจังหวะและความเงียบได้ 3 ระดับ ดังนี้
- เครื่องหมายวรรคตอนและจุดไข่ปลา: ใช้คอมมา ขีดกลาง (
--) และจุดไข่ปลา (...) เพื่อแสดงความลังเลในการสนทนาอย่างเป็นธรรมชาติ - แท็กหยุดชั่วคราวในบรรทัด: แทรก
<short pause>หรือ<long pause>ในจุดที่แน่นอนในสคริปต์ที่ผู้พูดควรหยุดชั่วคราวtext Hold on, let me think... <short pause> Alright, I've got it. - อัตราการพูดระดับคำ: ตั้งค่า
"style": "speaking rapidly"หรือ"style": "speaking slowly"ในspeech_metadataเพื่อควบคุมอัตราการพูด ตลอดทั้งคำ
ทำนองและระดับเสียง
ใช้ speech_metadata.style เพื่อควบคุมฉันทลักษณ์ ระดับเสียง และการผันเสียงตลอดเทิร์น (เช่น "style": "high pitch, cheerful and excited inflection" หรือ "style": "monotone and flat") หากอารมณ์หรือฉันทลักษณ์เปลี่ยนไปในระหว่างการสนทนา ให้แบ่งสคริปต์ออกเป็นเทิร์นแยกกันโดยมีค่า style ที่แตกต่างกันสำหรับแต่ละเทิร์น
การเน้น
ใช้อักษรตัวพิมพ์ใหญ่กับคำที่เฉพาะเจาะจงในข้อความถอดเสียง ร่วมกับเครื่องหมายวรรคตอนและแท็กเสียงในบรรทัด เพื่อเน้นเสียงอย่างเป็นธรรมชาติในคำสำคัญ ดังนี้
This is a VERY important point!
It was a VERY long day <sigh> ... nobody listens anymore.
เสียงร้องและเสียงที่ไม่ใช่เสียงพูด
ใส่เสียงร้องที่ไม่ใช่คำพูดของมนุษย์ในบรรทัดโดยใช้วงเล็บมุม (<...>) ณ จุดที่ควรมีเสียงนั้น แท็กเสียงร้องที่แนะนำมีดังนี้
<argh> |
<breath> |
<heavy breath> |
<exhales> |
<cackle> |
<cheer> |
<chuckle> / <chuckles> |
<cough> |
<cry> |
<gasp> |
<giggle> |
<groan> |
<growl> |
<grunt> |
<grr> |
<hiss> |
<laugh> / <laughter> |
<moan> |
<pant> |
<pff> / <phew> |
<scream> |
<shout> |
<shriek> |
<sigh> / <sighs> |
<sneeze> |
<snicker> |
<snort> |
<sob> |
<throat-clearing> |
<tsk> |
<whimper> |
<whispers> / <whispering> |
<yawn> |
<short pause> |
<long pause> |
การตอบรับระหว่างการสนทนาและเสียงพูดทับซ้อนกัน
ในการสนทนาที่มีผู้พูดหลายคน ให้รวมปฏิกิริยาของผู้ฟังไว้ในอักขระไปป์ (|reaction|) ภายในเทิร์นของผู้พูดเพื่อสร้างการตอบสนองแบบเป็นธรรมชาติหรือการพูดทับกันโดยไม่แบ่งเป็นเทิร์นแยกต่างหากสำหรับแต่ละปฏิกิริยา
- การแลกเปลี่ยนข้อความสั้นๆ ในช่องสื่อสารเบื้องหลัง: แทรกรีแอ็กชันสั้นๆ ของ Listener (
|oh hmm|,|oh really?|,|absolutely|) ในช่วงที่ผู้ที่กำลังพูดกำลังพูดอยู่- เทิร์นที่ 1 (ผู้พูด A):
"So the launch is Thursday |oh hmm| Are we actually ready?" - เทิร์นที่ 2 (ผู้พูด ข):
"Ready enough |oh really?| The last blocker cleared this morning." - เทิร์นที่ 3 (ผู้พูด A):
"Then let's ship it |absolutely| and watch the dashboards."
- เทิร์นที่ 1 (ผู้พูด A):
- คำพูดที่ทับซ้อนกันและสลับกัน: ใช้ส่วนไปป์หลายส่วนเพื่อจำลองคำพูดที่เกิดขึ้นพร้อมกันหรือสลับกันระหว่างผู้พูด 2 คน (ทำงานได้ดีที่สุดกับ
gemini-3.8-flash-tts)- การนับถอยหลัง/การร้องประสานเสียงพร้อมกัน:
"Let's surprise him on three |ok| ready?"ตามด้วย"one. two. three. |happy| happy |birthday| birthday!" - ผู้พูดทับซ้อนกันทั้งหมด:
"Hello |oh| there |my| it |goodness| must |gracious| be |would| almost |you| time |look| for |at that| dinner"
- การนับถอยหลัง/การร้องประสานเสียงพร้อมกัน:
ความสอดคล้องกันในทุกรุ่นและสิ่งที่ควรหลีกเลี่ยง
ทำตามหลักเกณฑ์ต่อไปนี้เพื่อให้เอกลักษณ์ของเสียงมีความสม่ำเสมอในแต่ละเทิร์น
- ออกแบบตัวตนล่วงหน้าในการออกแบบเสียงแทนที่จะใช้บล็อกสไตล์ยาวๆ:
ย่อหน้า
"Audio Profile"แบบยาวและหัวข้อย่อยหลายรายการ"Director's Notes"ที่ยกมาจากโมเดลก่อนหน้าเป็นสาเหตุที่พบบ่อยที่สุดของการเบี่ยงเบนของเสียง ใช้สัญชาตญาณด้านครีเอทีฟโฆษณาเดียวกันนั้นตั้งแต่ต้นในการออกแบบเสียงเพื่อสร้างvoice_...ลักษณะตัวละครที่กำหนดเองแบบถาวร จากนั้นใช้รหัสเสียงนั้นผ่านการเรียก TTS - ใช้เสียงอ้างอิงเพื่อความเสถียร (ละเว้นคำสั่งเมตา):
โมเดล TTS ของ Gemini 3.8 ได้รับการฝึกให้ยึดตามเสียงอ้างอิงเป็นอันดับแรก
อย่าใส่คำสั่งที่บอกให้โมเดลคงเสียงให้สม่ำเสมอ (เช่น
"do not switch speaker identity"หรือ"maintain identical timbre") เนื่องจากข้อความพรอมต์ที่มากเกินไปจะเพิ่มความคลาดเคลื่อน ละเว้นคำสั่งสไตล์ที่ไม่จำเป็นและปล่อยให้โมเดล เปลี่ยนแปลงไปตามธรรมชาติรอบจุดที่เสถียรซึ่งอ้างอิงจากเสียง - อย่าพยายามเปลี่ยนลักษณะของผู้พูดที่ไม่สามารถเปลี่ยนแปลงได้ใน
style: หลีกเลี่ยงการใส่อายุ เพศ ชื่อ หรือการเปลี่ยนสำเนียงถาวรในspeech_metadata.styleแต่ให้เลือกเสียงในภูมิภาคจากคลังเสียงเพิ่มเติมหรือสร้างเสียงด้วยการออกแบบเสียงแทน
เวิร์กโฟลว์ที่แนะนำ
- สร้างตัวละครครั้งเดียว: สร้างตัวละครในการออกแบบเสียงหรือเลือกเสียงตามภูมิภาคจากคลังเสียงเพิ่มเติมที่ตรงกับภาษาเป้าหมายและตัวละครของคุณ
- เขียนข้อความถอดเสียงที่พูดอย่างเป็นธรรมชาติโดยมีคำพูดติดขัด: เพื่อให้เป็นธรรมชาติมากที่สุด ให้เขียน
textเป็นข้อความถอดเสียงที่พูดจริง ซึ่งรวมถึงคำพูดติดขัดและการลังเลในการสนทนาที่เป็นธรรมชาติ (เช่น"Oh uh yeah I think... hm, so that's interesting") - ทดสอบ TTS แบบธรรมดาก่อน: สังเคราะห์ข้อความถอดเสียงด้วยช่อง
styleที่ว่างเปล่าก่อน คำขอส่วนใหญ่ไม่จำเป็นต้องมีคำสั่งstyleเลย - เพิ่มพรอมต์
styleสั้นๆ สำหรับการปรับแต่งเท่านั้น: เพิ่มสตริงstyleที่กระชับ (เช่น"casual, friendly"หรือ"muttering, then reassuring") สำหรับเทิร์นที่ต้องการการปรับแต่งการนำส่งที่เฉพาะเจาะจงเท่านั้น และใช้สตริงสั้นๆ เดียวกันนั้นซ้ำในเทิร์นต่างๆ เมื่อต้องการให้มีพื้นฐานที่สอดคล้องกัน
การสนทนาหลายรอบและเอเจนต์เสียง
เมื่อสร้าง Agent เสียงแบบสนทนาเรียลไทม์หรือแอปพลิเคชันแบบสนทนาไปมา ให้ทำดังนี้
- โทรหา TTS 1 ครั้งต่อเทิร์นเมื่อข้อความ LLM มาถึง
- ให้
voiceที่กำหนดค่าไว้ (สร้างไว้ล่วงหน้า ออกแบบvoice_...หรือจำลองvoice_.../voicekey_...) แสดงตัวตนของผู้พูดในแต่ละเทิร์น โดยไม่ต้องส่งตัวละครที่มีลักษณะยาวซ้ำในแต่ละเทิร์น - ปล่อยช่อง
styleต่อเทิร์นว่างไว้ หรือส่งสตริงคงที่สั้นๆ 1 รายการ (เช่น"casual, friendly") สำหรับการสนทนาทั้งหมด - แบ่งคำตอบที่ยาวของ Agent ออกเป็นเทิร์นสั้นๆ แทนที่จะใช้พรอมต์สไตล์ที่เข้มงวดขึ้น
ข้อจำกัด
- โมเดล TTS รับอินพุตที่เป็นข้อความเท่านั้นและสร้างเอาต์พุตที่เป็นเสียงเท่านั้น
- การสร้างเสียงผู้พูดหลายคนในคำขอเดียว (
speech_config.speakers) รองรับผู้พูดสูงสุด 2 คนโดยใช้เสียงที่สร้างไว้ล่วงหน้า หากต้องการรวมเสียงที่ออกแบบเอง (voice_...) หรือเสียงที่จำลอง (voice_.../voicekey_...) ในบทสนทนาที่มีตัวละครหลายตัว ให้สังเคราะห์เสียงของแต่ละคนแยกกัน เนื่องจากคำขอแบบ Unary จะแสดงผลaudio/wavพร้อมส่วนหัว RIFF ขนาด 44 ไบต์โดยค่าเริ่มต้น ให้ขอ PCM ดิบ ({"type": "audio", "mime_type": "audio/l16"}) หรือตัดส่วนหัว WAV ออกจากแต่ละเทิร์นก่อนที่จะเชื่อมโยงเฟรมเสียง PCM ขนาด 24kHz - ขีดจำกัดพื้นที่เก็บข้อมูลเสียงที่กำหนดเองและ TTL:
- เสียงแบบเก็บสถานะ (
store=True, พรอมต์หรือจำลอง): สูงสุด 200 เสียงต่อโปรเจ็กต์ โดยมี TTL 1 ปี (Time to Live) - คีย์เสียงแบบไม่เก็บสถานะ (
store=False,voicekey_...): TTL 7 วัน (Time to Live)
- เสียงแบบเก็บสถานะ (
- ดูความครอบคลุมของภาษาในส่วนภาษาที่รองรับ
ขั้นตอนถัดไป
- สร้างตัวตนของเสียงที่กำหนดเองจากภาษาธรรมชาติด้วยการออกแบบเสียง
- จำลองเสียงของผู้พูดที่มีอยู่โดยใช้การจำลองเสียง
- เปรียบเทียบข้อกำหนดของโมเดลในหน้าโมเดล Gemini 3.8 Flash TTS และ Gemini 3.8 Flash-Lite TTS
- สำรวจเสียงแบบ 2 ทิศทางที่โต้ตอบได้ด้วย Live API