تولید نوشتار به گفتار (TTS) بااستفاده از Gemini API


می‌توانید از مدل Gemini TTS (gemini-3.8-flash-tts یا gemini-3.8-flash-lite-tts) برای ترکیب گفتار (صدا) طبیعی و رسا از نوشتار استفاده کنید. وقتی از Firebase AI Logic استفاده می‌کنید، می‌توانید این درخواست را مستقیماً از برنامه وب یا تلفن همراهتان (مثل برنامه Apple (Swift)،‏ Android (Kotlin / Java)،‏ Web (JavaScript)،‏ Flutter (Dart)، یا Unity) انجام دهید.

تولید نوشتار به گفتار (TTS) قابل‌کنترل است، به این معنی که شما نوشتار دقیق را برای ترکیب به گفتار ارائه می‌دهید، درحالی‌که نحوه ارائه را—مانند احساسات، سرعت، صدای گوینده، و صداهای غیرگفتاری مانند خنده یا آه—بااستفاده از فراداده‌های ساختاریافته و برچسب‌های صوتی درون‌خطی هدایت می‌کنید. می‌توانید TTS را به‌عنوان نقطه مقابل ترانویسی (گفتار به نوشتار) درنظر بگیرید.

با این قابلیت می‌توانید ویژگی‌هایی مثل موارد زیر بسازید:

  • داستان‌سرایی تعاملی و کتاب‌های صوتی: روایت داستان‌های طولانی یا بازی‌های نقش‌آفرینی که در آن‌ها شخصیت‌ها صداهایشان را تغییر می‌دهند، با کانال‌های بازگشتی هم‌پوشان به یکدیگر واکنش نشان می‌دهند، و لحن احساسی خود را تطبیق می‌دهند (مانند پچ‌پچ کردن در لحظات هیجان‌انگیز یا خندیدن به یک جوک).
  • عوامل و دستیارهای صوتی با تأخیر کم: گفتار ترکیبی را به‌محض دریافت نوشتار از مدل زبانی بزرگ جاری‌سازی کنید و شخصیت صوتی ثابتی را درطول مکالمه حفظ کنید.
  • خوانندگان محتوای چندزبانه و مربیان زبان: مقاله‌ها، دستورالعمل‌های آشپزی، یا مطالب درسی را به بیش‌از ۱۳۰ زبان و لهجه منطقه‌ای با صدای بلند بخوانید، یا زبان‌ها را به‌طور یکپارچه در یک مکالمه تغییر دهید.

این راهنما نشان می‌دهد که چگونه گفتار تک‌گوینده و چندگوینده تولید کنید، پاسخ‌های صوتی را جاری‌سازی کنید، بااستفاده از SpeechMetadata و برچسب‌های درون‌خطی، ارائه صوتی را هدایت کنید، و از بین صداهای ازپیش‌ساخته، کتابخانه‌ای، یا سفارشی انتخاب کنید.

پرش به کد تک‌بلندگو پرش به کد چندبلندگو پرش به کد جاری‌سازی

مقایسه بین TTS و Live API

هر دو مدل نوشتار به گفتار (TTS) و مدل‌های Live API مدل‌های تولید گفتار با تأخیر کم هستند که می‌توانند برای زبان‌ها و صداهای پاسخ مختلف پیکربندی شوند. بااین‌حال، این دو مدل موارد استفاده بسیار متفاوتی دارند.

  • تولید نوشتار به گفتار (TTS) یک تعامل یک‌سویه درخواست-پاسخ است (نوشتار ورودی، صدا خروجی). این مدل برای سناریوهایی که نیاز به بازخوانی دقیق نوشتار ارائه‌شده با کنترل دقیق بر سبک و صدا دارند، مانند روایت پادکست، کتاب‌های صوتی، یا خواندن مقالات با صدای بلند، طراحی شده است.

  • نسل Live API از جاری‌سازی دوجهتی برای مکالمه‌های گفتاری هم‌زمان (ورودی گفتاری، خروجی گفتاری) پشتیبانی می‌کند. این مدل در بافت‌های مکالمه‌ای پویا که مدل تصمیم می‌گیرد چه گفتاری را برگرداند، عالی عمل می‌کند. توجه داشته باشید که جدیدترین مدل‌های Live API از ورودی ویدیو و تصویر نیز پشتیبانی می‌کنند.

قبل از شروع

روی ارائه‌دهنده Gemini API خود کلیک کنید تا محتوا و کد مختص ارائه‌دهنده را در این صفحه ببینید.

اگر قبلاً این کار را نکرده‌اید، راهنمای شروع به کار را تکمیل کنید که نحوه راه‌اندازی پروژه Firebase، اتصال برنامه به Firebase، افزودن کیت توسعه نرم‌افزار، مقداردهی اولیه سرویس پس‌نگر برای ارائه‌دهنده Gemini API انتخابی، و ایجاد نمونه GenerativeModel را شرح می‌دهد.

برای آزمایش و تکرار پیام‌واره‌هایتان، توصیه می‌کنیم از Google AI Studio استفاده کنید.

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

  • gemini-3.8-flash-tts
  • gemini-3.8-flash-lite-tts
مقایسه مدل‌های تبدیل نوشتار به گفتار

هر دو مدل Gemini 3.x TTS طرح‌واره درخواست و قالب پیام‌واره یکسانی دارند. بااین‌حال، در اینجا تفاوت‌هایی برای زمانی که ممکن است از هر مدل استفاده کنید آورده شده است.

ویژگی یا حجم کاری gemini-3.8-flash-tts gemini-3.8-flash-lite-tts
نقطه قوت اصلی وفاداری صدای در حد استودیو، ظرافت بازیگری، و پوشش گسترده گویش‌ها توان گذرداد بالا، تأخیر کم، و مقرون‌به‌صرفه بودن
بهترین موارد استفاده کتاب‌های صوتی، روایت استودیویی، مکالمه پیچیده چندگوینده، برچسب‌های مکرر انفجار صوتی، تلفظ دشوار، گویش‌های منطقه‌ای تولید با حجم بالا، آبشارهای عامل صوتی هم‌زمان، ویژگی‌های میانای کاربر بلند خواندن، گفتار روزمره تک‌گوینده
زبان‌های پشتیبانی‌شده ‫۱۳۲ زبان ۱۰۳ زبان

تولید کردن گفتار از نوشتار

