تولید متن به گفتار (TTS)

API Gemini می‌تواند ورودی متن را با استفاده از قابلیت‌های تولید متن به گفتار (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 ) از متن، صدای تک‌بلندگو و چندبلندگو تولید کنید.

قبل از اینکه شروع کنی

مطمئن شوید که از مدل Gemini TTS که در بخش مدل‌های پشتیبانی‌شده ذکر شده است، استفاده می‌کنید. برای نتایج بهینه، بررسی کنید که چه زمانی از کدام مدل استفاده کنید تا بهترین مدل را برای حجم کاری خود انتخاب کنید.

ممکن است قبل از شروع ساخت، آزمایش مدل‌های Gemini TTS در AI Studio مفید باشد.

TTS تک بلندگو

برای تبدیل متن به صدای تک‌گوینده با مدل‌های Gemini 3.8 TTS، متن کلمه به کلمه را در input وارد کنید، با استفاده از حاشیه‌نویسی speech_metadata ، استایل‌بندی نوبتی را پیوست کنید و صدای خود را در generation_config.speech_config پیکربندی کنید. می‌توانید صدایی را از گزینه‌های صدای از پیش ساخته شده، کتابخانه صدای توسعه یافته ( GET /v1beta/voices )، یک شناسه طراحی صدای سفارشی ( voice_... ) یا یک شناسه تکثیر صدا ( voice_... ) یا voicekey_... بدون وضعیت اختیاری انتخاب کنید.

این مثال، صدای خروجی پیش‌فرض WAV ( audio/wav ) را از مدل مستقیماً در یک فایل ذخیره می‌کند:

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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 های پایتون و جاوا اسکریپت، می‌توانید داده‌های صوتی تولید شده را با استفاده از ویژگی راحتی interaction.output_audio بازیابی کنید، که آخرین بلوک صوتی تولید شده را برمی‌گرداند (در پاسخ‌های خام REST JSON، صدای کدگذاری شده با base64 در steps[].content[].data ذخیره می‌شود). برای جزئیات بیشتر در مورد ویژگی‌های راحتی، به مرور کلی Interactions مراجعه کنید.

TTS چند بلندگو

برای گفتگوی چند گوینده، دو گوینده را در speech_config.speakers پیکربندی کنید و هر نوبت را به عنوان یک آیتم متنی جداگانه با حاشیه‌نویسی speech_metadata که speaker و style سطح نوبت اختیاری را مشخص می‌کند، ارسال کنید. برای آهنگ طبیعی نوبت‌گیری از "mode": "conversational" استفاده کنید:

پایتون

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": {
            "mode": "conversational",
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

جاوا اسکریپت

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: {
            mode: 'conversational',
            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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    prompt := "TTS the following conversation between Joe and Jane:\n" +
        "Joe: How's it going today Jane?\n" +
        "Jane: Not too bad, how about you?"

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Joe"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Jane"), Voice: genai.Ptr("Puck")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(prompt),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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" }
        ]
      }
    }
  }'

کنترل سبک گفتار با ابرداده و برچسب‌ها

Gemini 3.8 TTS با فیلد 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..." ).

برای بهترین شیوه‌های جامع، به راهنمای Prompting مراجعه کنید.

برو

package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    transcriptRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput(
                "Generate a short transcript around 100 words that reads " +
                    "like it was clipped from a podcast by excited herpetologists. " +
                    "The hosts names are Dr. Anya and Liam.",
            ),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    var transcript string
    if transcriptRes.Interaction.OutputText != nil {
        transcript = *transcriptRes.Interaction.OutputText
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Dr. Anya"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Liam"), Voice: genai.Ptr("Puck")},
        })),
    }

    ttsRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(transcript),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = ttsRes
}

تولید گفتار استریمینگ

شما می‌توانید با تنظیم stream: true ، صدای تولید شده را همزمان با سنتز شدن، پخش کنید. برخلاف درخواست‌های unary (که یک فایل WAV کامل با هدر RIFF برمی‌گردانند)، درخواست‌های پخش به طور پیش‌فرض تکه‌های PCM خطی 16 بیتی علامت‌دار little-endian ( audio/l16 ، 24 کیلوهرتز، مونو) خام بدون هدر را برمی‌گردانند، بنابراین تکه‌های صدا می‌توانند بدون هدرهای کانتینر به طور مداوم پخش یا به هم متصل شوند.

پایتون

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)

جاوا اسکریپت

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();

استراحت

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
  }'

فرمت‌های خروجی صدا

مدل‌های Gemini 3.8 TTS بسته به اینکه درخواست تکی یا استریم باشد، از فرمت‌های صوتی پیش‌فرض متفاوتی استفاده می‌کنند:

  • درخواست‌های تک‌فایلی ( stream=False ): صدای کامل WAV ( audio/wav ) را با یک هدر استاندارد RIFF (24 کیلوهرتز، مونو، PCM با علامت ۱۶ بیتی little-endian) برمی‌گرداند. می‌توانید بایت‌های صدای رمزگشایی شده را مستقیماً در یک فایل .wav ذخیره کنید، بدون اینکه به صورت دستی هدر WAV را به ابتدای آن اضافه کنید.
  • درخواست‌های پخش ( stream=True ): به طور پیش‌فرض تکه‌های خام PCM خطی ( audio/l16 ) بدون سربرگ (24 کیلوهرتز، مونو، PCM لیتل-اندیان علامت‌دار 16 بیتی) را برمی‌گرداند تا تکه‌ها بتوانند به طور مداوم و بدون سربرگ‌های کانتینر روی هر تکه، پخش یا به هم متصل شوند.

برای درخواست کدگذاری صوتی یا نرخ نمونه‌برداری متفاوت، mime_type و sample_rate اختیاری را درون response_format پیکربندی کنید:

قالب مقدار mime_type توضیحات
WAV (پیش‌فرض تک‌فایلی) "audio/wav" فایل WAV غیرفشرده با هدر RIFF (PCM 16 بیتی علامت‌دار little-endian، مونو، پیش‌فرض ۲۴ کیلوهرتز). پیش‌فرض برای درخواست‌های unary.
PCM خام (L16) (پیش‌فرض پخش) "audio/l16" صدای PCM خطی ۱۶ بیتی علامت‌دار little-endian بدون فشرده‌سازی و بدون هدر (۲۴ کیلوهرتز، مونو). پیش‌فرض برای درخواست‌های پخش.
مو-لا "audio/mulaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 mu-law (که معمولاً در سیستم‌های تلفن/IVR آمریکای شمالی و ژاپن استفاده می‌شود).
الف-قانون "audio/alaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 A-law (که معمولاً در سیستم‌های تلفنی اروپایی و بین‌المللی استفاده می‌شود).

همچنین می‌توانید sample_rate بر حسب هرتز (مثلاً 24000 ، 16000 یا 8000 ) مشخص کنید.

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
            Stream:           genai.Ptr(true),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    stream := res.InteractionSSEStreamEvent
    defer stream.Close()

    for stream.Next() {
        event := stream.Value()
        if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
            if audioDelta := stepDelta.GetDeltaAudio(); audioDelta != nil && audioDelta.Data != nil {
                audioData, err := base64.StdEncoding.DecodeString(*audioDelta.Data)
                if err != nil {
                    log.Fatal(err)
                }
                // Process the audio chunk (e.g. play it or write to a file)
                _ = audioData
            }
        }
    }
    if err := stream.Err(); err != nil {
        log.Fatal(err)
    }
}

استراحت

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" }
      ]
    }
  }'

گزینه‌های صوتی

Gemini 3.8 TTS از چهار روش برای انتخاب یا ایجاد صداها پشتیبانی می‌کند:

  1. صداهای استودیویی از پیش ساخته شده: 30 صدای منتخب که در جدول زیر فهرست شده‌اند.
  2. کتابخانه صوتی توسعه‌یافته: صدها صدای اضافی در زبان‌ها، لهجه‌ها و الگوهای کاراکتر مختلف که با استفاده از client.voices.list() ( GET /v1beta/voices ) قابل دسترسی هستند.
  3. طراحی صدا : یک شخصیت صوتی سفارشی از توضیحات زبان طبیعی در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="prompted" که یک شناسه voice_... دائمی و یک پیش‌نمایش sample_audio WAV در CreateVoice و GetVoice برمی‌گرداند) ایجاد کنید.
  4. تکرار صدا : صدای گوینده را از صدای مرجع و صدای تایید شده در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="replicated" ، مقدار ثابت store=True به طور پیش‌فرض یا مقدار اختیاری stateless store=False ) کپی کنید.

محدودیت‌های صوتی سفارشی و TTL

نوع صدا حالت ذخیره سازی سهمیه / محدودیت میزان ماندگاری (TTL)
صداهای حالت‌دار ( voice_... ، برانگیخته شده یا تکرار شده) store=True ۲۰۰ صدا در هر پروژه (به اشتراک گذاشته شده در میان صداهای پیشنهادی و تکراری) ۱ سال
کلیدهای صوتی بدون وضعیت ( voicekey_... ، تکثیر شده) store=False مدیریت‌شده توسط مشتری ۷ روز

صداهای از پیش ساخته شده

زفیر -- روشن پک -- خوش‌بین شارون -- آموزنده
کره -- شرکت فنریر -- هیجان‌انگیز لدا -- جوان
اوروس -- شرکت آئوده -- نسیم ملایم کالیرو -- آسان‌گیر
اتونو -- روشن انسلادوس -- نفس‌گیر یاپتوس -- شفاف
آمبریل -- آسان‌گیر آلگیبا -- صاف دسپینا -- صاف
ارینوم -- پاک آلگنیب -- شنی رسالگتی -- آموزنده
لائومدیا -- خوش‌بین آخنار -- نرم آلنیلام -- شرکت
شِدار -- حتی گاکروکس -- بالغ پولچریما -- مهاجم
آچیرد -- دوستانه Zubenelgenubi -- غیررسمی ویندمیاتریکس -- ملایم
ساداچیبیا -- سرزنده سدالتاگر - آگاه سولفات -- گرم

کتابخانه صوتی توسعه‌یافته و فیلترینگ

فراتر از 30 صدای استودیویی برجسته در جدول قبلی، کتابخانه صدای توسعه‌یافته صدها صدای اضافی را در زبان‌ها، لهجه‌های منطقه‌ای، شخصیت‌های شخصیتی و دامنه‌ها ارائه می‌دهد. می‌توانید کل کتابخانه صدا را به صورت تعاملی در Google AI Studio مرور، فیلتر و تست کنید، یا با استفاده از client.voices.list() ( GET /v1beta/voices , using 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_ در پایتون) list[str] فیلتر بر اساس منبع صدا: "prebuilt" ، "prompted" ( طراحی صدا ) یا "replicated" ( تکثیر صدا ).
search str جستجوی زیررشته متن آزاد، بدون حساسیت به حروف بزرگ و کوچک، هم با display_name و هم description مطابقت داشت.
page_size int حداکثر تعداد صداهای برگردانده شده در هر صفحه (پیش‌فرض 50 ، حداکثر 1000 ).
page_token str توکن از response.next_page_token برای دریافت صفحه بعدی نتایج.

پایتون

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}"
    )

