การสร้างการอ่านออกเสียงข้อความ (TTS)

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 วิธีดังนี้

  1. เสียงของ Studio ที่สร้างไว้ล่วงหน้า: เสียงที่คัดสรรแล้ว 30 เสียงซึ่งแสดงอยู่ในตารางต่อไปนี้
  2. คลังเสียงเพิ่มเติม: เสียงเพิ่มเติมหลายร้อยเสียงในภาษา สำเนียง และต้นแบบตัวละครต่างๆ ที่เข้าถึงได้โดยใช้ client.voices.list() (GET /v1beta/voices)
  3. การออกแบบเสียง: สร้างตัวตนเสียงที่กำหนดเองจากคำอธิบายภาษาธรรมชาติใน Google AI Studio หรือใช้ POST /v1beta/voices (type="prompted" ซึ่งจะแสดงผลรหัส voice_... แบบถาวรและตัวอย่างไฟล์ WAV sample_audio ใน CreateVoice และ GetVoice)
  4. การจำลองเสียง: จำลองเสียงของผู้พูดจากเสียงอ้างอิงและเสียงที่ได้รับความยินยอมใน 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 ให้ทำดังนี้

  1. ย้ายคำสั่งระดับเลี้ยวไปยัง speech_metadata: TTS ของ Gemini 3.8 จะถือว่า ข้อความที่ป้อนเป็นสำเนาที่ตรงตามต้นฉบับอย่างเคร่งครัด ย้ายวิธีการแสดงที่ต่อเนื่อง (style เช่น "whispering", "out of breath" หรือ "speaking slowly") และป้ายกำกับผู้พูด (speaker) ไปไว้ในคำอธิบายประกอบ speech_metadata ที่มีโครงสร้าง แทนที่จะฝังวิธีการแสดงไว้ในข้อความถอดเสียง
  2. ใช้แท็กในบรรทัดที่มีวงเล็บมุมสำหรับเหตุการณ์เสียงพูด ณ จุดใดจุดหนึ่งเท่านั้น: เก็บเสียงพูดที่ไม่ใช่คำพูดและหยุดชั่วคราวไว้ในบรรทัดในข้อความถอดเสียงโดยใช้วงเล็บมุม (เช่น <laugh>, <sigh>, <cough>, <breath> หรือ <short pause>) หลีกเลี่ยงแท็กเอฟเฟกต์เสียง (เช่น เสียงปรบมือหรือเสียงตุบ) และใส่รูปแบบการนำส่งใน speech_metadata.style
  3. ระบุ speaker ในทุกๆ เทิร์นในคำขอแบบหลายผู้พูด: ทุกๆ เทิร์นในคำขอแบบหลายผู้พูดต้องมี speaker อยู่ภายใน speech_metadata ที่ตรงกับผู้พูดที่กำหนดค่าไว้
  4. ออกแบบลักษณะตัวตนล่วงหน้าด้วยการออกแบบเสียง: แทนที่บล็อกหลายย่อหน้า "Audio Profile" หรือ "Director's Notes" ด้วยเสียงที่กำหนดเองซึ่งสร้างขึ้น ในการออกแบบเสียง จากนั้นส่ง voice_... รหัสนั้นผ่านคำขอ TTS โดยมีสตริง style ที่ว่างเปล่าหรือมีข้อมูลน้อยที่สุด
  5. พิจารณาเอาต์พุต 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) ดูรูปแบบเอาต์พุตเสียง

คู่มือการเขียนพรอมต์

โมเดล 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."
  • คำพูดที่ทับซ้อนกันและสลับกัน: ใช้ส่วนไปป์หลายส่วนเพื่อจำลองคำพูดที่เกิดขึ้นพร้อมกันหรือสลับกันระหว่างผู้พูด 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 แต่ให้เลือกเสียงในภูมิภาคจากคลังเสียงเพิ่มเติมหรือสร้างเสียงด้วยการออกแบบเสียงแทน
  1. สร้างตัวละครครั้งเดียว: สร้างตัวละครในการออกแบบเสียงหรือเลือกเสียงตามภูมิภาคจากคลังเสียงเพิ่มเติมที่ตรงกับภาษาเป้าหมายและตัวละครของคุณ
  2. เขียนข้อความถอดเสียงที่พูดอย่างเป็นธรรมชาติโดยมีคำพูดติดขัด: เพื่อให้เป็นธรรมชาติมากที่สุด ให้เขียน text เป็นข้อความถอดเสียงที่พูดจริง ซึ่งรวมถึงคำพูดติดขัดและการลังเลในการสนทนาที่เป็นธรรมชาติ (เช่น "Oh uh yeah I think... hm, so that's interesting")
  3. ทดสอบ TTS แบบธรรมดาก่อน: สังเคราะห์ข้อความถอดเสียงด้วยช่อง style ที่ว่างเปล่าก่อน คำขอส่วนใหญ่ไม่จำเป็นต้องมีคำสั่ง style เลย
  4. เพิ่มพรอมต์ 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)
  • ดูความครอบคลุมของภาษาในส่วนภาษาที่รองรับ

ขั้นตอนถัดไป