می‌توانید از ورودی نوشتاری، گفتار را به‌صورت صدای یک گوینده یا گفتگوی دو گوینده، به‌صورت فایل WAV کامل (generateContent) یا جاری‌سازی صوتی PCM خام با تأخیر کم (generateContentStream) تولید کنید.

تولید گفتار با یک گوینده

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، همچنین روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

نحوه تولید صدای تک‌گوینده به این صورت است:

  1. در GenerationConfig، responseModalities را روی AUDIO تنظیم کنید و SpeechConfig را با موارد زیر پیکربندی کنید:

  2. TextPart با موارد زیر بسازید:

    • (الزامی) ترانویسی کلمه به کلمه که باید خوانده شود.

    • (اختیاری) SpeechMetadata با شرح style (برای مثال، "cheerful and friendly").

  3. با generateContent تماس بگیرید. به‌طور پیش‌فرض، درخواست‌های تک‌مقداری یک فایل صوتی کامل WAV (audio/wav) (PCM خطی ۱۶ بیتی، ۲۴ کیلوهرتز، مونو، با سرصفحه RIFF استاندارد ۴۴ بایتی) را در بخش‌های داده درون‌خطی پاسخ برمی‌گردانند.

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Set `responseModalities` to include `.audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: SpeechConfig(voiceName: "Kore", languageCode: "en-US")
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.8-flash-tts",
  generationConfig: config
)

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
let prompt = TextPart(
  "Have a wonderful day!",
  speechMetadata: SpeechMetadata(style: "cheerful and friendly")
)

// Call `generateContent` to generate the speech output.
let response = try await model.generateContent(prompt)

// Extract the WAV audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
  let wavData = part.data       // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
  let mimeType = part.mimeType  // for example: "audio/wav"
  print("Received audio data with MIME type: \(mimeType)")

  // Play the WAV audio data using your own playback helper (for example, with `AVAudioPlayer(data: wavData)`).
  playAudio(data: wavData)
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از محدوده Coroutine فراخوانی شوند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = SpeechConfig(
        voice = Voice("Kore"),
        languageCode = "en-US"
    )
}

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.8-flash-tts",
        generationConfig = config
    )

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
val prompt = content {
    text(
        text = "Have a wonderful day!",
        speechMetadata = SpeechMetadata(style = "cheerful and friendly")
    )
}

// Call `generateContent` to generate the speech output.
val response = model.generateContent(prompt)

// Extract the WAV audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
    val wavData = part.inlineData  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

    // Pass the audio data to your audio player or playback helper (which you'll need to implement).
    playAudio(wavData)
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(new SpeechConfig(new Voice("Kore"), "en-US"))
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.8-flash-tts", config);

// Use the GenerativeModelFutures Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
Content content = new Content.Builder()
    .addText("Have a wonderful day!", new SpeechMetadata(null, "cheerful and friendly"))
    .build();
Executor executor = Executors.newSingleThreadExecutor();

// Call `generateContent` to generate the speech output.
// Extract the WAV audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        Part part = result.getCandidates().get(0).getContent().getParts().get(0);
        if (part instanceof InlineDataPart) {
            byte[] wavData = ((InlineDataPart) part).getInlineData();  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

            // Pass the audio data to your audio player or playback helper (which you'll need to implement).
            playAudio(wavData);
        }
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } },
    languageCode: "en-US"
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.8-flash-tts",
  generationConfig
});

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
const prompt = [
  {
    type: "text",
    text: "Have a wonderful day!",
    speechMetadata: { style: "cheerful and friendly" }
  }
];

// Call `generateContent` to generate the speech output.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();

// Extract the WAV audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
  const wavBase64 = inlineDataParts[0].inlineData.data;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
  // Decode base64 to ArrayBuffer
  const wavBuffer = Uint8Array.from(atob(wavBase64), c => c.charCodeAt(0)).buffer;

  // The response is a complete WAV file, so the Web Audio API can decode and play it directly.
  const audioCtx = new AudioContext();
  const audioBuffer = await audioCtx.decodeAudioData(wavBuffer);
  const source = audioCtx.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(audioCtx.destination);
  source.start();
}

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: SpeechConfig(voiceName: 'Kore', languageCode: 'en-US'),
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.8-flash-tts',
  generationConfig: config,
);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
final prompt = Content.multi([
  TextPart(
    'Have a wonderful day!',
    speechMetadata: SpeechMetadata(style: 'cheerful and friendly'),
  ),
]);

// Call `generateContent` to generate the speech output.
final response = await model.generateContent([prompt]);

// Extract the WAV audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
  final Uint8List wavData = part.bytes;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

  // Play the WAV audio data using your preferred audio player or helper (which you'll need to implement).
  await playAudio(wavData);
}

Unity


using Firebase.AI;

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Set `responseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name and language code.
var config = new GenerationConfig(
  responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
  speechConfig: SpeechConfig.UsePrebuiltVoice("Kore", "en-US")
);

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
  modelName: "gemini-3.8-flash-tts",
  generationConfig: config
);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
var prompt = new ModelContent(
  new ModelContent.TextPart(
    "Have a wonderful day!",
    new SpeechMetadata(speaker: null, style: "cheerful and friendly")
  )
);

// Call `GenerateContentAsync` to generate the speech output.
var response = await model.GenerateContentAsync(prompt);

// Extract the WAV audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
  foreach (var part in response.Candidates[0].Content.Parts) {
    if (part is ModelContent.InlineDataPart inlineData) {
      byte[] wavData = inlineData.Data;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

      // Pass the audio data to your audio player or playback helper (which you'll need to implement).
      PlayAudio(wavData);
    }
  }
}

تولید گفتار با چند گوینده

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، همچنین روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