جاوا اسکریپت

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}`
  );
}

استراحت

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 ) از بیش از ۱۳۰ زبان و Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) از بیش از ۱۰۰ زبان پشتیبانی می‌کنند:

زبان جمینی ۳.۸ فلش TTS جمینی ۳.۸ فلش-لایت TTS
آچه‌ای (خط عربی) ✔️ ✔️
آفریکانس ✔️ ✔️
آکان ✔️ ✔️
امهری ✔️ ✔️
ارمنی ✔️ ✔️
آسامی ✔️ ✔️
عوضی ✔️ ✔️
بالیایی ✔️ ✔️
بنگلا ✔️ ✔️
بنجار (خط عربی) ✔️ —
بنجار (خط لاتین) ✔️ ✔️
باشقیر ✔️ —
باسک ✔️ ✔️
بلاروسی ✔️ ✔️
بمبا ✔️ —
بوجپوری ✔️ ✔️
بوسنیایی ✔️ ✔️
بوگینی ✔️ ✔️
بلغاری ✔️ ✔️
برمه‌ای ✔️ —
کانتونی ✔️ ✔️
کاتالان ✔️ ✔️
سبوانو ✔️ ✔️
کردی مرکزی ✔️ ✔️
چتیسگری ✔️ ✔️
چینی (خط هانس) ✔️ ✔️
چینی (خط هانت) ✔️ ✔️
تاتاری کریمه ✔️ —
کرواتی ✔️ ✔️
چک ✔️ ✔️
دانمارکی ✔️ ✔️
هلندی ✔️ ✔️
دیولا ✔️ —
دزونگخا ✔️ —
عربی مصری ✔️ ✔️
انگلیسی ✔️ ✔️
استونیایی ✔️ ✔️
فیلیپینی ✔️ ✔️
فنلاندی ✔️ —
فرانسوی ✔️ ✔️
گالیسیایی ✔️ ✔️
گاندا ✔️ ✔️
گرجی ✔️ ✔️
آلمانی ✔️ ✔️
یونانی ✔️ ✔️
گوارانی ✔️ —
گجراتی ✔️ ✔️
کریول هائیتیایی ✔️ ✔️
هاله مغولی ✔️ ✔️
هوسا ✔️ ✔️
عبری ✔️ ✔️
هندی ✔️ ✔️
مجارستانی ✔️ ✔️
ایسلندی ✔️ ✔️
ایگبو ✔️ —
ایلوکو ✔️ ✔️
اندونزیایی ✔️ ✔️
فارسی ایرانی ✔️ ✔️
ایتالیایی ✔️ ✔️
ژاپنی ✔️ ✔️
جاوه ای ✔️ ✔️
کابل ✔️ —
کامبا ✔️ ✔️
کانارا ✔️ ✔️
کشمیری (خط عربی) ✔️ ✔️
کشمیری (خط دیوه) ✔️ ✔️
قزاق ✔️ ✔️
خمر ✔️ ✔️
کیکویو ✔️ ✔️
کینیارواندایی ✔️ ✔️
کنگو ✔️ ✔️
کره ای ✔️ ✔️
قرقیز ✔️ ✔️
لائو ✔️ ✔️
لاتگالیایی ✔️ —
لینگالا ✔️ ✔️
لیتوانیایی ✔️ —
لوکزامبورگی ✔️ —
مقدونی ✔️ ✔️
ماگای ✔️ ✔️
میثیلی ✔️ ✔️
مالایالامی ✔️ ✔️
مالتی ✔️ ✔️
مانیپوری ✔️ ✔️
مراتی ✔️ ✔️
مینانگکابائو (خط عربی) ✔️ ✔️
مینانگکابائو (خط لاتین) ✔️ —
میزو ✔️ ✔️
نپالی (زبان شخصی) ✔️ ✔️
فولفولد نیجریه‌ای ✔️ ✔️
آذربایجان شمالی ✔️ ✔️
سوتوی شمالی ✔️ ✔️
ازبکی شمالی ✔️ ✔️
بوکمال نروژی ✔️ ✔️
نروژی نینورسک ✔️ ✔️
نیانیا ✔️ ✔️
اکسیتان ✔️ —
اودیا (زبان شخصی) ✔️ ✔️
پانگاسینان ✔️ —
فارسی (افغانستان) ✔️ ✔️
لهستانی ✔️ ✔️
پرتغالی ✔️ ✔️
پنجابی ✔️ ✔️
رومانیایی ✔️ ✔️
روسی ✔️ ✔️
سانتالی ✔️ ✔️
صربی ✔️ ✔️
سندی ✔️ —
سینهالی ✔️ ✔️
اسلواکی ✔️ ✔️
اسلوونیایی ✔️ —
سومالیایی ✔️ —
آذربایجان جنوبی ✔️ ✔️
پشتو جنوبی ✔️ ✔️
سوتوی جنوبی ✔️ —
اسپانیایی ✔️ ✔️
عربی استاندارد (خط عربی) ✔️ ✔️
عربی استاندارد (خط لاتین) ✔️ ✔️
استاندارد لتونی ✔️ ✔️
مالایی استاندارد ✔️ ✔️
سواحیلی (زبان شخصی) ✔️ —
سواتی ✔️ —
سوئدی ✔️ —
تاجیک ✔️ —
تامیل ✔️ ✔️
تلوگو ✔️ ✔️
تایلندی ✔️ —
تیگرینیا ✔️ —
آلبانیایی توسک ✔️ —
ترکی ✔️ ✔️
اویغوری ✔️ —
ویتنامی ✔️ ✔️

مدل‌های پشتیبانی‌شده

مدل تک بلندگو چند بلندگو طراحی صدا تکرار صدا
جمینی ۳.۸ فلش TTS ( gemini-3.8-flash-tts ) ✔️ ✔️ ✔️ ✔️
جمینی ۳.۸ فلش-لایت TTS ( gemini-3.8-flash-lite-tts ) ✔️ ✔️ ✔️ ✔️
پیش‌نمایش TTS فلش جمینی ۳.۱ ✔️ ✔️ — —
پیش‌نمایش Gemini 2.5 Pro TTS ✔️ ✔️ — —

چه زمانی از کدام مدل استفاده کنیم

هر دو مدل Gemini 3.8 TTS دقیقاً طرحواره API و قالب اعلان یکسانی را به اشتراک می‌گذارند و به شما امکان می‌دهند با یک تغییر پارامتر، بین آنها جابجا شوید:

  • وقتی حداکثر دقت آکوستیک، اجرای دقیق و کنترل بیان در اولویت هستند، از Gemini 3.8 Flash TTS ( gemini-3.8-flash-tts ) استفاده کنید . این محصول برای کارهای خلاقانه در سطح استودیویی، دیالوگ‌های پیچیده بین چند گوینده، صداهای پشت سر هم سنگین، تلفظ‌های دشوار، گویش‌های منطقه‌ای یا اقلیتی و روایت‌های طولانی که نیاز به صدای بسیار قوی و ثبات تُن صدا در اتاق دارند، ایده‌آل است.
  • از Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) به عنوان جایگزین سریع و مقرون به صرفه‌ی gemini-3.1-flash-tts-preview استفاده کنید. این نرم‌افزار برای تولید انبوه با حجم بالا، آبشارهای عامل صوتی مکالمه‌ای، ویژگی‌های خواندن با صدای بلند، تکثیر صدای قابل اعتماد و گفتار تک‌گوینده‌ی روزمره در زبان‌های اصلی بهینه شده است.

راهنمای مهاجرت

اگر از gemini-3.1-flash-tts-preview یا مدل‌های قدیمی‌تر Gemini TTS به Gemini 3.8 TTS مهاجرت می‌کنید:

  1. انتقال دستورالعمل‌های سطح نوبت به speech_metadata : Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرد. دستورالعمل‌های تحویل 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 ) در درخواست‌های unary: برخلاف gemini-3.1-flash-tts-preview و مدل‌های TTS قبلی (که به‌طور پیش‌فرض PCM audio/l16 خام بدون سربرگ را برمی‌گرداندند)، Gemini 3.8 TTS به‌طور پیش‌فرض برای درخواست‌های unary، صدای WAV ( audio/wav ) را با یک سربرگ استاندارد RIFF برمی‌گرداند.
    • اگر کد شما قبلاً بایت‌های خام PCM را در یک هدر WAV قرار داده است (برای مثال، با استفاده از ماژول wave پایتون یا ffmpeg )، پوشش هدر دستی را حذف کرده و بایت‌های برگردانده شده را مستقیماً در یک فایل .wav بنویسید.
    • اگر خط تولید شما به صدای خام PCM، mu-law یا A-law بدون هدر نیاز دارد، صریحاً response_format روی "audio/l16" ، "audio/mulaw" یا "audio/alaw" تنظیم کنید. به بخش فرمت‌های خروجی صدا مراجعه کنید.

راهنمای راهنمایی

مدل‌های Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرند. برخلاف مدل‌های پیش‌نمایش قبلی که دستورالعمل‌های صحنه در متن ساده جاسازی می‌شدند، Gemini 3.8 TTS دستورالعمل‌های پایدار سطح نوبت ( 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..."

سرعت و مکث

شما می‌توانید ریتم و سکوت را در سه سطح جزئیات کنترل کنید:

  • علائم نگارشی و حذف: برای مکث طبیعی در مکالمه از ویرگول، خط تیره ( -- ) و حذف ( ... ) استفاده کنید.
  • تگ‌های مکث درون‌خطی: <short pause> یا <long pause> را دقیقاً در نقاطی از فیلمنامه که گوینده باید مکث کند، قرار دهید: text Hold on, let me think... <short pause> Alright, I've got it.
  • سرعت نوبت: برای کنترل سرعت صحبت در کل نوبت، در speech_metadata گزینه "style": "speaking rapidly" یا "style": "speaking slowly" را تنظیم کنید.

عروض و آهنگ صدا

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| ) درون نوبت گوینده قرار دهید تا کانال‌های برگشتی طبیعی یا گفتار همپوشانی ایجاد شود بدون اینکه برای هر واکنش به نوبت جداگانه‌ای تقسیم شود.

  • تبادلات کوتاه پشت‌پرده: واکنش‌های کوتاه شنونده ( |oh hmm| ، |oh really?| ، |absolutely| ) را درون نوبت گوینده فعال قرار دهید:
    • نوبت اول (گوینده الف): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • نوبت دوم (گوینده ب): "Ready enough |oh really?| The last blocker cleared this morning."
    • نوبت سوم (گوینده الف): "Then let's ship it |absolutely| and watch the dashboards."
  • گفتار همپوشانی و درهم‌تنیده: از چندین بخش لوله برای شبیه‌سازی گفتار همزمان یا درهم‌تنیده بین دو گوینده استفاده کنید (با 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 خود منتقل کنید.
  • برای پایداری به مرجع صوتی تکیه کنید (فرادستورالعمل‌ها را حذف کنید): مدل‌های Gemini 3.8 TTS طوری آموزش دیده‌اند که ابتدا روی مرجع صوتی لنگر بیندازند. دستورالعمل‌هایی که به مدل می‌گویند صدا را ثابت نگه دارد (مانند "do not switch speaker identity" یا "maintain identical timbre" ) را قرار ندهید—متن اضافی باعث افزایش رانش می‌شود. دستورالعمل‌های سبک غیرضروری را حذف کنید و بگذارید مدل به طور طبیعی حول نقطه پایدار ارائه شده توسط مرجع صوتی تغییر کند.
  • سعی نکنید ویژگی‌های تغییرناپذیر گوینده را در style تغییر دهید: از قرار دادن سن، جنسیت، نام یا تغییرات لهجه دائمی در speech_metadata.style خودداری کنید. در عوض، یک صدای منطقه‌ای را از Extended Voice Library انتخاب کنید یا با Voice design یکی ایجاد کنید.
  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" ) استفاده کنید و وقتی می‌خواهید خط مبنای ثابتی داشته باشید، دقیقاً از همان رشته‌ی کوتاه در نوبت‌های مختلف استفاده کنید.

دیالوگ‌های چند نوبتی و عوامل صوتی

هنگام ساخت عامل‌های صوتی مکالمه‌ای بلادرنگ یا برنامه‌های چند نوبتی:

  • همزمان با رسیدن تکه‌های متن LLM ، در هر نوبت یک فراخوانی TTS انجام دهید.
  • اجازه دهید voice پیکربندی‌شده (صدای از پیش ساخته شده، voice_... طراحی شده، یا voice_... تکثیر شده / voicekey_... ) هویت گوینده را در طول نوبت‌ها حمل کند - هرگز یک شخصیت طولانی را در هر نوبت دوباره ارسال نکنید.
  • فیلد style هر نوبت را خالی بگذارید، یا یک رشته کوتاه و ثابت (مانند "casual, friendly" ) برای کل مکالمه ارسال کنید.
  • به جای اینکه به دنبال سبک‌های قوی‌تر باشید، پاسخ‌های طولانی اپراتور را به نوبت‌های کوتاه‌تر تقسیم کنید.

محدودیت‌ها

  • مدل‌های TTS ورودی‌های فقط متنی را می‌پذیرند و خروجی‌های فقط صوتی تولید می‌کنند.
  • تولید چند گوینده با یک درخواست ( speech_config.speakers ) حداکثر از ۲ گوینده با استفاده از صداهای از پیش ساخته شده پشتیبانی می‌کند. برای ترکیب صداهای سفارشی طراحی شده ( voice_... ) یا کپی شده ( voice_... / voicekey_... ) در گفتگوی چند کاراکتری، نوبت هر گوینده را به صورت جداگانه ترکیب کنید. از آنجا که درخواست‌های تکی به طور پیش‌فرض audio/wav را با یک هدر RIFF 44 بایتی برمی‌گردانند، قبل از اتصال فریم‌های صوتی PCM 24 کیلوهرتز، PCM خام ( {"type": "audio", "mime_type": "audio/l16"} ) را درخواست کنید یا هدر WAV را از هر نوبت جدا کنید.
  • محدودیت‌های ذخیره‌سازی صدای سفارشی و TTL:
    • صداهای دارای وضعیت ( store=True ، فراخوانی یا تکرار): حداکثر ۲۰۰ صدا در هر پروژه با TTL (زمان ماندگاری) ۱ ساله .
    • کلیدهای صوتی بدون وضعیت ( store=False ، voicekey_... ): زمان ماندگاری ۷ روزه (TTL ).
  • برای اطلاع از پوشش زبان‌ها، بخش زبان‌های پشتیبانی‌شده را مرور کنید.

قدم بعدی چیست؟

،

API Gemini می‌تواند ورودی متن را با استفاده از قابلیت‌های تولید متن به گفتار (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 ) از متن، صدای تک‌بلندگو و چندبلندگو تولید کنید.

قبل از اینکه شروع کنی

مطمئن شوید که از مدل Gemini TTS که در بخش مدل‌های پشتیبانی‌شده ذکر شده است، استفاده می‌کنید. برای نتایج بهینه، بررسی کنید که چه زمانی از کدام مدل استفاده کنید تا بهترین مدل را برای حجم کاری خود انتخاب کنید.

ممکن است قبل از شروع ساخت، آزمایش مدل‌های Gemini TTS در AI Studio مفید باشد.

TTS تک بلندگو

برای تبدیل متن به صدای تک‌گوینده با مدل‌های Gemini 3.8 TTS، متن کلمه به کلمه را در input وارد کنید، با استفاده از حاشیه‌نویسی speech_metadata ، استایل‌بندی نوبتی را پیوست کنید و صدای خود را در generation_config.speech_config پیکربندی کنید. می‌توانید صدایی را از گزینه‌های صدای از پیش ساخته شده، کتابخانه صدای توسعه یافته ( GET /v1beta/voices )، یک شناسه طراحی صدای سفارشی ( voice_... ) یا یک شناسه تکثیر صدا ( voice_... ) یا voicekey_... بدون وضعیت اختیاری انتخاب کنید.

این مثال، صدای خروجی پیش‌فرض WAV ( audio/wav ) را از مدل مستقیماً در یک فایل ذخیره می‌کند:

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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 های پایتون و جاوا اسکریپت، می‌توانید داده‌های صوتی تولید شده را با استفاده از ویژگی راحتی interaction.output_audio بازیابی کنید، که آخرین بلوک صوتی تولید شده را برمی‌گرداند (در پاسخ‌های خام REST JSON، صدای کدگذاری شده با base64 در steps[].content[].data ذخیره می‌شود). برای جزئیات بیشتر در مورد ویژگی‌های راحتی، به مرور کلی Interactions مراجعه کنید.

TTS چند بلندگو

برای گفتگوی چند گوینده، دو گوینده را در speech_config.speakers پیکربندی کنید و هر نوبت را به عنوان یک آیتم متنی جداگانه با حاشیه‌نویسی speech_metadata که speaker و style سطح نوبت اختیاری را مشخص می‌کند، ارسال کنید. برای آهنگ طبیعی نوبت‌گیری از "mode": "conversational" استفاده کنید:

پایتون

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": {
            "mode": "conversational",
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

جاوا اسکریپت

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: {
            mode: 'conversational',
            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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    prompt := "TTS the following conversation between Joe and Jane:\n" +
        "Joe: How's it going today Jane?\n" +
        "Jane: Not too bad, how about you?"

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Joe"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Jane"), Voice: genai.Ptr("Puck")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(prompt),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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" }
        ]
      }
    }
  }'

کنترل سبک گفتار با ابرداده و برچسب‌ها

Gemini 3.8 TTS با فیلد 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..." ).

برای بهترین شیوه‌های جامع، به راهنمای Prompting مراجعه کنید.

برو

package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    transcriptRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput(
                "Generate a short transcript around 100 words that reads " +
                    "like it was clipped from a podcast by excited herpetologists. " +
                    "The hosts names are Dr. Anya and Liam.",
            ),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    var transcript string
    if transcriptRes.Interaction.OutputText != nil {
        transcript = *transcriptRes.Interaction.OutputText
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Dr. Anya"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Liam"), Voice: genai.Ptr("Puck")},
        })),
    }

    ttsRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(transcript),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = ttsRes
}

تولید گفتار استریمینگ

شما می‌توانید با تنظیم stream: true ، صدای تولید شده را همزمان با سنتز شدن، پخش کنید. برخلاف درخواست‌های unary (که یک فایل WAV کامل با هدر RIFF برمی‌گردانند)، درخواست‌های پخش به طور پیش‌فرض تکه‌های PCM خطی 16 بیتی علامت‌دار little-endian ( audio/l16 ، 24 کیلوهرتز، مونو) خام بدون هدر را برمی‌گردانند، بنابراین تکه‌های صدا می‌توانند بدون هدرهای کانتینر به طور مداوم پخش یا به هم متصل شوند.

پایتون

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)

جاوا اسکریپت

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();

استراحت

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
  }'

فرمت‌های خروجی صدا

مدل‌های Gemini 3.8 TTS بسته به اینکه درخواست تکی یا استریم باشد، از فرمت‌های صوتی پیش‌فرض متفاوتی استفاده می‌کنند:

  • درخواست‌های تک‌فایلی ( stream=False ): صدای کامل WAV ( audio/wav ) را با یک هدر استاندارد RIFF (24 کیلوهرتز، مونو، PCM با علامت ۱۶ بیتی little-endian) برمی‌گرداند. می‌توانید بایت‌های صدای رمزگشایی شده را مستقیماً در یک فایل .wav ذخیره کنید، بدون اینکه به صورت دستی هدر WAV را به ابتدای آن اضافه کنید.
  • درخواست‌های پخش ( stream=True ): به طور پیش‌فرض تکه‌های خام PCM خطی ( audio/l16 ) بدون سربرگ (24 کیلوهرتز، مونو، PCM لیتل-اندیان علامت‌دار 16 بیتی) را برمی‌گرداند تا تکه‌ها بتوانند به طور مداوم و بدون سربرگ‌های کانتینر روی هر تکه، پخش یا به هم متصل شوند.

برای درخواست کدگذاری صوتی یا نرخ نمونه‌برداری متفاوت، mime_type و sample_rate اختیاری را درون response_format پیکربندی کنید:

قالب مقدار mime_type توضیحات
WAV (پیش‌فرض تک‌فایلی) "audio/wav" فایل WAV غیرفشرده با هدر RIFF (PCM 16 بیتی علامت‌دار little-endian، مونو، پیش‌فرض ۲۴ کیلوهرتز). پیش‌فرض برای درخواست‌های unary.
PCM خام (L16) (پیش‌فرض پخش) "audio/l16" صدای PCM خطی ۱۶ بیتی علامت‌دار little-endian بدون فشرده‌سازی و بدون هدر (۲۴ کیلوهرتز، مونو). پیش‌فرض برای درخواست‌های پخش.
مو-لا "audio/mulaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 mu-law (که معمولاً در سیستم‌های تلفن/IVR آمریکای شمالی و ژاپن استفاده می‌شود).
الف-قانون "audio/alaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 A-law (که معمولاً در سیستم‌های تلفنی اروپایی و بین‌المللی استفاده می‌شود).

همچنین می‌توانید sample_rate بر حسب هرتز (مثلاً 24000 ، 16000 یا 8000 ) مشخص کنید.

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
            Stream:           genai.Ptr(true),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    stream := res.InteractionSSEStreamEvent
    defer stream.Close()

    for stream.Next() {
        event := stream.Value()
        if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
            if audioDelta := stepDelta.GetDeltaAudio(); audioDelta != nil && audioDelta.Data != nil {
                audioData, err := base64.StdEncoding.DecodeString(*audioDelta.Data)
                if err != nil {
                    log.Fatal(err)
                }
                // Process the audio chunk (e.g. play it or write to a file)
                _ = audioData
            }
        }
    }
    if err := stream.Err(); err != nil {
        log.Fatal(err)
    }
}

استراحت

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" }
      ]
    }
  }'

گزینه‌های صوتی

Gemini 3.8 TTS از چهار روش برای انتخاب یا ایجاد صداها پشتیبانی می‌کند:

  1. صداهای استودیویی از پیش ساخته شده: 30 صدای منتخب که در جدول زیر فهرست شده‌اند.
  2. کتابخانه صوتی توسعه‌یافته: صدها صدای اضافی در زبان‌ها، لهجه‌ها و الگوهای کاراکتر مختلف که با استفاده از client.voices.list() ( GET /v1beta/voices ) قابل دسترسی هستند.
  3. طراحی صدا : یک شخصیت صوتی سفارشی از توضیحات زبان طبیعی در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="prompted" که یک شناسه voice_... دائمی و یک پیش‌نمایش sample_audio WAV در CreateVoice و GetVoice برمی‌گرداند) ایجاد کنید.
  4. تکرار صدا : صدای گوینده را از صدای مرجع و صدای تایید شده در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="replicated" ، مقدار ثابت store=True به طور پیش‌فرض یا مقدار اختیاری stateless store=False ) کپی کنید.

محدودیت‌های صوتی سفارشی و TTL

نوع صدا حالت ذخیره سازی سهمیه / محدودیت میزان ماندگاری (TTL)
صداهای حالت‌دار ( voice_... ، برانگیخته شده یا تکرار شده) store=True ۲۰۰ صدا در هر پروژه (به اشتراک گذاشته شده در میان صداهای پیشنهادی و تکراری) ۱ سال
کلیدهای صوتی بدون وضعیت ( voicekey_... ، تکثیر شده) store=False مدیریت‌شده توسط مشتری ۷ روز

صداهای از پیش ساخته شده

زفیر -- روشن پک -- خوش‌بین شارون -- آموزنده
کره -- شرکت فنریر -- هیجان‌انگیز لدا -- جوان
اوروس -- شرکت آئوده -- نسیم ملایم کالیرو -- آسان‌گیر
اتونو -- روشن انسلادوس -- نفس‌گیر یاپتوس -- شفاف
آمبریل -- آسان‌گیر آلگیبا -- صاف دسپینا -- صاف
ارینوم -- پاک آلگنیب -- شنی رسالگتی -- آموزنده
لائومدیا -- خوش‌بین آخنار -- نرم آلنیلام -- شرکت
شِدار -- حتی گاکروکس -- بالغ پولچریما -- مهاجم
آچیرد -- دوستانه Zubenelgenubi -- غیررسمی ویندمیاتریکس -- ملایم
ساداچیبیا -- سرزنده سدالتاگر - آگاه سولفات -- گرم

کتابخانه صوتی توسعه‌یافته و فیلترینگ

فراتر از 30 صدای استودیویی برجسته در جدول قبلی، کتابخانه صدای توسعه‌یافته صدها صدای اضافی را در زبان‌ها، لهجه‌های منطقه‌ای، شخصیت‌های شخصیتی و دامنه‌ها ارائه می‌دهد. می‌توانید کل کتابخانه صدا را به صورت تعاملی در Google AI Studio مرور، فیلتر و تست کنید، یا با استفاده از client.voices.list() ( GET /v1beta/voices , using 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_ در پایتون) list[str] فیلتر بر اساس منبع صدا: "prebuilt" ، "prompted" ( طراحی صدا ) یا "replicated" ( تکثیر صدا ).
search str جستجوی زیررشته متن آزاد، بدون حساسیت به حروف بزرگ و کوچک، هم با display_name و هم description مطابقت داشت.
page_size int حداکثر تعداد صداهای برگردانده شده در هر صفحه (پیش‌فرض 50 ، حداکثر 1000 ).
page_token str توکن از response.next_page_token برای دریافت صفحه بعدی نتایج.

پایتون

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}"
    )

جاوا اسکریپت

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}`
  );
}