می‌توانید با اختصاص دادن صدای متمایز به هر گوینده و ارسال هر خط از مکالمه به‌عنوان TextPart خودش، مکالمه طبیعی دو گوینده را در یک درخواست تولید کنید:

  1. یک MultiSpeakerVoiceConfig ایجاد کنید که دو نام گوینده (برای مثال، "Joe" و "Jane") را به SpeakerVoiceConfig صداهای آن‌ها نگاشت کند.

  2. در GenerationConfig، responseModalities را روی AUDIO تنظیم کنید و MultiSpeakerVoiceConfig (و languageCode اختیاری) را به SpeechConfig ارسال کنید.

  3. آرایه یا فهرستی از اشیاء TextPart، به‌طور مشخص یک TextPart به‌ازای هر نوبت مکالمه، ارائه دهید. در هر TextPart، SpeechMetadata را با موارد زیر تنظیم کنید:

    • (الزامی) speaker که با یکی از نام‌های گوینده تعریف‌شده در MultiSpeakerVoiceConfig شما مطابقت داشته باشد.
    • (اختیاری) شرحی style (برای مثال، "cheerful and friendly").
  4. با generateContent تماس بگیرید. مدل کل مکالمه را ترکیب می‌کند و فایل صوتی کامل WAV (audio/wav) را برمی‌گرداند.

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
let multiSpeechConfig = SpeechConfig(
  multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
    speakerVoiceConfigs: [
      SpeakerVoiceConfig(speaker: "Joe", voiceName: "Puck"),
      SpeakerVoiceConfig(speaker: "Jane", voiceName: "Kore")
    ]
  ),
  languageCode: "en-US"
)

// Set `responseModalities` to include `.audio`.
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: multiSpeechConfig
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.8-flash-tts",
  generationConfig: config
)

// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
let prompt: [any PartsRepresentable] = [
  TextPart(
    "How's it going today, Jane?",
    speechMetadata: SpeechMetadata(speaker: "Joe", style: "cheerful and friendly")
  ),
  TextPart(
    "Not too bad, how about you?",
    speechMetadata: SpeechMetadata(speaker: "Jane", style: "calm and relaxed")
  )
]

// Call `generateContent` to generate the multi-speaker speech output.
let response = try await model.generateContent(prompt)

// Extract the WAV audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
  let wavData = part.data       // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
  let mimeType = part.mimeType  // for example: "audio/wav"
  print("Received audio data with MIME type: \(mimeType)")

  // Play the WAV audio data using your own playback helper (for example, with `AVAudioPlayer(data: wavData)`).
  playAudio(data: wavData)
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از محدوده Coroutine فراخوانی شوند.

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
val multiSpeechConfig = SpeechConfig(
    multiSpeakerVoiceConfig = MultiSpeakerVoiceConfig(
        speakerVoiceConfigs = listOf(
            SpeakerVoiceConfig(speaker = "Joe", voice = Voice("Puck")),
            SpeakerVoiceConfig(speaker = "Jane", voice = Voice("Kore"))
        )
    ),
    languageCode = "en-US"
)

// Set `responseModalities` to include `AUDIO`.
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = multiSpeechConfig
}

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.8-flash-tts",
        generationConfig = config
    )

// Provide one text part per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
val prompt = content {
    text(
        text = "How's it going today, Jane?",
        speechMetadata = SpeechMetadata(speaker = "Joe", style = "cheerful and friendly")
    )
    text(
        text = "Not too bad, how about you?",
        speechMetadata = SpeechMetadata(speaker = "Jane", style = "calm and relaxed")
    )
}

// Call `generateContent` to generate the multi-speaker speech output.
val response = model.generateContent(prompt)

// Extract the WAV audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
    val wavData = part.inlineData  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

    // Pass the audio data to your audio player or playback helper (which you'll need to implement).
    playAudio(wavData)
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
MultiSpeakerVoiceConfig multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
    Arrays.asList(
        new SpeakerVoiceConfig("Joe", new Voice("Puck")),
        new SpeakerVoiceConfig("Jane", new Voice("Kore"))
    )
);

SpeechConfig multiSpeechConfig = new SpeechConfig(multiSpeakerVoiceConfig, "en-US");

// Set `responseModalities` to include `AUDIO`.
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(multiSpeechConfig)
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.8-flash-tts", config);

// Use the `GenerativeModelFutures` Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide one text part per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
Content content = new Content.Builder()
    .addText(
        "How's it going today, Jane?",
        new SpeechMetadata("Joe", "cheerful and friendly"))
    .addText(
        "Not too bad, how about you?",
        new SpeechMetadata("Jane", "calm and relaxed"))
    .build();
Executor executor = Executors.newSingleThreadExecutor();

// Call `generateContent` to generate the multi-speaker speech output.
// Extract the WAV audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        Part part = result.getCandidates().get(0).getContent().getParts().get(0);
        if (part instanceof InlineDataPart) {
            byte[] wavData = ((InlineDataPart) part).getInlineData();  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

            // Pass the audio data to your audio player or playback helper (which you'll need to implement).
            playAudio(wavData);
        }
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    multiSpeakerVoiceConfig: {
      speakerVoiceConfigs: [
        { speaker: "Joe", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } } },
        { speaker: "Jane", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
      ]
    },
    languageCode: "en-US"
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.8-flash-tts",
  generationConfig
});

// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `speechMetadata`.
const prompt = [
  {
    type: "text",
    text: "How's it going today, Jane?",
    speechMetadata: { speaker: "Joe", style: "cheerful and friendly" }
  },
  {
    type: "text",
    text: "Not too bad, how about you?",
    speechMetadata: { speaker: "Jane", style: "calm and relaxed" }
  }
];

// Call `generateContent` to generate the multi-speaker speech output.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();

// Extract the WAV audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
  const wavBase64 = inlineDataParts[0].inlineData.data;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)
  // Decode base64 to ArrayBuffer
  const wavBuffer = Uint8Array.from(atob(wavBase64), c => c.charCodeAt(0)).buffer;

  // The response is a complete WAV file, so the Web Audio API can decode and play it directly.
  const audioCtx = new AudioContext();
  const audioBuffer = await audioCtx.decodeAudioData(wavBuffer);
  const source = audioCtx.createBufferSource();
  source.buffer = audioBuffer;
  source.connect(audioCtx.destination);
  source.start();
}

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
final multiSpeechConfig = SpeechConfig.multiSpeaker(
  multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
    speakerVoiceConfigs: [
      SpeakerVoiceConfig(speaker: 'Joe', voiceName: 'Puck'),
      SpeakerVoiceConfig(speaker: 'Jane', voiceName: 'Kore'),
    ],
  ),
  languageCode: 'en-US',
);

// Set `responseModalities` to include `audio`.
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: multiSpeechConfig,
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.8-flash-tts',
  generationConfig: config,
);

// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
final prompt = Content.multi([
  TextPart(
    "How's it going today, Jane?",
    speechMetadata: SpeechMetadata(speaker: 'Joe', style: 'cheerful and friendly'),
  ),
  TextPart(
    'Not too bad, how about you?',
    speechMetadata: SpeechMetadata(speaker: 'Jane', style: 'calm and relaxed'),
  ),
]);

// Call `generateContent` to generate the multi-speaker speech output.
final response = await model.generateContent([prompt]);

// Extract the WAV audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
  final Uint8List wavData = part.bytes;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

  // Play the WAV audio data using your preferred audio player or helper (which you'll need to implement).
  await playAudio(wavData);
}

Unity


using Firebase.AI;

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
var multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
  new System.Collections.Generic.List<SpeakerVoiceConfig> {
    SpeakerVoiceConfig.UsePrebuiltVoice("Joe", "Puck"),
    SpeakerVoiceConfig.UsePrebuiltVoice("Jane", "Kore")
  }
);

var multiSpeechConfig = SpeechConfig.UseMultiSpeakerVoice(multiSpeakerVoiceConfig, "en-US");

// Set `responseModalities` to include `Audio`.
var config = new GenerationConfig(
  responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
  speechConfig: multiSpeechConfig
);

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
  modelName: "gemini-3.8-flash-tts",
  generationConfig: config
);

// Provide one `TextPart` per dialogue turn, specifying the speaker and optional style in `SpeechMetadata`.
var prompt = new ModelContent(
  new ModelContent.TextPart(
    "How's it going today, Jane?",
    new SpeechMetadata(speaker: "Joe", style: "cheerful and friendly")
  ),
  new ModelContent.TextPart(
    "Not too bad, how about you?",
    new SpeechMetadata(speaker: "Jane", style: "calm and relaxed")
  )
);

// Call `GenerateContentAsync` to generate the multi-speaker speech output.
var response = await model.GenerateContentAsync(prompt);

// Extract the WAV audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
  foreach (var part in response.Candidates[0].Content.Parts) {
    if (part is ModelContent.InlineDataPart inlineData) {
      byte[] wavData = inlineData.Data;  // WAV audio bytes (24kHz, 1 channel, 16-bit PCM)

      // Pass the audio data to your audio player or playback helper (which you'll need to implement).
      PlayAudio(wavData);
    }
  }
}

جاری‌سازی پاسخ

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، همچنین روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

برای کاهش زمان تا اولین صدا (TTFA) و بازپخش هم‌زمان، می‌توانید پاسخ صوتی را درحین تولید جاری‌سازی کنید، به‌جای اینکه منتظر بمانید تا کل کلیپ تمام شود. جاری‌سازی با پیکربندی‌های تک‌بلندگو و چندبلندگو کار می‌کند.

برای جاری‌سازی گفتار، به‌جای generateContent، با generateContentStream تماس بگیرید. برخلاف درخواست‌های تک‌تایی (که فایل WAV برمی‌گردانند)، درخواست‌های جاری‌سازی تکه‌های PCM بدون سرصفحه خام ۱۶ بیتی با علامت little-endian (audio/l16،‏ ۲۴ کیلوهرتز، تک‌باندی) برمی‌گردانند تا بتوانید هر تکه را مستقیماً به میان‌گیر خروجی صوتی‌تان اضافه کنید.

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Set `responseModalities` to include `.audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: SpeechConfig(voiceName: "Kore")
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.8-flash-tts",
  generationConfig: config
)

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
let prompt = TextPart(
  "Tell me a story about a brave knight.",
  speechMetadata: SpeechMetadata(style: "warm, engaging audiobook narrator")
)

// Call `generateContentStream` to stream the speech output as it is generated.
let responseStream = try model.generateContentStream(prompt)

// Extract the raw PCM audio chunks and queue them for playback:
for try await chunk in responseStream {
  for part in chunk.inlineDataParts {
    let pcmChunk = part.data  // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)

    // Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
    appendAudioChunk(pcmChunk)
  }
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از محدوده Coroutine فراخوانی شوند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = SpeechConfig(voice = Voice("Kore"))
}

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.8-flash-tts",
        generationConfig = config
    )

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
val prompt = content {
    text(
        text = "Tell me a story about a brave knight.",
        speechMetadata = SpeechMetadata(style = "warm, engaging audiobook narrator")
    )
}

// Call `generateContentStream` to stream the speech output as it is generated.
// Extract the raw PCM audio chunks and queue them for playback.
model.generateContentStream(prompt).collect { chunk ->
    val part = chunk.candidates.firstOrNull()?.content?.parts?.firstOrNull()
    if (part is InlineDataPart) {
        val pcmChunk = part.inlineData  // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)

        // Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
        appendAudioChunk(pcmChunk)
    }
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(new SpeechConfig(new Voice("Kore")))
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.8-flash-tts", config);

// Use the `GenerativeModelFutures` Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
Content content = new Content.Builder()
    .addText(
        "Tell me a story about a brave knight.",
        new SpeechMetadata(null, "warm, engaging audiobook narrator"))
    .build();

// Call `generateContentStream` to stream the speech output as it is generated.
Publisher<GenerateContentResponse> streamingResponse =
    model.generateContentStream(content);

// Extract the raw PCM audio chunks and queue them for playback.
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
  @Override
  public void onSubscribe(Subscription s) {
      s.request(Long.MAX_VALUE);
  }

  @Override
  public void onNext(GenerateContentResponse chunk) {
      Part part = chunk.getCandidates().get(0).getContent().getParts().get(0);
      if (part instanceof InlineDataPart) {
          byte[] pcmChunk = ((InlineDataPart) part).getInlineData();  // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)

          // Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
          appendAudioChunk(pcmChunk);
      }
  }

  @Override
  public void onComplete() {
      // Audio stream complete.
  }

  @Override
  public void onError(Throwable t) {
      t.printStackTrace();
  }
});

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } }
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.8-flash-tts",
  generationConfig
});

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
const prompt = [
  {
    type: "text",
    text: "Tell me a story about a brave knight.",
    speechMetadata: { style: "warm, engaging audiobook narrator" }
  }
];

// Call `generateContentStream` to stream the speech output as it is generated.
const result = await model.generateContentStream(prompt);

// Extract the raw PCM audio chunks and queue them for playback:
const playbackQueue = [];
for await (const chunk of result.stream) {
  const inlineDataParts = chunk.inlineDataParts();
  if (inlineDataParts?.[0]) {
    const pcmBase64 = inlineDataParts[0].inlineData.data;  // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)
    const pcmBuffer = Uint8Array.from(atob(pcmBase64), c => c.charCodeAt(0)).buffer;

    // Append the audio chunk to your audio queue/buffer for playback.
    // In a real app, start playing chunks as they arrive (rather than waiting for
    // the whole stream to finish) to get the low-latency benefit of streaming.
    playbackQueue.push(pcmBuffer);
  }
}

// To play back an array of PCM buffers in sequence, pass them to your playback helper (which you'll need to write).
processPlaybackQueue(playbackQueue);

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: SpeechConfig(voiceName: 'Kore'),
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.8-flash-tts',
  generationConfig: config,
);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
final prompt = Content.multi([
  TextPart(
    'Tell me a story about a brave knight.',
    speechMetadata: SpeechMetadata(style: 'warm, engaging audiobook narrator'),
  ),
]);

// Call `generateContentStream` to stream the speech output as it is generated.
final responseStream = model.generateContentStream([prompt]);

// Extract the raw PCM audio chunks and queue them for playback:
await for (final chunk in responseStream) {
  final part = chunk.candidates.first.content.parts.first;
  if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
    final Uint8List pcmChunk = part.bytes;  // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)

    // Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
    appendAudioChunk(pcmChunk);
  }
}

Unity


using System.Collections.Generic;
using System.Linq;
using Firebase.AI;

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Set `ResponseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
var config = new GenerationConfig(
    responseModalities: new List<ResponseModality> { ResponseModality.Audio },
    speechConfig: SpeechConfig.UsePrebuiltVoice("Kore")
);

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
    modelName: "gemini-3.8-flash-tts",
    generationConfig: config
);