استراحت

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 ) از بیش از ۱۳۰ زبان و Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) از بیش از ۱۰۰ زبان پشتیبانی می‌کنند:

زبان جمینی ۳.۸ فلش TTS جمینی ۳.۸ فلش-لایت TTS
آچه‌ای (خط عربی) ✔️ ✔️
آفریکانس ✔️ ✔️
آکان ✔️ ✔️
امهری ✔️ ✔️
ارمنی ✔️ ✔️
آسامی ✔️ ✔️
عوضی ✔️ ✔️
بالیایی ✔️ ✔️
بنگلا ✔️ ✔️
بنجار (خط عربی) ✔️ —
بنجار (خط لاتین) ✔️ ✔️
باشقیر ✔️ —
باسک ✔️ ✔️
بلاروسی ✔️ ✔️
بمبا ✔️ —
بوجپوری ✔️ ✔️
بوسنیایی ✔️ ✔️
بوگینی ✔️ ✔️
بلغاری ✔️ ✔️
برمه‌ای ✔️ —
کانتونی ✔️ ✔️
کاتالان ✔️ ✔️
سبوانو ✔️ ✔️
کردی مرکزی ✔️ ✔️
چتیسگری ✔️ ✔️
چینی (خط هانس) ✔️ ✔️
چینی (خط هانت) ✔️ ✔️
تاتاری کریمه ✔️ —
کرواتی ✔️ ✔️
چک ✔️ ✔️
دانمارکی ✔️ ✔️
هلندی ✔️ ✔️
دیولا ✔️ —
دزونگخا ✔️ —
عربی مصری ✔️ ✔️
انگلیسی ✔️ ✔️
استونیایی ✔️ ✔️
فیلیپینی ✔️ ✔️
فنلاندی ✔️ —
فرانسوی ✔️ ✔️
گالیسیایی ✔️ ✔️
گاندا ✔️ ✔️
گرجی ✔️ ✔️
آلمانی ✔️ ✔️
یونانی ✔️ ✔️
گوارانی ✔️ —
گجراتی ✔️ ✔️
کریول هائیتیایی ✔️ ✔️
هاله مغولی ✔️ ✔️
هوسا ✔️ ✔️
عبری ✔️ ✔️
هندی ✔️ ✔️
مجارستانی ✔️ ✔️
ایسلندی ✔️ ✔️
ایگبو ✔️ —
ایلوکو ✔️ ✔️
اندونزیایی ✔️ ✔️
فارسی ایرانی ✔️ ✔️
ایتالیایی ✔️ ✔️
ژاپنی ✔️ ✔️
جاوه ای ✔️ ✔️
کابل ✔️ —
کامبا ✔️ ✔️
کانارا ✔️ ✔️
کشمیری (خط عربی) ✔️ ✔️
کشمیری (خط دیوه) ✔️ ✔️
قزاق ✔️ ✔️
خمر ✔️ ✔️
کیکویو ✔️ ✔️
کینیارواندایی ✔️ ✔️
کنگو ✔️ ✔️
کره ای ✔️ ✔️
قرقیز ✔️ ✔️
لائو ✔️ ✔️
لاتگالیایی ✔️ —
لینگالا ✔️ ✔️
لیتوانیایی ✔️ —
لوکزامبورگی ✔️ —
مقدونی ✔️ ✔️
ماگای ✔️ ✔️
میثیلی ✔️ ✔️
مالایالامی ✔️ ✔️
مالتی ✔️ ✔️
مانیپوری ✔️ ✔️
مراتی ✔️ ✔️
مینانگکابائو (خط عربی) ✔️ ✔️
مینانگکابائو (خط لاتین) ✔️ —
میزو ✔️ ✔️
نپالی (زبان شخصی) ✔️ ✔️
فولفولد نیجریه‌ای ✔️ ✔️
آذربایجان شمالی ✔️ ✔️
سوتوی شمالی ✔️ ✔️
ازبکی شمالی ✔️ ✔️
بوکمال نروژی ✔️ ✔️
نروژی نینورسک ✔️ ✔️
نیانیا ✔️ ✔️
اکسیتان ✔️ —
اودیا (زبان شخصی) ✔️ ✔️
پانگاسینان ✔️ —
فارسی (افغانستان) ✔️ ✔️
لهستانی ✔️ ✔️
پرتغالی ✔️ ✔️
پنجابی ✔️ ✔️
رومانیایی ✔️ ✔️
روسی ✔️ ✔️
سانتالی ✔️ ✔️
صربی ✔️ ✔️
سندی ✔️ —
سینهالی ✔️ ✔️
اسلواکی ✔️ ✔️
اسلوونیایی ✔️ —
سومالیایی ✔️ —
آذربایجان جنوبی ✔️ ✔️
پشتو جنوبی ✔️ ✔️
سوتوی جنوبی ✔️ —
اسپانیایی ✔️ ✔️
عربی استاندارد (خط عربی) ✔️ ✔️
عربی استاندارد (خط لاتین) ✔️ ✔️
استاندارد لتونی ✔️ ✔️
مالایی استاندارد ✔️ ✔️
سواحیلی (زبان شخصی) ✔️ —
سواتی ✔️ —
سوئدی ✔️ —
تاجیک ✔️ —
تامیل ✔️ ✔️
تلوگو ✔️ ✔️
تایلندی ✔️ —
تیگرینیا ✔️ —
آلبانیایی توسک ✔️ —
ترکی ✔️ ✔️
اویغوری ✔️ —
ویتنامی ✔️ ✔️

مدل‌های پشتیبانی‌شده

مدل تک بلندگو چند بلندگو طراحی صدا تکرار صدا
جمینی ۳.۸ فلش TTS ( gemini-3.8-flash-tts ) ✔️ ✔️ ✔️ ✔️
جمینی ۳.۸ فلش-لایت TTS ( gemini-3.8-flash-lite-tts ) ✔️ ✔️ ✔️ ✔️
پیش‌نمایش TTS فلش جمینی ۳.۱ ✔️ ✔️ — —
پیش‌نمایش Gemini 2.5 Pro TTS ✔️ ✔️ — —

چه زمانی از کدام مدل استفاده کنیم

هر دو مدل Gemini 3.8 TTS دقیقاً طرحواره API و قالب اعلان یکسانی را به اشتراک می‌گذارند و به شما امکان می‌دهند با یک تغییر پارامتر، بین آنها جابجا شوید:

  • وقتی حداکثر دقت آکوستیک، اجرای دقیق و کنترل بیان در اولویت هستند، از Gemini 3.8 Flash TTS ( gemini-3.8-flash-tts ) استفاده کنید . این محصول برای کارهای خلاقانه در سطح استودیویی، دیالوگ‌های پیچیده بین چند گوینده، صداهای پشت سر هم سنگین، تلفظ‌های دشوار، گویش‌های منطقه‌ای یا اقلیتی و روایت‌های طولانی که نیاز به صدای بسیار قوی و ثبات تُن صدا در اتاق دارند، ایده‌آل است.
  • از Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) به عنوان جایگزین سریع و مقرون به صرفه‌ی gemini-3.1-flash-tts-preview استفاده کنید. این نرم‌افزار برای تولید انبوه با حجم بالا، آبشارهای عامل صوتی مکالمه‌ای، ویژگی‌های خواندن با صدای بلند، تکثیر صدای قابل اعتماد و گفتار تک‌گوینده‌ی روزمره در زبان‌های اصلی بهینه شده است.

راهنمای مهاجرت

اگر از gemini-3.1-flash-tts-preview یا مدل‌های قدیمی‌تر Gemini TTS به Gemini 3.8 TTS مهاجرت می‌کنید:

  1. انتقال دستورالعمل‌های سطح نوبت به speech_metadata : Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرد. دستورالعمل‌های تحویل 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 ) در درخواست‌های unary: برخلاف gemini-3.1-flash-tts-preview و مدل‌های TTS قبلی (که به‌طور پیش‌فرض PCM audio/l16 خام بدون سربرگ را برمی‌گرداندند)، Gemini 3.8 TTS به‌طور پیش‌فرض برای درخواست‌های unary، صدای WAV ( audio/wav ) را با یک سربرگ استاندارد RIFF برمی‌گرداند.
    • اگر کد شما قبلاً بایت‌های خام PCM را در یک هدر WAV قرار داده است (برای مثال، با استفاده از ماژول wave پایتون یا ffmpeg )، پوشش هدر دستی را حذف کرده و بایت‌های برگردانده شده را مستقیماً در یک فایل .wav بنویسید.
    • اگر خط تولید شما به صدای خام PCM، mu-law یا A-law بدون هدر نیاز دارد، صریحاً response_format روی "audio/l16" ، "audio/mulaw" یا "audio/alaw" تنظیم کنید. به بخش فرمت‌های خروجی صدا مراجعه کنید.

راهنمای راهنمایی

مدل‌های Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرند. برخلاف مدل‌های پیش‌نمایش قبلی که دستورالعمل‌های صحنه در متن ساده جاسازی می‌شدند، Gemini 3.8 TTS دستورالعمل‌های پایدار سطح نوبت ( 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..."

سرعت و مکث

شما می‌توانید ریتم و سکوت را در سه سطح جزئیات کنترل کنید:

  • علائم نگارشی و حذف: برای مکث طبیعی در مکالمه از ویرگول، خط تیره ( -- ) و حذف ( ... ) استفاده کنید.
  • تگ‌های مکث درون‌خطی: <short pause> یا <long pause> را دقیقاً در نقاطی از فیلمنامه که گوینده باید مکث کند، قرار دهید: text Hold on, let me think... <short pause> Alright, I've got it.
  • سرعت نوبت: برای کنترل سرعت صحبت در کل نوبت، در speech_metadata گزینه "style": "speaking rapidly" یا "style": "speaking slowly" را تنظیم کنید.

عروض و آهنگ صدا

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| ) درون نوبت گوینده قرار دهید تا کانال‌های برگشتی طبیعی یا گفتار همپوشانی ایجاد شود بدون اینکه برای هر واکنش به نوبت جداگانه‌ای تقسیم شود.

  • تبادلات کوتاه پشت‌پرده: واکنش‌های کوتاه شنونده ( |oh hmm| ، |oh really?| ، |absolutely| ) را درون نوبت گوینده فعال قرار دهید:
    • نوبت اول (گوینده الف): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • نوبت دوم (گوینده ب): "Ready enough |oh really?| The last blocker cleared this morning."
    • نوبت سوم (گوینده الف): "Then let's ship it |absolutely| and watch the dashboards."
  • گفتار همپوشانی و درهم‌تنیده: از چندین بخش لوله برای شبیه‌سازی گفتار همزمان یا درهم‌تنیده بین دو گوینده استفاده کنید (با 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 خود منتقل کنید.
  • برای پایداری به مرجع صوتی تکیه کنید (فرادستورالعمل‌ها را حذف کنید): مدل‌های Gemini 3.8 TTS طوری آموزش دیده‌اند که ابتدا روی مرجع صوتی لنگر بیندازند. دستورالعمل‌هایی که به مدل می‌گویند صدا را ثابت نگه دارد (مانند "do not switch speaker identity" یا "maintain identical timbre" ) را قرار ندهید—متن اضافی باعث افزایش رانش می‌شود. دستورالعمل‌های سبک غیرضروری را حذف کنید و بگذارید مدل به طور طبیعی حول نقطه پایدار ارائه شده توسط مرجع صوتی تغییر کند.
  • سعی نکنید ویژگی‌های تغییرناپذیر گوینده را در style تغییر دهید: از قرار دادن سن، جنسیت، نام یا تغییرات لهجه دائمی در speech_metadata.style خودداری کنید. در عوض، یک صدای منطقه‌ای را از Extended Voice Library انتخاب کنید یا با Voice design یکی ایجاد کنید.
  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" ) استفاده کنید و وقتی می‌خواهید خط مبنای ثابتی داشته باشید، دقیقاً از همان رشته‌ی کوتاه در نوبت‌های مختلف استفاده کنید.

دیالوگ‌های چند نوبتی و عوامل صوتی

هنگام ساخت عامل‌های صوتی مکالمه‌ای بلادرنگ یا برنامه‌های چند نوبتی:

  • همزمان با رسیدن تکه‌های متن LLM ، در هر نوبت یک فراخوانی TTS انجام دهید.
  • اجازه دهید voice پیکربندی‌شده (صدای از پیش ساخته شده، voice_... طراحی شده، یا voice_... تکثیر شده / voicekey_... ) هویت گوینده را در طول نوبت‌ها حمل کند - هرگز یک شخصیت طولانی را در هر نوبت دوباره ارسال نکنید.
  • فیلد style هر نوبت را خالی بگذارید، یا یک رشته کوتاه و ثابت (مانند "casual, friendly" ) برای کل مکالمه ارسال کنید.
  • به جای اینکه به دنبال سبک‌های قوی‌تر باشید، پاسخ‌های طولانی اپراتور را به نوبت‌های کوتاه‌تر تقسیم کنید.

محدودیت‌ها

  • مدل‌های TTS ورودی‌های فقط متنی را می‌پذیرند و خروجی‌های فقط صوتی تولید می‌کنند.
  • تولید چند گوینده با یک درخواست ( speech_config.speakers ) حداکثر از ۲ گوینده با استفاده از صداهای از پیش ساخته شده پشتیبانی می‌کند. برای ترکیب صداهای سفارشی طراحی شده ( voice_... ) یا کپی شده ( voice_... / voicekey_... ) در گفتگوی چند کاراکتری، نوبت هر گوینده را به صورت جداگانه ترکیب کنید. از آنجا که درخواست‌های تکی به طور پیش‌فرض audio/wav را با یک هدر RIFF 44 بایتی برمی‌گردانند، قبل از اتصال فریم‌های صوتی PCM 24 کیلوهرتز، PCM خام ( {"type": "audio", "mime_type": "audio/l16"} ) را درخواست کنید یا هدر WAV را از هر نوبت جدا کنید.
  • محدودیت‌های ذخیره‌سازی صدای سفارشی و TTL:
    • صداهای دارای وضعیت ( store=True ، فراخوانی یا تکرار): حداکثر ۲۰۰ صدا در هر پروژه با TTL (زمان ماندگاری) ۱ ساله .
    • کلیدهای صوتی بدون وضعیت ( store=False ، voicekey_... ): زمان ماندگاری ۷ روزه (TTL ).
  • برای اطلاع از پوشش زبان‌ها، بخش زبان‌های پشتیبانی‌شده را مرور کنید.

قدم بعدی چیست؟

،

API Gemini می‌تواند ورودی متن را با استفاده از قابلیت‌های تولید متن به گفتار (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 ) از متن، صدای تک‌بلندگو و چندبلندگو تولید کنید.

قبل از اینکه شروع کنی

مطمئن شوید که از مدل Gemini TTS که در بخش مدل‌های پشتیبانی‌شده ذکر شده است، استفاده می‌کنید. برای نتایج بهینه، بررسی کنید که چه زمانی از کدام مدل استفاده کنید تا بهترین مدل را برای حجم کاری خود انتخاب کنید.

ممکن است قبل از شروع ساخت، آزمایش مدل‌های Gemini TTS در AI Studio مفید باشد.

TTS تک بلندگو

برای تبدیل متن به صدای تک‌گوینده با مدل‌های Gemini 3.8 TTS، متن کلمه به کلمه را در input وارد کنید، با استفاده از حاشیه‌نویسی speech_metadata ، استایل‌بندی نوبتی را پیوست کنید و صدای خود را در generation_config.speech_config پیکربندی کنید. می‌توانید صدایی را از گزینه‌های صدای از پیش ساخته شده، کتابخانه صدای توسعه یافته ( GET /v1beta/voices )، یک شناسه طراحی صدای سفارشی ( voice_... ) یا یک شناسه تکثیر صدا ( voice_... ) یا voicekey_... بدون وضعیت اختیاری انتخاب کنید.

این مثال، صدای خروجی پیش‌فرض WAV ( audio/wav ) را از مدل مستقیماً در یک فایل ذخیره می‌کند:

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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 های پایتون و جاوا اسکریپت، می‌توانید داده‌های صوتی تولید شده را با استفاده از ویژگی راحتی interaction.output_audio بازیابی کنید، که آخرین بلوک صوتی تولید شده را برمی‌گرداند (در پاسخ‌های خام REST JSON، صدای کدگذاری شده با base64 در steps[].content[].data ذخیره می‌شود). برای جزئیات بیشتر در مورد ویژگی‌های راحتی، به مرور کلی Interactions مراجعه کنید.

TTS چند بلندگو

برای گفتگوی چند گوینده، دو گوینده را در speech_config.speakers پیکربندی کنید و هر نوبت را به عنوان یک آیتم متنی جداگانه با حاشیه‌نویسی speech_metadata که speaker و style سطح نوبت اختیاری را مشخص می‌کند، ارسال کنید. برای آهنگ طبیعی نوبت‌گیری از "mode": "conversational" استفاده کنید:

پایتون

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": {
            "mode": "conversational",
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

جاوا اسکریپت

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: {
            mode: 'conversational',
            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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    prompt := "TTS the following conversation between Joe and Jane:\n" +
        "Joe: How's it going today Jane?\n" +
        "Jane: Not too bad, how about you?"

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Joe"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Jane"), Voice: genai.Ptr("Puck")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(prompt),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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" }
        ]
      }
    }
  }'