// Provide the verbatim text to synthesize as speech.
// Optionally provide turn-level style metadata.
var prompt = new ModelContent(
    new ModelContent.TextPart(
        "Tell me a story about a brave knight.",
        new SpeechMetadata(speaker: null, style: "warm, engaging audiobook narrator")
    )
);

// Call `GenerateContentStreamAsync` to stream the speech output as it is generated.
var responseStream = model.GenerateContentStreamAsync(prompt);

// Extract the raw PCM audio chunks and queue them for playback:
await foreach (var response in responseStream)
{
    var audioParts = response.Candidates.FirstOrDefault().Content.Parts
                            .OfType<ModelContent.InlineDataPart>();

    foreach (var part in audioParts)
    {
        byte[] pcmChunk = part.Data; // Headerless raw PCM bytes (24kHz, 1 channel, 16-bit)

        // Append the audio chunk to your audio queue/buffer for playback (using a helper you implement).
        AppendAudioChunk(pcmChunk);
    }
}



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

مدل‌های Gemini 3.x TTS با text داخل هر TextPart دقیقاً به‌عنوان ترانویسی کلمه‌به‌کلمه رفتار می‌کنند که باید با صدای بلند خوانده شود. دستورالعمل‌های روایی (مثل "Say cheerfully:") را داخل رشته نوشتار ننویسید، وگرنه ممکن است مدل آن کلمات را با صدای بلند بخواند.

بااستفاده از تکنیک‌های زیر می‌توانید اجرای آوازی را هدایت کنید:

style سطح نوبت و برچسب‌های صوتی درون‌خطی

دستورالعمل‌های عملکردتان را براساس دامنه بین SpeechMetadata و برچسب‌های درون‌خطی علامت بزرگ‌تر و کوچک‌تر (<...>) تقسیم کنید.

حوزه محل قرار دادن چه چیزی را کنترل می‌کند مثال‌ها
سطح پیچ
(در سراسر پیچ حفظ می‌شود)
SpeechMetadata.style احساس، شخصیت، لحن، زیروبم، گام، و سرعت کلی صحبت کردن ‫"cheerful and friendly"،‏
"whispered, nervous"،‏
"speaking rapidly"،‏
"out of breath"،‏
"sarcastic"
نقطه زمانی
(بومی‌سازی‌شده برای لحظه‌ای خاص در جمله)
درون‌خطی در نوشتار TextPart بااستفاده از <...> صداهای غیرگفتاری انسان، نفس کشیدن، مکث، یا تغییرات لحظه‌ای در بیان "Wait... <short pause> did you hear that? <gasp> Someone's at the door."

سرعت، مکث، زیروبم، و تأکید

  • نشانه‌های سجاوندی و سه‌نقطه: از ویرگول، خط تیره (--)، و سه‌نقطه (...) در ترانویسی استفاده کنید تا عبارت‌بندی و مکث طبیعی ایجاد شود.

  • برچسب‌های مکث صریح: <short pause> یا <long pause> را به‌صورت درون‌خطی در نقطه دقیقی که گوینده باید مکث کند درج کنید:

    Hold on, let me think... <short pause> Alright, I've got it.
    
  • سرعت و زیروبمی گفتار: style را در SpeechMetadata تنظیم کنید تا سرعت، زیروبمی، یا لحن کلی را برای نوبت کنترل کنید (برای مثال، "speaking rapidly and excitedly"، "speaking slowly"، یا "monotone and flat"). اگر احساس یا سرعت در اواسط تک‌گویی تغییر کرد، متن را به نوبت‌های TextPart جداگانه تقسیم کنید، هرکدام با style خودش.

  • تأکید واژه: کلمات خاصی را در ترانویسی بزرگ‌نویسی کنید تا بر آن‌ها تأکید شود:

    It was a VERY long day <sigh> ... nobody listens anymore.
    

صداهای غیرگفتاری و صداهای ناگهانی

صداهای غیرگفتاری انسان را بااستفاده از پرانتزهای زاویه‌دار (<...>) در مرز دقیق کلمه‌ای که صدا باید در آنجا رخ دهد، به‌صورت درون‌خطی درج کنید. از صداهای انسانی به‌جای جلوه‌های صوتی غیرکلامی استفاده کنید. برچسب‌های توصیه‌شده برای استفاده در اینجا آمده است:

<argh> <exhales> <heavy breath> <scream> <snort>
<breath> <gasp> <hiss> <short pause> <sob>
<cackle> <giggle> <laugh> /
<laughter>
<shout> <throat-clearing>
<cheer> <groan> <long pause> <shriek> <tsk>
<chuckle> /
<chuckles>
<growl> <moan> <sigh> /
<sighs>
<whimper>
<cough> <grr> <pant> <sneeze> <whispers> /
<whispering>
<cry> <grunt> <pff> /
<phew>
<snicker> <yawn>

کانال‌های برگشتی و گفتار هم‌پوشان

در مکالمه چندگوینده، می‌توانید واکنش‌های کوتاه شنونده را در نویسه‌های خط عمودی (|reaction|) در ترانویسی گوینده فعال قرار دهید. گوینده غیرفعال به‌طور طبیعی در آن نقطه بدون نیاز به نوبت جداگانه مداخله می‌کند:

  • پاسخ‌های کوتاه شنونده:

    • نوبت ۱ (speaker: "Joe"): "So the launch is Thursday |oh hmm| Are we actually ready?"
    • نوبت ۲ (speaker: "Jane"): "Ready enough |oh really?| The last blocker cleared this morning."
  • گفتار هم‌پوشان: می‌توانید از چندین بخش خط عمودی برای شبیه‌سازی گفتار هم‌زمان استفاده کنید (با gemini-3.8-flash-tts بهترین عملکرد را دارد)، مانند:

    • نوبت ۱ (speaker: "Joe"): "Let's surprise him on three |ok| ready?"
    • نوبت ۲ (speaker: "Jane"): "one. two. three. |happy| happy |birthday| birthday!"