کنترل سبک گفتار با ابرداده و برچسب‌ها

Gemini 3.8 TTS با فیلد 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..." ).

برای بهترین شیوه‌های جامع، به راهنمای Prompting مراجعه کنید.

برو

package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    transcriptRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput(
                "Generate a short transcript around 100 words that reads " +
                    "like it was clipped from a podcast by excited herpetologists. " +
                    "The hosts names are Dr. Anya and Liam.",
            ),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    var transcript string
    if transcriptRes.Interaction.OutputText != nil {
        transcript = *transcriptRes.Interaction.OutputText
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Dr. Anya"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Liam"), Voice: genai.Ptr("Puck")},
        })),
    }

    ttsRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(transcript),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = ttsRes
}

تولید گفتار استریمینگ

شما می‌توانید با تنظیم stream: true ، صدای تولید شده را همزمان با سنتز شدن، پخش کنید. برخلاف درخواست‌های unary (که یک فایل WAV کامل با هدر RIFF برمی‌گردانند)، درخواست‌های پخش به طور پیش‌فرض تکه‌های PCM خطی 16 بیتی علامت‌دار little-endian ( audio/l16 ، 24 کیلوهرتز، مونو) خام بدون هدر را برمی‌گردانند، بنابراین تکه‌های صدا می‌توانند بدون هدرهای کانتینر به طور مداوم پخش یا به هم متصل شوند.

پایتون

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)

جاوا اسکریپت

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();

استراحت

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
  }'

فرمت‌های خروجی صدا

مدل‌های Gemini 3.8 TTS بسته به اینکه درخواست تکی یا استریم باشد، از فرمت‌های صوتی پیش‌فرض متفاوتی استفاده می‌کنند:

  • درخواست‌های تک‌فایلی ( stream=False ): صدای کامل WAV ( audio/wav ) را با یک هدر استاندارد RIFF (24 کیلوهرتز، مونو، PCM با علامت ۱۶ بیتی little-endian) برمی‌گرداند. می‌توانید بایت‌های صدای رمزگشایی شده را مستقیماً در یک فایل .wav ذخیره کنید، بدون اینکه به صورت دستی هدر WAV را به ابتدای آن اضافه کنید.
  • درخواست‌های پخش ( stream=True ): به طور پیش‌فرض تکه‌های خام PCM خطی ( audio/l16 ) بدون سربرگ (24 کیلوهرتز، مونو، PCM لیتل-اندیان علامت‌دار 16 بیتی) را برمی‌گرداند تا تکه‌ها بتوانند به طور مداوم و بدون سربرگ‌های کانتینر روی هر تکه، پخش یا به هم متصل شوند.

برای درخواست کدگذاری صوتی یا نرخ نمونه‌برداری متفاوت، mime_type و sample_rate اختیاری را درون response_format پیکربندی کنید:

قالب مقدار mime_type توضیحات
WAV (پیش‌فرض تک‌فایلی) "audio/wav" فایل WAV غیرفشرده با هدر RIFF (PCM 16 بیتی علامت‌دار little-endian، مونو، پیش‌فرض ۲۴ کیلوهرتز). پیش‌فرض برای درخواست‌های unary.
PCM خام (L16) (پیش‌فرض پخش) "audio/l16" صدای PCM خطی ۱۶ بیتی علامت‌دار little-endian بدون فشرده‌سازی و بدون هدر (۲۴ کیلوهرتز، مونو). پیش‌فرض برای درخواست‌های پخش.
مو-لا "audio/mulaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 mu-law (که معمولاً در سیستم‌های تلفن/IVR آمریکای شمالی و ژاپن استفاده می‌شود).
الف-قانون "audio/alaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 A-law (که معمولاً در سیستم‌های تلفنی اروپایی و بین‌المللی استفاده می‌شود).

همچنین می‌توانید sample_rate بر حسب هرتز (مثلاً 24000 ، 16000 یا 8000 ) مشخص کنید.

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
            Stream:           genai.Ptr(true),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    stream := res.InteractionSSEStreamEvent
    defer stream.Close()

    for stream.Next() {
        event := stream.Value()
        if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
            if audioDelta := stepDelta.GetDeltaAudio(); audioDelta != nil && audioDelta.Data != nil {
                audioData, err := base64.StdEncoding.DecodeString(*audioDelta.Data)
                if err != nil {
                    log.Fatal(err)
                }
                // Process the audio chunk (e.g. play it or write to a file)
                _ = audioData
            }
        }
    }
    if err := stream.Err(); err != nil {
        log.Fatal(err)
    }
}

استراحت

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" }
      ]
    }
  }'

گزینه‌های صوتی

Gemini 3.8 TTS از چهار روش برای انتخاب یا ایجاد صداها پشتیبانی می‌کند:

  1. صداهای استودیویی از پیش ساخته شده: 30 صدای منتخب که در جدول زیر فهرست شده‌اند.
  2. کتابخانه صوتی توسعه‌یافته: صدها صدای اضافی در زبان‌ها، لهجه‌ها و الگوهای کاراکتر مختلف که با استفاده از client.voices.list() ( GET /v1beta/voices ) قابل دسترسی هستند.
  3. طراحی صدا : یک شخصیت صوتی سفارشی از توضیحات زبان طبیعی در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="prompted" که یک شناسه voice_... دائمی و یک پیش‌نمایش sample_audio WAV در CreateVoice و GetVoice برمی‌گرداند) ایجاد کنید.
  4. تکرار صدا : صدای گوینده را از صدای مرجع و صدای تایید شده در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="replicated" ، مقدار ثابت store=True به طور پیش‌فرض یا مقدار اختیاری stateless store=False ) کپی کنید.

محدودیت‌های صوتی سفارشی و TTL

نوع صدا حالت ذخیره سازی سهمیه / محدودیت میزان ماندگاری (TTL)
صداهای حالت‌دار ( voice_... ، برانگیخته شده یا تکرار شده) store=True ۲۰۰ صدا در هر پروژه (به اشتراک گذاشته شده در میان صداهای پیشنهادی و تکراری) ۱ سال
کلیدهای صوتی بدون وضعیت ( voicekey_... ، تکثیر شده) store=False مدیریت‌شده توسط مشتری ۷ روز

صداهای از پیش ساخته شده

زفیر -- روشن پک -- خوش‌بین شارون -- آموزنده
کره -- شرکت فنریر -- هیجان‌انگیز لدا -- جوان
اوروس -- شرکت آئوده -- نسیم ملایم کالیرو -- آسان‌گیر
اتونو -- روشن انسلادوس -- نفس‌گیر یاپتوس -- شفاف
آمبریل -- آسان‌گیر آلگیبا -- صاف دسپینا -- صاف
ارینوم -- پاک آلگنیب -- شنی رسالگتی -- آموزنده
لائومدیا -- خوش‌بین آخنار -- نرم آلنیلام -- شرکت
شِدار -- حتی گاکروکس -- بالغ پولچریما -- مهاجم
آچیرد -- دوستانه Zubenelgenubi -- غیررسمی ویندمیاتریکس -- ملایم
ساداچیبیا -- سرزنده سدالتاگر - آگاه سولفات -- گرم

کتابخانه صوتی توسعه‌یافته و فیلترینگ

فراتر از 30 صدای استودیویی برجسته در جدول قبلی، کتابخانه صدای توسعه‌یافته صدها صدای اضافی را در زبان‌ها، لهجه‌های منطقه‌ای، شخصیت‌های شخصیتی و دامنه‌ها ارائه می‌دهد. می‌توانید کل کتابخانه صدا را به صورت تعاملی در Google AI Studio مرور، فیلتر و تست کنید، یا با استفاده از client.voices.list() ( GET /v1beta/voices , using 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_ در پایتون) list[str] فیلتر بر اساس منبع صدا: "prebuilt" ، "prompted" ( طراحی صدا ) یا "replicated" ( تکثیر صدا ).
search str جستجوی زیررشته متن آزاد، بدون حساسیت به حروف بزرگ و کوچک، هم با display_name و هم description مطابقت داشت.
page_size int حداکثر تعداد صداهای برگردانده شده در هر صفحه (پیش‌فرض 50 ، حداکثر 1000 ).
page_token str توکن از response.next_page_token برای دریافت صفحه بعدی نتایج.

پایتون

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}"
    )

جاوا اسکریپت

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}`
  );
}

استراحت

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 ) از بیش از ۱۳۰ زبان و Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) از بیش از ۱۰۰ زبان پشتیبانی می‌کنند:

زبان جمینی ۳.۸ فلش TTS جمینی ۳.۸ فلش-لایت TTS
آچه‌ای (خط عربی) ✔️ ✔️
آفریکانس ✔️ ✔️
آکان ✔️ ✔️
امهری ✔️ ✔️
ارمنی ✔️ ✔️
آسامی ✔️ ✔️
عوضی ✔️ ✔️
بالیایی ✔️ ✔️
بنگلا ✔️ ✔️
بنجار (خط عربی) ✔️ —
بنجار (خط لاتین) ✔️ ✔️
باشقیر ✔️ —
باسک ✔️ ✔️
بلاروسی ✔️ ✔️
بمبا ✔️ —
بوجپوری ✔️ ✔️
بوسنیایی ✔️ ✔️
بوگینی ✔️ ✔️
بلغاری ✔️ ✔️
برمه‌ای ✔️ —
کانتونی ✔️ ✔️
کاتالان ✔️ ✔️
سبوانو ✔️ ✔️
کردی مرکزی ✔️ ✔️
چتیسگری ✔️ ✔️
چینی (خط هانس) ✔️ ✔️
چینی (خط هانت) ✔️ ✔️
تاتاری کریمه ✔️ —
کرواتی ✔️ ✔️
چک ✔️ ✔️
دانمارکی ✔️ ✔️
هلندی ✔️ ✔️
دیولا ✔️ —
دزونگخا ✔️ —
عربی مصری ✔️ ✔️
انگلیسی ✔️ ✔️
استونیایی ✔️ ✔️
فیلیپینی ✔️ ✔️
فنلاندی ✔️ —
فرانسوی ✔️ ✔️
گالیسیایی ✔️ ✔️
گاندا ✔️ ✔️
گرجی ✔️ ✔️
آلمانی ✔️ ✔️
یونانی ✔️ ✔️
گوارانی ✔️ —
گجراتی ✔️ ✔️
کریول هائیتیایی ✔️ ✔️
هاله مغولی ✔️ ✔️
هوسا ✔️ ✔️
عبری ✔️ ✔️
هندی ✔️ ✔️
مجارستانی ✔️ ✔️
ایسلندی ✔️ ✔️
ایگبو ✔️ —
ایلوکو ✔️ ✔️
اندونزیایی ✔️ ✔️
فارسی ایرانی ✔️ ✔️
ایتالیایی ✔️ ✔️
ژاپنی ✔️ ✔️
جاوه ای ✔️ ✔️
کابل ✔️ —
کامبا ✔️ ✔️
کانارا ✔️ ✔️
کشمیری (خط عربی) ✔️ ✔️
کشمیری (خط دیوه) ✔️ ✔️
قزاق ✔️ ✔️
خمر ✔️ ✔️
کیکویو ✔️ ✔️
کینیارواندایی ✔️ ✔️
کنگو ✔️ ✔️
کره ای ✔️ ✔️
قرقیز ✔️ ✔️
لائو ✔️ ✔️
لاتگالیایی ✔️ —
لینگالا ✔️ ✔️
لیتوانیایی ✔️ —
لوکزامبورگی ✔️ —
مقدونی ✔️ ✔️
ماگای ✔️ ✔️
میثیلی ✔️ ✔️
مالایالامی ✔️ ✔️
مالتی ✔️ ✔️
مانیپوری ✔️ ✔️
مراتی ✔️ ✔️
مینانگکابائو (خط عربی) ✔️ ✔️
مینانگکابائو (خط لاتین) ✔️ —
میزو ✔️ ✔️
نپالی (زبان شخصی) ✔️ ✔️
فولفولد نیجریه‌ای ✔️ ✔️
آذربایجان شمالی ✔️ ✔️
سوتوی شمالی ✔️ ✔️
ازبکی شمالی ✔️ ✔️
بوکمال نروژی ✔️ ✔️
نروژی نینورسک ✔️ ✔️
نیانیا ✔️ ✔️
اکسیتان ✔️ —
اودیا (زبان شخصی) ✔️ ✔️
پانگاسینان ✔️ —
فارسی (افغانستان) ✔️ ✔️
لهستانی ✔️ ✔️
پرتغالی ✔️ ✔️
پنجابی ✔️ ✔️
رومانیایی ✔️ ✔️
روسی ✔️ ✔️
سانتالی ✔️ ✔️
صربی ✔️ ✔️
سندی ✔️ —
سینهالی ✔️ ✔️
اسلواکی ✔️ ✔️
اسلوونیایی ✔️ —
سومالیایی ✔️ —
آذربایجان جنوبی ✔️ ✔️
پشتو جنوبی ✔️ ✔️
سوتوی جنوبی ✔️ —
اسپانیایی ✔️ ✔️
عربی استاندارد (خط عربی) ✔️ ✔️
عربی استاندارد (خط لاتین) ✔️ ✔️
استاندارد لتونی ✔️ ✔️
مالایی استاندارد ✔️ ✔️
سواحیلی (زبان شخصی) ✔️ —
سواتی ✔️ —
سوئدی ✔️ —
تاجیک ✔️ —
تامیل ✔️ ✔️
تلوگو ✔️ ✔️
تایلندی ✔️ —
تیگرینیا ✔️ —
آلبانیایی توسک ✔️ —
ترکی ✔️ ✔️
اویغوری ✔️ —
ویتنامی ✔️ ✔️

مدل‌های پشتیبانی‌شده

مدل تک بلندگو چند بلندگو طراحی صدا تکرار صدا
جمینی ۳.۸ فلش TTS ( gemini-3.8-flash-tts ) ✔️ ✔️ ✔️ ✔️
جمینی ۳.۸ فلش-لایت TTS ( gemini-3.8-flash-lite-tts ) ✔️ ✔️ ✔️ ✔️
پیش‌نمایش TTS فلش جمینی ۳.۱ ✔️ ✔️ — —
پیش‌نمایش Gemini 2.5 Pro TTS ✔️ ✔️ — —

چه زمانی از کدام مدل استفاده کنیم

هر دو مدل Gemini 3.8 TTS دقیقاً طرحواره API و قالب اعلان یکسانی را به اشتراک می‌گذارند و به شما امکان می‌دهند با یک تغییر پارامتر، بین آنها جابجا شوید:

  • وقتی حداکثر دقت آکوستیک، اجرای دقیق و کنترل بیان در اولویت هستند، از Gemini 3.8 Flash TTS ( gemini-3.8-flash-tts ) استفاده کنید . این محصول برای کارهای خلاقانه در سطح استودیویی، دیالوگ‌های پیچیده بین چند گوینده، صداهای پشت سر هم سنگین، تلفظ‌های دشوار، گویش‌های منطقه‌ای یا اقلیتی و روایت‌های طولانی که نیاز به صدای بسیار قوی و ثبات تُن صدا در اتاق دارند، ایده‌آل است.
  • از Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) به عنوان جایگزین سریع و مقرون به صرفه‌ی gemini-3.1-flash-tts-preview استفاده کنید. این نرم‌افزار برای تولید انبوه با حجم بالا، آبشارهای عامل صوتی مکالمه‌ای، ویژگی‌های خواندن با صدای بلند، تکثیر صدای قابل اعتماد و گفتار تک‌گوینده‌ی روزمره در زبان‌های اصلی بهینه شده است.

راهنمای مهاجرت

اگر از gemini-3.1-flash-tts-preview یا مدل‌های قدیمی‌تر Gemini TTS به Gemini 3.8 TTS مهاجرت می‌کنید:

  1. انتقال دستورالعمل‌های سطح نوبت به speech_metadata : Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرد. دستورالعمل‌های تحویل 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 ) در درخواست‌های unary: برخلاف gemini-3.1-flash-tts-preview و مدل‌های TTS قبلی (که به‌طور پیش‌فرض PCM audio/l16 خام بدون سربرگ را برمی‌گرداندند)، Gemini 3.8 TTS به‌طور پیش‌فرض برای درخواست‌های unary، صدای WAV ( audio/wav ) را با یک سربرگ استاندارد RIFF برمی‌گرداند.
    • اگر کد شما قبلاً بایت‌های خام PCM را در یک هدر WAV قرار داده است (برای مثال، با استفاده از ماژول wave پایتون یا ffmpeg )، پوشش هدر دستی را حذف کرده و بایت‌های برگردانده شده را مستقیماً در یک فایل .wav بنویسید.
    • اگر خط تولید شما به صدای خام PCM، mu-law یا A-law بدون هدر نیاز دارد، صریحاً response_format روی "audio/l16" ، "audio/mulaw" یا "audio/alaw" تنظیم کنید. به بخش فرمت‌های خروجی صدا مراجعه کنید.

راهنمای راهنمایی

مدل‌های Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرند. برخلاف مدل‌های پیش‌نمایش قبلی که دستورالعمل‌های صحنه در متن ساده جاسازی می‌شدند، Gemini 3.8 TTS دستورالعمل‌های پایدار سطح نوبت ( 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..."

سرعت و مکث

شما می‌توانید ریتم و سکوت را در سه سطح جزئیات کنترل کنید:

  • علائم نگارشی و حذف: برای مکث طبیعی در مکالمه از ویرگول، خط تیره ( -- ) و حذف ( ... ) استفاده کنید.
  • تگ‌های مکث درون‌خطی: <short pause> یا <long pause> را دقیقاً در نقاطی از فیلمنامه که گوینده باید مکث کند، قرار دهید: text Hold on, let me think... <short pause> Alright, I've got it.
  • سرعت نوبت: برای کنترل سرعت صحبت در کل نوبت، در speech_metadata گزینه "style": "speaking rapidly" یا "style": "speaking slowly" را تنظیم کنید.

عروض و آهنگ صدا

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| ) درون نوبت گوینده قرار دهید تا کانال‌های برگشتی طبیعی یا گفتار همپوشانی ایجاد شود بدون اینکه برای هر واکنش به نوبت جداگانه‌ای تقسیم شود.

  • تبادلات کوتاه پشت‌پرده: واکنش‌های کوتاه شنونده ( |oh hmm| ، |oh really?| ، |absolutely| ) را درون نوبت گوینده فعال قرار دهید:
    • نوبت اول (گوینده الف): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • نوبت دوم (گوینده ب): "Ready enough |oh really?| The last blocker cleared this morning."
    • نوبت سوم (گوینده الف): "Then let's ship it |absolutely| and watch the dashboards."
  • گفتار همپوشانی و درهم‌تنیده: از چندین بخش لوله برای شبیه‌سازی گفتار همزمان یا درهم‌تنیده بین دو گوینده استفاده کنید (با 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 خود منتقل کنید.
  • برای پایداری به مرجع صوتی تکیه کنید (فرادستورالعمل‌ها را حذف کنید): مدل‌های Gemini 3.8 TTS طوری آموزش دیده‌اند که ابتدا روی مرجع صوتی لنگر بیندازند. دستورالعمل‌هایی که به مدل می‌گویند صدا را ثابت نگه دارد (مانند "do not switch speaker identity" یا "maintain identical timbre" ) را قرار ندهید—متن اضافی باعث افزایش رانش می‌شود. دستورالعمل‌های سبک غیرضروری را حذف کنید و بگذارید مدل به طور طبیعی حول نقطه پایدار ارائه شده توسط مرجع صوتی تغییر کند.
  • سعی نکنید ویژگی‌های تغییرناپذیر گوینده را در style تغییر دهید: از قرار دادن سن، جنسیت، نام یا تغییرات لهجه دائمی در speech_metadata.style خودداری کنید. در عوض، یک صدای منطقه‌ای را از Extended Voice Library انتخاب کنید یا با Voice design یکی ایجاد کنید.
  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" ) استفاده کنید و وقتی می‌خواهید خط مبنای ثابتی داشته باشید، دقیقاً از همان رشته‌ی کوتاه در نوبت‌های مختلف استفاده کنید.

دیالوگ‌های چند نوبتی و عوامل صوتی

هنگام ساخت عامل‌های صوتی مکالمه‌ای بلادرنگ یا برنامه‌های چند نوبتی:

  • همزمان با رسیدن تکه‌های متن LLM ، در هر نوبت یک فراخوانی TTS انجام دهید.
  • اجازه دهید voice پیکربندی‌شده (صدای از پیش ساخته شده، voice_... طراحی شده، یا voice_... تکثیر شده / voicekey_... ) هویت گوینده را در طول نوبت‌ها حمل کند - هرگز یک شخصیت طولانی را در هر نوبت دوباره ارسال نکنید.
  • فیلد style هر نوبت را خالی بگذارید، یا یک رشته کوتاه و ثابت (مانند "casual, friendly" ) برای کل مکالمه ارسال کنید.
  • به جای اینکه به دنبال سبک‌های قوی‌تر باشید، پاسخ‌های طولانی اپراتور را به نوبت‌های کوتاه‌تر تقسیم کنید.

محدودیت‌ها

  • مدل‌های TTS ورودی‌های فقط متنی را می‌پذیرند و خروجی‌های فقط صوتی تولید می‌کنند.
  • تولید چند گوینده با یک درخواست ( speech_config.speakers ) حداکثر از ۲ گوینده با استفاده از صداهای از پیش ساخته شده پشتیبانی می‌کند. برای ترکیب صداهای سفارشی طراحی شده ( voice_... ) یا کپی شده ( voice_... / voicekey_... ) در گفتگوی چند کاراکتری، نوبت هر گوینده را به صورت جداگانه ترکیب کنید. از آنجا که درخواست‌های تکی به طور پیش‌فرض audio/wav را با یک هدر RIFF 44 بایتی برمی‌گردانند، قبل از اتصال فریم‌های صوتی PCM 24 کیلوهرتز، PCM خام ( {"type": "audio", "mime_type": "audio/l16"} ) را درخواست کنید یا هدر WAV را از هر نوبت جدا کنید.
  • محدودیت‌های ذخیره‌سازی صدای سفارشی و TTL:
    • صداهای دارای وضعیت ( store=True ، فراخوانی یا تکرار): حداکثر ۲۰۰ صدا در هر پروژه با TTL (زمان ماندگاری) ۱ ساله .
    • کلیدهای صوتی بدون وضعیت ( store=False ، voicekey_... ): زمان ماندگاری ۷ روزه (TTL ).
  • برای اطلاع از پوشش زبان‌ها، بخش زبان‌های پشتیبانی‌شده را مرور کنید.

قدم بعدی چیست؟

،

API Gemini می‌تواند ورودی متن را با استفاده از قابلیت‌های تولید متن به گفتار (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 ) از متن، صدای تک‌بلندگو و چندبلندگو تولید کنید.

قبل از اینکه شروع کنی

مطمئن شوید که از مدل Gemini TTS که در بخش مدل‌های پشتیبانی‌شده ذکر شده است، استفاده می‌کنید. برای نتایج بهینه، بررسی کنید که چه زمانی از کدام مدل استفاده کنید تا بهترین مدل را برای حجم کاری خود انتخاب کنید.

ممکن است قبل از شروع ساخت، آزمایش مدل‌های Gemini TTS در AI Studio مفید باشد.

TTS تک بلندگو

برای تبدیل متن به صدای تک‌گوینده با مدل‌های Gemini 3.8 TTS، متن کلمه به کلمه را در input وارد کنید، با استفاده از حاشیه‌نویسی speech_metadata ، استایل‌بندی نوبتی را پیوست کنید و صدای خود را در generation_config.speech_config پیکربندی کنید. می‌توانید صدایی را از گزینه‌های صدای از پیش ساخته شده، کتابخانه صدای توسعه یافته ( GET /v1beta/voices )، یک شناسه طراحی صدای سفارشی ( voice_... ) یا یک شناسه تکثیر صدا ( voice_... ) یا voicekey_... بدون وضعیت اختیاری انتخاب کنید.

این مثال، صدای خروجی پیش‌فرض WAV ( audio/wav ) را از مدل مستقیماً در یک فایل ذخیره می‌کند:

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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 های پایتون و جاوا اسکریپت، می‌توانید داده‌های صوتی تولید شده را با استفاده از ویژگی راحتی interaction.output_audio بازیابی کنید، که آخرین بلوک صوتی تولید شده را برمی‌گرداند (در پاسخ‌های خام REST JSON، صدای کدگذاری شده با base64 در steps[].content[].data ذخیره می‌شود). برای جزئیات بیشتر در مورد ویژگی‌های راحتی، به مرور کلی Interactions مراجعه کنید.

TTS چند بلندگو

برای گفتگوی چند گوینده، دو گوینده را در speech_config.speakers پیکربندی کنید و هر نوبت را به عنوان یک آیتم متنی جداگانه با حاشیه‌نویسی speech_metadata که speaker و style سطح نوبت اختیاری را مشخص می‌کند، ارسال کنید. برای آهنگ طبیعی نوبت‌گیری از "mode": "conversational" استفاده کنید:

پایتون

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": {
            "mode": "conversational",
            "speakers": [
                {"speaker": "Joe", "voice": "Puck"},
                {"speaker": "Jane", "voice": "Kore"},
            ],
        }
    },
)

with open("out.wav", "wb") as f:
    f.write(base64.b64decode(interaction.output_audio.data))

جاوا اسکریپت

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: {
            mode: 'conversational',
            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();

برو

package main

import (
    "context"
    "encoding/base64"
    "encoding/binary"
    "log"
    "os"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func saveWaveFile(filename string, pcmData []byte) error {
    f, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer f.Close()

    sampleRate := uint32(24000)
    numChannels := uint16(1)
    bitsPerSample := uint16(16)
    byteRate := sampleRate * uint32(numChannels) * uint32(bitsPerSample/8)
    blockAlign := numChannels * (bitsPerSample / 8)
    dataSize := uint32(len(pcmData))

    f.WriteString("RIFF")
    binary.Write(f, binary.LittleEndian, uint32(36+dataSize))
    f.WriteString("WAVEfmt ")
    binary.Write(f, binary.LittleEndian, uint32(16))
    binary.Write(f, binary.LittleEndian, uint16(1))
    binary.Write(f, binary.LittleEndian, numChannels)
    binary.Write(f, binary.LittleEndian, sampleRate)
    binary.Write(f, binary.LittleEndian, byteRate)
    binary.Write(f, binary.LittleEndian, blockAlign)
    binary.Write(f, binary.LittleEndian, bitsPerSample)
    f.WriteString("data")
    binary.Write(f, binary.LittleEndian, dataSize)
    _, err = f.Write(pcmData)
    return err
}

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    prompt := "TTS the following conversation between Joe and Jane:\n" +
        "Joe: How's it going today Jane?\n" +
        "Jane: Not too bad, how about you?"

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Joe"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Jane"), Voice: genai.Ptr("Puck")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(prompt),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    if res.Interaction.OutputAudio != nil && res.Interaction.OutputAudio.Data != nil {
        pcmBytes, err := base64.StdEncoding.DecodeString(*res.Interaction.OutputAudio.Data)
        if err != nil {
            log.Fatal(err)
        }
        if err := saveWaveFile("out.wav", pcmBytes); err != nil {
            log.Fatal(err)
        }
    }
}

استراحت

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" }
        ]
      }
    }
  }'

کنترل سبک گفتار با ابرداده و برچسب‌ها

Gemini 3.8 TTS با فیلد 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..." ).

برای بهترین شیوه‌های جامع، به راهنمای Prompting مراجعه کنید.

برو

package main

import (
    "context"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    transcriptRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.8-flash"),
            Input: interactions.NewInteractionsInput(
                "Generate a short transcript around 100 words that reads " +
                    "like it was clipped from a podcast by excited herpetologists. " +
                    "The hosts names are Dr. Anya and Liam.",
            ),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    var transcript string
    if transcriptRes.Interaction.OutputText != nil {
        transcript = *transcriptRes.Interaction.OutputText
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Speaker: genai.Ptr("Dr. Anya"), Voice: genai.Ptr("Kore")},
            {Speaker: genai.Ptr("Liam"), Voice: genai.Ptr("Puck")},
        })),
    }

    ttsRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput(transcript),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
        }),
    })
    if err != nil {
        log.Fatal(err)
    }
    _ = ttsRes
}

تولید گفتار استریمینگ

شما می‌توانید با تنظیم stream: true ، صدای تولید شده را همزمان با سنتز شدن، پخش کنید. برخلاف درخواست‌های unary (که یک فایل WAV کامل با هدر RIFF برمی‌گردانند)، درخواست‌های پخش به طور پیش‌فرض تکه‌های PCM خطی 16 بیتی علامت‌دار little-endian ( audio/l16 ، 24 کیلوهرتز، مونو) خام بدون هدر را برمی‌گردانند، بنابراین تکه‌های صدا می‌توانند بدون هدرهای کانتینر به طور مداوم پخش یا به هم متصل شوند.

پایتون

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)

جاوا اسکریپت

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();

استراحت

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
  }'

فرمت‌های خروجی صدا

مدل‌های Gemini 3.8 TTS بسته به اینکه درخواست تکی یا استریم باشد، از فرمت‌های صوتی پیش‌فرض متفاوتی استفاده می‌کنند:

  • درخواست‌های تک‌فایلی ( stream=False ): صدای کامل WAV ( audio/wav ) را با یک هدر استاندارد RIFF (24 کیلوهرتز، مونو، PCM با علامت ۱۶ بیتی little-endian) برمی‌گرداند. می‌توانید بایت‌های صدای رمزگشایی شده را مستقیماً در یک فایل .wav ذخیره کنید، بدون اینکه به صورت دستی هدر WAV را به ابتدای آن اضافه کنید.
  • درخواست‌های پخش ( stream=True ): به طور پیش‌فرض تکه‌های خام PCM خطی ( audio/l16 ) بدون سربرگ (24 کیلوهرتز، مونو، PCM لیتل-اندیان علامت‌دار 16 بیتی) را برمی‌گرداند تا تکه‌ها بتوانند به طور مداوم و بدون سربرگ‌های کانتینر روی هر تکه، پخش یا به هم متصل شوند.

برای درخواست کدگذاری صوتی یا نرخ نمونه‌برداری متفاوت، mime_type و sample_rate اختیاری را درون response_format پیکربندی کنید:

قالب مقدار mime_type توضیحات
WAV (پیش‌فرض تک‌فایلی) "audio/wav" فایل WAV غیرفشرده با هدر RIFF (PCM 16 بیتی علامت‌دار little-endian، مونو، پیش‌فرض ۲۴ کیلوهرتز). پیش‌فرض برای درخواست‌های unary.
PCM خام (L16) (پیش‌فرض پخش) "audio/l16" صدای PCM خطی ۱۶ بیتی علامت‌دار little-endian بدون فشرده‌سازی و بدون هدر (۲۴ کیلوهرتز، مونو). پیش‌فرض برای درخواست‌های پخش.
مو-لا "audio/mulaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 mu-law (که معمولاً در سیستم‌های تلفن/IVR آمریکای شمالی و ژاپن استفاده می‌شود).
الف-قانون "audio/alaw" صدای کدگذاری شده‌ی ۸ بیتی G.711 A-law (که معمولاً در سیستم‌های تلفنی اروپایی و بین‌المللی استفاده می‌شود).

همچنین می‌توانید sample_rate بر حسب هرتز (مثلاً 24000 ، 16000 یا 8000 ) مشخص کنید.

پایتون

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))

جاوا اسکریپت

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();

برو

package main

import (
    "context"
    "encoding/base64"
    "log"

    "google.golang.org/genai"
    "google.golang.org/genai/interactions/models/interactions"
    "google.golang.org/genai/interactions/models/operations"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    generationConfig := &interactions.GenerationConfig{
        SpeechConfig: genai.Ptr(interactions.NewSpeechConfigUnion([]interactions.SpeechConfig{
            {Voice: genai.Ptr("Kore")},
        })),
    }

    res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
        Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
            Model: interactions.Model("gemini-3.1-flash-tts-preview"),
            Input: interactions.NewInteractionsInput("Say cheerfully: Have a wonderful day!"),
            ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
                interactions.NewResponseFormat(interactions.AudioResponseFormat{}),
            )),
            GenerationConfig: generationConfig,
            Stream:           genai.Ptr(true),
        }),
    })
    if err != nil {
        log.Fatal(err)
    }

    stream := res.InteractionSSEStreamEvent
    defer stream.Close()

    for stream.Next() {
        event := stream.Value()
        if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
            if audioDelta := stepDelta.GetDeltaAudio(); audioDelta != nil && audioDelta.Data != nil {
                audioData, err := base64.StdEncoding.DecodeString(*audioDelta.Data)
                if err != nil {
                    log.Fatal(err)
                }
                // Process the audio chunk (e.g. play it or write to a file)
                _ = audioData
            }
        }
    }
    if err := stream.Err(); err != nil {
        log.Fatal(err)
    }
}

استراحت

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" }
      ]
    }
  }'

گزینه‌های صوتی

Gemini 3.8 TTS از چهار روش برای انتخاب یا ایجاد صداها پشتیبانی می‌کند:

  1. صداهای استودیویی از پیش ساخته شده: 30 صدای منتخب که در جدول زیر فهرست شده‌اند.
  2. کتابخانه صوتی توسعه‌یافته: صدها صدای اضافی در زبان‌ها، لهجه‌ها و الگوهای کاراکتر مختلف که با استفاده از client.voices.list() ( GET /v1beta/voices ) قابل دسترسی هستند.
  3. طراحی صدا : یک شخصیت صوتی سفارشی از توضیحات زبان طبیعی در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="prompted" که یک شناسه voice_... دائمی و یک پیش‌نمایش sample_audio WAV در CreateVoice و GetVoice برمی‌گرداند) ایجاد کنید.
  4. تکرار صدا : صدای گوینده را از صدای مرجع و صدای تایید شده در Google AI Studio یا با استفاده از POST /v1beta/voices ( type="replicated" ، مقدار ثابت store=True به طور پیش‌فرض یا مقدار اختیاری stateless store=False ) کپی کنید.

محدودیت‌های صوتی سفارشی و TTL

نوع صدا حالت ذخیره سازی سهمیه / محدودیت میزان ماندگاری (TTL)
صداهای حالت‌دار ( voice_... ، برانگیخته شده یا تکرار شده) store=True ۲۰۰ صدا در هر پروژه (به اشتراک گذاشته شده در میان صداهای پیشنهادی و تکراری) ۱ سال
کلیدهای صوتی بدون وضعیت ( voicekey_... ، تکثیر شده) store=False مدیریت‌شده توسط مشتری ۷ روز

صداهای از پیش ساخته شده

زفیر -- روشن پک -- خوش‌بین شارون -- آموزنده
کره -- شرکت فنریر -- هیجان‌انگیز لدا -- جوان
اوروس -- شرکت آئوده -- نسیم ملایم کالیرو -- آسان‌گیر
اتونو -- روشن انسلادوس -- نفس‌گیر یاپتوس -- شفاف
آمبریل -- آسان‌گیر آلگیبا -- صاف دسپینا -- صاف
ارینوم -- پاک آلگنیب -- شنی رسالگتی -- آموزنده
لائومدیا -- خوش‌بین آخنار -- نرم آلنیلام -- شرکت
شِدار -- حتی گاکروکس -- بالغ پولچریما -- مهاجم
آچیرد -- دوستانه Zubenelgenubi -- غیررسمی ویندمیاتریکس -- ملایم
ساداچیبیا -- سرزنده سدالتاگر - آگاه سولفات -- گرم

کتابخانه صوتی توسعه‌یافته و فیلترینگ

فراتر از 30 صدای استودیویی برجسته در جدول قبلی، کتابخانه صدای توسعه‌یافته صدها صدای اضافی را در زبان‌ها، لهجه‌های منطقه‌ای، شخصیت‌های شخصیتی و دامنه‌ها ارائه می‌دهد. می‌توانید کل کتابخانه صدا را به صورت تعاملی در Google AI Studio مرور، فیلتر و تست کنید، یا با استفاده از client.voices.list() ( GET /v1beta/voices , using 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_ در پایتون) list[str] فیلتر بر اساس منبع صدا: "prebuilt" ، "prompted" ( طراحی صدا ) یا "replicated" ( تکثیر صدا ).
search str جستجوی زیررشته متن آزاد، بدون حساسیت به حروف بزرگ و کوچک، هم با display_name و هم description مطابقت داشت.
page_size int حداکثر تعداد صداهای برگردانده شده در هر صفحه (پیش‌فرض 50 ، حداکثر 1000 ).
page_token str توکن از response.next_page_token برای دریافت صفحه بعدی نتایج.

پایتون

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}"
    )

جاوا اسکریپت

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}`
  );
}