روال‌های مطلوب برای سازگاری

  • ابتدا بدون style آزمایش کنید، سپس تغییرات جزئی مختصر style را اضافه کنید: اکثر درخواست‌ها با فیلد style خالی طبیعی به‌نظر می‌رسند. فقط وقتی نوبت به اصلاح خاصی در ارائه نیاز دارد، عبارت style کوتاهی (مثل "casual, friendly" یا "reflective and awe-inspired") اضافه کنید و وقتی می‌خواهید خط مبنای ثابتی داشته باشید، همان رشته کوتاه را در نوبت‌های مختلف دوباره استفاده کنید.

  • ترانویسی‌های گفتاری طبیعی بنویسید: مخفف‌های محاوره‌ای و نارسایی‌های طبیعی گفتار (مانند "Oh, uh, yeah I think... hm, that's interesting") را مستقیماً در متن ترانویسی بگنجانید.

  • از بلوک‌های قدیمی [Audio Profile] و فرادستورالعمل‌ها اجتناب کنید: پاراگراف‌های طولانی شخصیت، بلوک‌های [Director's Notes]، یا فرادستورالعمل‌هایی مانند "maintain identical timbre" انحراف صدا را افزایش می‌دهند. به‌جای آن، صدای مطابق را از کتابخانه صدای گسترده انتخاب کنید یا با طراحی صدا صدای شخصیت ثابتی ایجاد کنید.

  • سعی نکنید ویژگی‌های تغییرناپذیر صدا را در style لغو کنید: از SpeechMetadata.style برای تغییر سن، جنسیت، یا لهجه دائمی صدا استفاده نکنید. درعوض، صدایی را با آن ویژگی‌ها انتخاب یا طراحی کنید.



صداهای پشتیبانی‌شده

مدل‌های Gemini 3.x TTS از سه روش برای مشخص کردن صدا پشتیبانی می‌کنند:

همه صداها چندزبانه هستند، یعنی می‌توانید از یک صدا برای تولید گفتار به هریک از زبان‌های پشتیبانی‌شده استفاده کنید و درعین‌حال هویت گوینده را ثابت نگه دارید. برای مثال، اگر صدا را روی صدای ازپیش‌ساخته‌شده Kore تنظیم کنید و پیام‌واره‌ها را به زبان‌های اسپانیایی، هندی، و ویتنامی ارسال کنید، پاسخ‌ها همه از صدای Kore در هریک از این زبان‌ها استفاده می‌کنند. درحالی‌که ۳۰ صدای ازپیش‌ساخته اصلی صداهای چندزبانه با کاربرد عمومی هستند، صداهای کتابخانه صدای گسترده و صداهای سفارشی به یک منطقه زبانی اصلی یا لهجه منطقه‌ای وابسته هستند. این یعنی که آن‌ها همچنان می‌توانند به زبان‌های دیگر صحبت کنند، اما در منطقه زبانی اصلی‌شان واقعی‌تر به‌نظر می‌رسند.

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

مدل‌های Gemini TTS از ۳۰ صدای ازپیش‌ساخته اصلی (مانند Kore، Puck، Zephyr، Charon، و Fenrir) پشتیبانی می‌کنند که هرکدام ویژگی‌های صوتی متمایزی دارند. نام صدا را در SpeechConfig ارسال کنید (همان‌طور که در نمونه‌های تک‌بلندگو و چندبلندگو در ابتدای این صفحه نشان داده شده است).

صداهای پیش‌تنظیم‌شده از «کتابخانه صدای گسترش‌یافته»

علاوه‌بر ۳۰ صدای ازپیش‌ساخته، کتابخانه صدای گسترده بیش‌از ۲۰۰۰ صدای ازپیش‌تنظیم‌شده دست‌چین‌شده را ارائه می‌دهد که زبان‌های مختلف، لهجه‌های منطقه‌ای، محدوده‌های سنی، شخصیت‌های مختلف، و موارد استفاده (مانند کتاب‌های صوتی، نمایندگان پشتیبانی مشتری، و گویندگان خبر) را پوشش می‌دهد.

نحوه استفاده از هر صدایی از «کتابخانه صدای گسترده» در برنامه‌تان در اینجا آمده است:

  1. بااستفاده از یکی از این گزینه‌ها، صداها را مرور و پیش‌نمایش کنید:

  2. رشته id صدای کتابخانه را به‌عنوان نام صدا در SpeechConfig ارسال کنید (مشابه آنچه در مثال تک‌گوینده در ابتدای این صفحه نشان داده شده است).

صداهای سفارشی: طراحی صدا و همانندسازی صدا

مدل‌های Gemini 3.x TTS همچنین از صداهای سفارشی بااستفاده از یکی از گزینه‌های زیر پشتیبانی می‌کنند:

  • طراحی صدا (پیش‌نمایش): صدای سفارشی منحصربه‌فردی را از شرح زبان طبیعی سن، طنین صدا، لهجه، و شخصیت گوینده (بدون نیاز به هیچ صدای مرجعی) تولید کنید. شناسه صدای ذخیره‌شده را برمی‌گرداند (voice_...).

  • همانندسازی صدا (پیش‌نمایش): صدا، لحن، و آهنگ صدای گوینده را از روی یک صدای ضبط‌شده مرجع و یک صدای ضبط‌شده رضایت گفتاری همانندسازی کنید. یا شناسه صدای ذخیره‌شده در پروژه (voice_...) یا کلید همانندسازی صدای بدون حالت و مدیریت‌شده توسط برنامه (voicekey_...) را برمی‌گرداند.

استفاده از صدای سفارشی در برنامه Firebase AI Logic

ایجاد و مدیریت صداهای سفارشی یک عملیات مدیریتی یا سمت سرور است، بنابراین کیت‌های توسعه نرم‌افزار کلاینت Firebase AI Logic مستقیماً نقاط پایانی مدیریت صداها (CreateVoice، ListVoices، DeleteVoice) را نمایش نمی‌دهند.

درعوض، برای استفاده از صدای سفارشی، باید کارهای زیر را انجام دهید:

  1. بااستفاده از یکی از این گزینه‌ها، یک‌بار صدای سفارشی را ایجاد کنید:

    • از Google AI Studio یا Agent  Studio برای دریافت شناسه voice_<id> یا voicekey_<id> استفاده کنید.

    • از Voices API برای دریافت شناسه voice_<id> یا voicekey_<id> خود استفاده کنید. در اسناد ارائه‌دهنده Gemini API انتخابی‌تان بیشتر بدانید:

  2. رشته voice_<id> یا voicekey_<id> را به‌عنوان نام صدا در SpeechConfig ارسال کنید (مشابه آنچه در مثال تک‌بلندگو در ابتدای این صفحه نشان داده شده است).

هنگام استفاده از صداهای سفارشی، الزامات زیر را درنظر داشته باشید:

  • مکان (Agent Platform Gemini API (formerly Vertex AI)): صداهای سفارشی (voice_... و voicekey_...) فقط در مکان global (که مکان پیش‌فرض هنگام استفاده از Firebase AI Logic است) پشتیبانی می‌شوند.

  • درخواست‌های تک‌گوینده: MultiSpeakerVoiceConfig فقط از صداهای پیش‌ساخته اصلی پشتیبانی می‌کند. برای استفاده از صداهای طراحی‌شده سفارشی یا تکراری در یک گفتگوی چندشخصیتی، نوبت هر شخصیت را در یک درخواست جداگانه تک‌گوینده ترکیب کنید.

  • حفظ و انقضا: صداهای سفارشی ذخیره‌شده (voice_...) اگر به‌مدت ۱ سال استفاده نشوند منقضی می‌شوند (هر درخواست ترکیب، زمان‌سنج حفظ ۱ ساله را بازنشانی می‌کند)؛ کلیدهای همانندسازی صدای بدون حالت (voicekey_...) ۷ روز پس‌از ایجاد منقضی می‌شوند.

زبان‌های پشتیبانی‌شده

مدل‌های Gemini 3.x TTS به‌طور خودکار زبان را از نوشتار ورودی شما تشخیص می‌دهند، ازجمله زمانی که پیام‌واره زبان را درطول نوبت‌ها در مکالمه چندگوینده تغییر می‌دهد.

  • Gemini 3.8 Flash TTS (gemini-3.8-flash-tts): از ۱۳۲ زبان پشتیبانی می‌کند.
  • Gemini 3.8 Flash‑Lite TTS (gemini-3.8-flash-lite-tts): از ۱۰۳ زبان پشتیبانی می‌کند.

(اختیاری) کد زبان را به‌طور صریح تنظیم کنید

اگر می‌خواهید ترکیب گفتار را به‌طور صریح به منطقه زبانی خاصی محدود کنید، می‌توانید یک languageCode BCP-47 را در SpeechConfig خود ارسال کنید:



قالب‌های خروجی صوتی

قالب صوتی پیش‌فرض برگردانده‌شده در InlineDataPart به این بستگی دارد که درخواست تک‌مقداری یا جاری‌سازی ارائه دهید:

روش درخواست نوع MIME برگردانده‌شده پیش‌فرض جزئیات قالب صدا
Unary
(generateContent)
audio/wav فایل WAV کامل (PCM خطی ۱۶ بیتی، ۲۴ کیلوهرتز، مونو، بایت کوچک) با سرایند RIFF استاندارد ۴۴ بایتی.

می‌تواند مستقیماً توسط پخش‌کننده‌های صوتی پلاتفرم استاندارد (مانند AVAudioPlayer در پلاتفرم‌های Apple،‏ Web Audio decodeAudioData، یا پخش‌کننده‌های مبتنی بر فایل) پخش شود.

جاری‌سازی
(generateContentStream)
audio/l16 تکه‌های PCM لیتل اندین امضاشده ۱۶ بیتی خام بدون سرصفحه با فرکانس ۲۴ کیلوهرتز، مونو.

برای صف‌بندی میان‌گیر با تأخیر کم و الحاق بدون سرایندهای فایل تکه‌ای طراحی شده است.



محدودیت‌ها و الزامات

هنگام استفاده از مدل‌های Gemini 3.x TTS، محدودیت‌ها و الزامات زیر را درنظر داشته باشید:

  • ورودی فقط نوشتاری، خروجی فقط صوتی: مدل‌های «نوشتار به گفتار» فقط ورودی نوشتاری (TextPart) را می‌پذیرند و لازم است responseModalities روی AUDIO تنظیم شود.

  • فقط ترکیب کلمه‌به‌کلمه: مدل‌ها ترانویسی ارائه‌شده را کلمه‌به‌کلمه می‌خوانند و پاسخ‌های نوشتاری مکالمه‌ای تولید نمی‌کنند.

  • محدودیت‌های داده‌واحد: حداکثر ورودی ۸٬۱۹۲ داده‌واحد و حداکثر خروجی ۱۶٬۳۸۴ داده‌واحد در هر درخواست است.

  • محدودیت چندگوینده: MultiSpeakerVoiceConfig به ۲ گوینده نیاز دارد و فقط از صداهای پیش‌ساخته اصلی پشتیبانی می‌کند. هر TextPart در درخواست چندگوینده‌ای باید شامل SpeechMetadata.speaker مطابق با یکی از گوینده‌های پیکربندی‌شده باشد.

  • پارامترها و روش‌های پشتیبانی‌نشده:

    • کیت‌های توسعه نرم‌افزار Firebase AI Logic هنوز از تنظیم responseFormat در GenerationConfig برای لغو قالب پیش‌فرض خروجی صدا پشتیبانی نمی‌کنند.
    • تنظیم systemInstruction،‏ temperature،‏ topP،‏ topK،‏ candidateCount،‏ presencePenalty، یا frequencyPenalty پشتیبانی نمی‌شود و باعث می‌شود درخواست‌ها با خطای 400 INVALID_ARGUMENT ناموفق شود.
    • فراخوانی countTokens برای مدل‌های «تبدیل نوشتار به گفتار» پشتیبانی نمی‌شود (تعداد داده‌واحدها در usageMetadata در پاسخ برگردانده می‌شود).
  • مکان (Agent Platform Gemini API (formerly Vertex AI)): صداهای سفارشی (voice_... و voicekey_...) به مکان global نیاز دارند (که مکان پیش‌فرض هنگام استفاده از Firebase AI Logic است).



انتقال از gemini-3.1-flash-tts-preview

‫gemini-3.8-flash-tts و gemini-3.8-flash-lite-tts هر دو از ساختار درخواست یکسانی استفاده می‌کنند. جدول مقایسه مدل را مرور کنید تا بهترین جایگزین را برای حجم کاری خود انتخاب کنید و کد خود را به‌صورت زیر به‌روز کنید:

ناحیه ‫gemini-3.1-flash-tts-preview (قدیمی) ‫gemini-3.8-flash-tts و
gemini-3.8-flash-lite-tts
سبک و جهت ارائه در نوشتار پیام‌واره جاسازی شده است. برای مثال:
"Say cheerfully: ..."،
[Audio Profile]،
[Director's Notes]
در SpeechMetadata(style: "...") در هر TextPart قبول شد

نوشتار TextPart را دقیقاً مطابق با ترانویسی گفتاری کلمه‌به‌کلمه نگه دارید.

مکالمه چندگوینده رشته نوشتاری تکی با پیشوندهای "Speaker: ..." درون‌خطی یک TextPart در هر نوبت مکالمه، با SpeechMetadata(speaker: "...", style: "...") در هر TextPart
برچسب‌های صوتی درون‌خطی قلاب. برای مثال،
[sigh] یا [laughs]
پرانتز شکسته. برای مثال،
<sigh> یا <laugh> یا <short pause>

ناروانی‌های گفتاری مانند "uhm" را مستقیماً در نوشتار بنویسید.

قالب صوتی تک‌تایی پیش‌فرض (generateContent) ‫PCM‏ ۱۶ بیتی خام بدون سرصفحه (audio/pcm،‏ ۲۴ کیلوهرتز، مونو) فایل WAV کامل (audio/wav،‏ PCM‏ ۱۶ بیتی، ۲۴ کیلوهرتز، مونو، با سرصفحه RIFF‏ ۴۴ بایتی)

جاری‌سازی (generateContentStream) به‌صورت PCM‏ ۱۶ بیتی خام بدون سرصفحه باقی می‌ماند (audio/l16).

دستورالعمل‌های سیستم، دما، top-P،‏ top-K نادیده گرفته شد با خطای 400 INVALID_ARGUMENT رد شد. این پارامترها را از پیکربندی مدل خود بردارید.

بازبینه انتقال

  • به جدیدترین نسخه Firebase AI Logic SDK ارتقا دهید و نام مدل خود را به gemini-3.8-flash-tts یا gemini-3.8-flash-lite-tts به‌روز کنید.

  • دستورالعمل‌های سبک را به SpeechMetadata.style منتقل کنید: پیشوندهای "Say cheerfully:"، [Audio Profile]، [Scene]، و بلوک‌های [Director's Notes] را از رشته‌های پیام‌واره‌تان بردارید تا مدل آن‌ها را با صدای بلند نخواند. به‌جای آن، شرح سبک مختصری را در SpeechMetadata.style ارسال کنید.

  • تقسیم کردن متن‌های چندگوینده به TextPart نوبت جداگانه: بلوک‌های نوشتاری "Joe: ... \n Jane: ..." را با آرایه/فهرستی از اشیاء TextPart جایگزین کنید که هر نوبت SpeechMetadata.speaker را تنظیم می‌کند.

  • تبدیل برچسب‌های [...] به برچسب‌های <...>: برچسب‌های صوتی داخل کروشه (مانند [whispers]، [sighs]، [laughs]) را با برچسب‌های صوتی داخل پرانتز زاویه‌دار (مانند <whispers>، <sigh>، <laugh>، <short pause>) جایگزین کنید.

  • به‌روزرسانی بازپخش صوتی تک‌تایی: چون generateContent اکنون یک فایل WAV کامل (با سرایند RIFF‏ ۴۴ بایتی) را به‌جای PCM خام بدون سرایند برمی‌گرداند، هر کدی را که به‌صورت دستی سرایند WAV را به پاسخ‌های تک‌تایی اضافه می‌کند بردارید (یا اگر نمونه‌های PCM خام را به یک میان‌گیر API سطح پایین مانند AudioTrack Android یا AudioClip Unity وارد می‌کنید، از سرایند ۴۴ بایتی صرف‌نظر کنید).

  • برداشتن پارامترهای پیکربندی پشتیبانی‌نشده: temperature، topP، topK، candidateCount، presencePenalty، frequencyPenalty، و systemInstruction را از پیکربندی GenerativeModel نوشتار به گفتار بردارید.



چه کارهای دیگری می‌توانید انجام دهید؟

امتحان کردن قابلیت‌های دیگر

با نحوه کنترل کردن تولید محتوا آشنا شوید

همچنین می‌توانید با پیام‌واره‌ها و پیکربندی‌های مدل آزمایش کنید و حتی بااستفاده از Google AI Studio تکه‌کد تولیدشده دریافت کنید.

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

با مدل‌های دردسترس برای موارد استفاده مختلف و سهمیه‌ها و قیمت‌گذاری آن‌ها آشنا شوید.


درباره تجربه‌تان با Firebase AI Logic بازخورد ارائه دهید