استراحت

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 ) از بیش از ۱۳۰ زبان و Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) از بیش از ۱۰۰ زبان پشتیبانی می‌کنند:

زبان جمینی ۳.۸ فلش TTS جمینی ۳.۸ فلش-لایت TTS
آچه‌ای (خط عربی) ✔️ ✔️
آفریکانس ✔️ ✔️
آکان ✔️ ✔️
امهری ✔️ ✔️
ارمنی ✔️ ✔️
آسامی ✔️ ✔️
عوضی ✔️ ✔️
بالیایی ✔️ ✔️
بنگلا ✔️ ✔️
بنجار (خط عربی) ✔️ —
بنجار (خط لاتین) ✔️ ✔️
باشقیر ✔️ —
باسک ✔️ ✔️
بلاروسی ✔️ ✔️
بمبا ✔️ —
بوجپوری ✔️ ✔️
بوسنیایی ✔️ ✔️
بوگینی ✔️ ✔️
بلغاری ✔️ ✔️
برمه‌ای ✔️ —
کانتونی ✔️ ✔️
کاتالان ✔️ ✔️
سبوانو ✔️ ✔️
کردی مرکزی ✔️ ✔️
چتیسگری ✔️ ✔️
چینی (خط هانس) ✔️ ✔️
چینی (خط هانت) ✔️ ✔️
تاتاری کریمه ✔️ —
کرواتی ✔️ ✔️
چک ✔️ ✔️
دانمارکی ✔️ ✔️
هلندی ✔️ ✔️
دیولا ✔️ —
دزونگخا ✔️ —
عربی مصری ✔️ ✔️
انگلیسی ✔️ ✔️
استونیایی ✔️ ✔️
فیلیپینی ✔️ ✔️
فنلاندی ✔️ —
فرانسوی ✔️ ✔️
گالیسیایی ✔️ ✔️
گاندا ✔️ ✔️
گرجی ✔️ ✔️
آلمانی ✔️ ✔️
یونانی ✔️ ✔️
گوارانی ✔️ —
گجراتی ✔️ ✔️
کریول هائیتیایی ✔️ ✔️
هاله مغولی ✔️ ✔️
هوسا ✔️ ✔️
عبری ✔️ ✔️
هندی ✔️ ✔️
مجارستانی ✔️ ✔️
ایسلندی ✔️ ✔️
ایگبو ✔️ —
ایلوکو ✔️ ✔️
اندونزیایی ✔️ ✔️
فارسی ایرانی ✔️ ✔️
ایتالیایی ✔️ ✔️
ژاپنی ✔️ ✔️
جاوه ای ✔️ ✔️
کابل ✔️ —
کامبا ✔️ ✔️
کانارا ✔️ ✔️
کشمیری (خط عربی) ✔️ ✔️
کشمیری (خط دیوه) ✔️ ✔️
قزاق ✔️ ✔️
خمر ✔️ ✔️
کیکویو ✔️ ✔️
کینیارواندایی ✔️ ✔️
کنگو ✔️ ✔️
کره ای ✔️ ✔️
قرقیز ✔️ ✔️
لائو ✔️ ✔️
لاتگالیایی ✔️ —
لینگالا ✔️ ✔️
لیتوانیایی ✔️ —
لوکزامبورگی ✔️ —
مقدونی ✔️ ✔️
ماگای ✔️ ✔️
میثیلی ✔️ ✔️
مالایالامی ✔️ ✔️
مالتی ✔️ ✔️
مانیپوری ✔️ ✔️
مراتی ✔️ ✔️
مینانگکابائو (خط عربی) ✔️ ✔️
مینانگکابائو (خط لاتین) ✔️ —
میزو ✔️ ✔️
نپالی (زبان شخصی) ✔️ ✔️
فولفولد نیجریه‌ای ✔️ ✔️
آذربایجان شمالی ✔️ ✔️
سوتوی شمالی ✔️ ✔️
ازبکی شمالی ✔️ ✔️
بوکمال نروژی ✔️ ✔️
نروژی نینورسک ✔️ ✔️
نیانیا ✔️ ✔️
اکسیتان ✔️ —
اودیا (زبان شخصی) ✔️ ✔️
پانگاسینان ✔️ —
فارسی (افغانستان) ✔️ ✔️
لهستانی ✔️ ✔️
پرتغالی ✔️ ✔️
پنجابی ✔️ ✔️
رومانیایی ✔️ ✔️
روسی ✔️ ✔️
سانتالی ✔️ ✔️
صربی ✔️ ✔️
سندی ✔️ —
سینهالی ✔️ ✔️
اسلواکی ✔️ ✔️
اسلوونیایی ✔️ —
سومالیایی ✔️ —
آذربایجان جنوبی ✔️ ✔️
پشتو جنوبی ✔️ ✔️
سوتوی جنوبی ✔️ —
اسپانیایی ✔️ ✔️
عربی استاندارد (خط عربی) ✔️ ✔️
عربی استاندارد (خط لاتین) ✔️ ✔️
استاندارد لتونی ✔️ ✔️
مالایی استاندارد ✔️ ✔️
سواحیلی (زبان شخصی) ✔️ —
سواتی ✔️ —
سوئدی ✔️ —
تاجیک ✔️ —
تامیل ✔️ ✔️
تلوگو ✔️ ✔️
تایلندی ✔️ —
تیگرینیا ✔️ —
آلبانیایی توسک ✔️ —
ترکی ✔️ ✔️
اویغوری ✔️ —
ویتنامی ✔️ ✔️

مدل‌های پشتیبانی‌شده

مدل تک بلندگو چند بلندگو طراحی صدا تکرار صدا
جمینی ۳.۸ فلش TTS ( gemini-3.8-flash-tts ) ✔️ ✔️ ✔️ ✔️
جمینی ۳.۸ فلش-لایت TTS ( gemini-3.8-flash-lite-tts ) ✔️ ✔️ ✔️ ✔️
پیش‌نمایش TTS فلش جمینی ۳.۱ ✔️ ✔️ — —
پیش‌نمایش Gemini 2.5 Pro TTS ✔️ ✔️ — —

چه زمانی از کدام مدل استفاده کنیم

هر دو مدل Gemini 3.8 TTS دقیقاً طرحواره API و قالب اعلان یکسانی را به اشتراک می‌گذارند و به شما امکان می‌دهند با یک تغییر پارامتر، بین آنها جابجا شوید:

  • وقتی حداکثر دقت آکوستیک، اجرای دقیق و کنترل بیان در اولویت هستند، از Gemini 3.8 Flash TTS ( gemini-3.8-flash-tts ) استفاده کنید . این محصول برای کارهای خلاقانه در سطح استودیویی، دیالوگ‌های پیچیده بین چند گوینده، صداهای پشت سر هم سنگین، تلفظ‌های دشوار، گویش‌های منطقه‌ای یا اقلیتی و روایت‌های طولانی که نیاز به صدای بسیار قوی و ثبات تُن صدا در اتاق دارند، ایده‌آل است.
  • از Gemini 3.8 Flash-Lite TTS ( gemini-3.8-flash-lite-tts ) به عنوان جایگزین سریع و مقرون به صرفه‌ی gemini-3.1-flash-tts-preview استفاده کنید. این نرم‌افزار برای تولید انبوه با حجم بالا، آبشارهای عامل صوتی مکالمه‌ای، ویژگی‌های خواندن با صدای بلند، تکثیر صدای قابل اعتماد و گفتار تک‌گوینده‌ی روزمره در زبان‌های اصلی بهینه شده است.

راهنمای مهاجرت

اگر از gemini-3.1-flash-tts-preview یا مدل‌های قدیمی‌تر Gemini TTS به Gemini 3.8 TTS مهاجرت می‌کنید:

  1. انتقال دستورالعمل‌های سطح نوبت به speech_metadata : Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرد. دستورالعمل‌های تحویل 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 ) در درخواست‌های unary: برخلاف gemini-3.1-flash-tts-preview و مدل‌های TTS قبلی (که به‌طور پیش‌فرض PCM audio/l16 خام بدون سربرگ را برمی‌گرداندند)، Gemini 3.8 TTS به‌طور پیش‌فرض برای درخواست‌های unary، صدای WAV ( audio/wav ) را با یک سربرگ استاندارد RIFF برمی‌گرداند.
    • اگر کد شما قبلاً بایت‌های خام PCM را در یک هدر WAV قرار داده است (برای مثال، با استفاده از ماژول wave پایتون یا ffmpeg )، پوشش هدر دستی را حذف کرده و بایت‌های برگردانده شده را مستقیماً در یک فایل .wav بنویسید.
    • اگر خط تولید شما به صدای خام PCM، mu-law یا A-law بدون هدر نیاز دارد، صریحاً response_format روی "audio/l16" ، "audio/mulaw" یا "audio/alaw" تنظیم کنید. به بخش فرمت‌های خروجی صدا مراجعه کنید.

راهنمای راهنمایی

مدل‌های Gemini 3.8 TTS متن ورودی را دقیقاً به عنوان یک رونوشت کلمه به کلمه در نظر می‌گیرند. برخلاف مدل‌های پیش‌نمایش قبلی که دستورالعمل‌های صحنه در متن ساده جاسازی می‌شدند، Gemini 3.8 TTS دستورالعمل‌های پایدار سطح نوبت ( 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..."

سرعت و مکث

شما می‌توانید ریتم و سکوت را در سه سطح جزئیات کنترل کنید:

  • علائم نگارشی و حذف: برای مکث طبیعی در مکالمه از ویرگول، خط تیره ( -- ) و حذف ( ... ) استفاده کنید.
  • تگ‌های مکث درون‌خطی: <short pause> یا <long pause> را دقیقاً در نقاطی از فیلمنامه که گوینده باید مکث کند، قرار دهید: text Hold on, let me think... <short pause> Alright, I've got it.
  • سرعت نوبت: برای کنترل سرعت صحبت در کل نوبت، در speech_metadata گزینه "style": "speaking rapidly" یا "style": "speaking slowly" را تنظیم کنید.

عروض و آهنگ صدا

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| ) درون نوبت گوینده قرار دهید تا کانال‌های برگشتی طبیعی یا گفتار همپوشانی ایجاد شود بدون اینکه برای هر واکنش به نوبت جداگانه‌ای تقسیم شود.

  • تبادلات کوتاه پشت‌پرده: واکنش‌های کوتاه شنونده ( |oh hmm| ، |oh really?| ، |absolutely| ) را درون نوبت گوینده فعال قرار دهید:
    • نوبت اول (گوینده الف): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • نوبت دوم (گوینده ب): "Ready enough |oh really?| The last blocker cleared this morning."
    • نوبت سوم (گوینده الف): "Then let's ship it |absolutely| and watch the dashboards."
  • گفتار همپوشانی و درهم‌تنیده: از چندین بخش لوله برای شبیه‌سازی گفتار همزمان یا درهم‌تنیده بین دو گوینده استفاده کنید (با 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 خود منتقل کنید.
  • برای پایداری به مرجع صوتی تکیه کنید (فرادستورالعمل‌ها را حذف کنید): مدل‌های Gemini 3.8 TTS طوری آموزش دیده‌اند که ابتدا روی مرجع صوتی لنگر بیندازند. دستورالعمل‌هایی که به مدل می‌گویند صدا را ثابت نگه دارد (مانند "do not switch speaker identity" یا "maintain identical timbre" ) را قرار ندهید—متن اضافی باعث افزایش رانش می‌شود. دستورالعمل‌های سبک غیرضروری را حذف کنید و بگذارید مدل به طور طبیعی حول نقطه پایدار ارائه شده توسط مرجع صوتی تغییر کند.
  • سعی نکنید ویژگی‌های تغییرناپذیر گوینده را در style تغییر دهید: از قرار دادن سن، جنسیت، نام یا تغییرات لهجه دائمی در speech_metadata.style خودداری کنید. در عوض، یک صدای منطقه‌ای را از Extended Voice Library انتخاب کنید یا با Voice design یکی ایجاد کنید.
  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" ) استفاده کنید و وقتی می‌خواهید خط مبنای ثابتی داشته باشید، دقیقاً از همان رشته‌ی کوتاه در نوبت‌های مختلف استفاده کنید.

دیالوگ‌های چند نوبتی و عوامل صوتی

هنگام ساخت عامل‌های صوتی مکالمه‌ای بلادرنگ یا برنامه‌های چند نوبتی:

  • همزمان با رسیدن تکه‌های متن LLM ، در هر نوبت یک فراخوانی TTS انجام دهید.
  • اجازه دهید voice پیکربندی‌شده (صدای از پیش ساخته شده، voice_... طراحی شده، یا voice_... تکثیر شده / voicekey_... ) هویت گوینده را در طول نوبت‌ها حمل کند - هرگز یک شخصیت طولانی را در هر نوبت دوباره ارسال نکنید.
  • فیلد style هر نوبت را خالی بگذارید، یا یک رشته کوتاه و ثابت (مانند "casual, friendly" ) برای کل مکالمه ارسال کنید.
  • به جای اینکه به دنبال سبک‌های قوی‌تر باشید، پاسخ‌های طولانی اپراتور را به نوبت‌های کوتاه‌تر تقسیم کنید.

محدودیت‌ها

  • مدل‌های TTS ورودی‌های فقط متنی را می‌پذیرند و خروجی‌های فقط صوتی تولید می‌کنند.
  • تولید چند گوینده با یک درخواست ( speech_config.speakers ) حداکثر از ۲ گوینده با استفاده از صداهای از پیش ساخته شده پشتیبانی می‌کند. برای ترکیب صداهای سفارشی طراحی شده ( voice_... ) یا کپی شده ( voice_... / voicekey_... ) در گفتگوی چند کاراکتری، نوبت هر گوینده را به صورت جداگانه ترکیب کنید. از آنجا که درخواست‌های تکی به طور پیش‌فرض audio/wav را با یک هدر RIFF 44 بایتی برمی‌گردانند، قبل از اتصال فریم‌های صوتی PCM 24 کیلوهرتز، PCM خام ( {"type": "audio", "mime_type": "audio/l16"} ) را درخواست کنید یا هدر WAV را از هر نوبت جدا کنید.
  • محدودیت‌های ذخیره‌سازی صدای سفارشی و TTL:
    • صداهای دارای وضعیت ( store=True ، فراخوانی یا تکرار): حداکثر ۲۰۰ صدا در هر پروژه با TTL (زمان ماندگاری) ۱ ساله .
    • کلیدهای صوتی بدون وضعیت ( store=False ، voicekey_... ): زمان ماندگاری ۷ روزه (TTL ).
  • برای اطلاع از پوشش زبان‌ها، بخش زبان‌های پشتیبانی‌شده را مرور کنید.

قدم بعدی چیست؟