Live API capabilities guide

این یک راهنمای جامع است که قابلیت ها و پیکربندی های موجود با Live API را پوشش می دهد. برای مشاهده کلی و کد نمونه برای موارد استفاده رایج، به صفحه شروع با Live API مراجعه کنید .

قبل از شروع

  • با مفاهیم اصلی آشنا شوید: اگر قبلاً این کار را نکرده‌اید، ابتدا صفحه شروع با Live API را بخوانید. این شما را با اصول اساسی Live API، نحوه عملکرد آن، و تمایز بین مدل‌های مختلف و روش‌های تولید صوتی مربوطه ( صوتی بومی یا نیمه آبشاری) آشنا می‌کند.
  • Live API را در AI Studio امتحان کنید: ممکن است قبل از شروع ساخت، امتحان Live API در Google AI Studio مفید باشد. برای استفاده از Live API در Google AI Studio، Stream را انتخاب کنید.

برقراری ارتباط

مثال زیر نحوه ایجاد ارتباط با کلید API را نشان می دهد:

پایتون

import asyncio
from google import genai

client = genai.Client()

model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        print("Session started")

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        console.debug(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send content...

  session.close();
}

main();

روش های تعامل

بخش‌های زیر نمونه‌ها و زمینه‌های پشتیبانی را برای روش‌های مختلف ورودی و خروجی موجود در Live API ارائه می‌کنند.

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

در اینجا نحوه ارسال و دریافت متن آورده شده است:

پایتون

import asyncio
from google import genai

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello, how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.text is not None:
                print(response.text, end="")

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

به روز رسانی افزایشی محتوا

از به‌روزرسانی‌های افزایشی برای ارسال ورودی متن، ایجاد زمینه جلسه یا بازیابی بافت جلسه استفاده کنید. برای زمینه‌های کوتاه، می‌توانید تعاملات گام به گام را برای نشان دادن توالی دقیق رویدادها ارسال کنید:

پایتون

turns = [
    {"role": "user", "parts": [{"text": "What is the capital of France?"}]},
    {"role": "model", "parts": [{"text": "Paris"}]},
]

await session.send_client_content(turns=turns, turn_complete=False)

turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]

await session.send_client_content(turns=turns, turn_complete=True)

جاوا اسکریپت

let inputTurns = [
  { "role": "user", "parts": [{ "text": "What is the capital of France?" }] },
  { "role": "model", "parts": [{ "text": "Paris" }] },
]

session.sendClientContent({ turns: inputTurns, turnComplete: false })

inputTurns = [{ "role": "user", "parts": [{ "text": "What is the capital of Germany?" }] }]

session.sendClientContent({ turns: inputTurns, turnComplete: true })

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

ارسال و دریافت صدا

رایج‌ترین مثال صوتی، صدا به صدا ، در راهنمای شروع ارائه شده است.

در اینجا یک مثال صوتی به متن است که یک فایل WAV را می خواند، آن را با فرمت صحیح ارسال می کند و خروجی متن را دریافت می کند:

پایتون

# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
from google import genai
from google.genai import types
import soundfile as sf
import librosa

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:

        buffer = io.BytesIO()
        y, sr = librosa.load("sample.wav", sr=16000)
        sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
        buffer.seek(0)
        audio_bytes = buffer.read()

        # If already in correct format, you can use this:
        # audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        async for response in session.receive():
            if response.text is not None:
                print(response.text)

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
// Install helpers for converting files: npm install wavefile
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("sample.wav");

  // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
  const wav = new WaveFile();
  wav.fromBuffer(fileBuffer);
  wav.toSampleRate(16000);
  wav.toBitDepth("16");
  const base64Audio = wav.toBase64();

  // If already in correct format, you can use this:
  // const fileBuffer = fs.readFileSync("sample.pcm");
  // const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }

  );

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

و در اینجا یک مثال متن به صوتی است. با تنظیم AUDIO به عنوان حالت پاسخ می توانید صدا را دریافت کنید. این مثال داده های دریافتی را به عنوان فایل WAV ذخیره می کند:

پایتون

import asyncio
import wave
from google import genai

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["AUDIO"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)

        message = "Hello how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.data is not None:
                wf.writeframes(response.data)

            # Un-comment this code to print audio data info
            # if response.server_content.model_turn is not None:
            #      print(response.server_content.model_turn.parts[0].inline_data.mime_type)

        wf.close()

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.AUDIO] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  // Combine audio data strings and save as wave file
  const combinedAudio = turns.reduce((acc, turn) => {
    if (turn.data) {
      const buffer = Buffer.from(turn.data, 'base64');
      const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
      return acc.concat(Array.from(intArray));
    }
    return acc;
  }, []);

  const audioBuffer = new Int16Array(combinedAudio);

  const wf = new WaveFile();
  wf.fromScratch(1, 24000, '16', audioBuffer);
  fs.writeFileSync('output.wav', wf.toBuffer());

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

فرمت های صوتی

داده‌های صوتی در Live API همیشه خام، کم‌کمک و PCM 16 بیتی است. خروجی صدا همیشه از نرخ نمونه 24 کیلوهرتز استفاده می کند. صدای ورودی به طور طبیعی 16 کیلوهرتز است، اما Live API در صورت نیاز مجدداً نمونه‌گیری می‌کند تا هر نرخ نمونه ارسال شود. برای انتقال نرخ نمونه صدای ورودی، نوع MIME هر Blob حاوی صدا را روی مقداری مانند audio/pcm;rate=16000 تنظیم کنید.

رونویسی های صوتی

می‌توانید با ارسال output_audio_transcription در تنظیمات تنظیمات، رونویسی خروجی صدای مدل را فعال کنید. زبان رونویسی از پاسخ مدل استنباط می شود.

پایتون

import asyncio
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["AUDIO"],
        "output_audio_transcription": {}
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello? Gemini are you there?"

        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.server_content.model_turn:
                print("Model turn:", response.server_content.model_turn)
            if response.server_content.output_transcription:
                print("Transcript:", response.server_content.output_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';

const config = {
  responseModalities: [Modality.AUDIO],
  outputAudioTranscription: {}
};

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  const inputTurns = 'Hello how are you?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.outputTranscription) {
      console.debug('Received output transcription: %s\n', turn.serverContent.outputTranscription.text);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

می‌توانید با ارسال input_audio_transcription در تنظیمات تنظیمات، رونویسی ورودی صوتی را فعال کنید.

پایتون

import asyncio
from pathlib import Path
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {
    "response_modalities": ["TEXT"],
    "input_audio_transcription": {},
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        audio_data = Path("16000.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
        )

        async for msg in session.receive():
            if msg.server_content.input_transcription:
                print('Transcript:', msg.server_content.input_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';

const config = {
  responseModalities: [Modality.TEXT],
  inputAudioTranscription: {}
};

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("16000.wav");

  // Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
  const wav = new WaveFile();
  wav.fromBuffer(fileBuffer);
  wav.toSampleRate(16000);
  wav.toBitDepth("16");
  const base64Audio = wav.toBase64();

  // If already in correct format, you can use this:
  // const fileBuffer = fs.readFileSync("sample.pcm");
  // const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }
  );

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.outputTranscription) {
      console.log("Transcription")
      console.log(turn.serverContent.outputTranscription.text);
    }
  }
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
    else if (turn.serverContent && turn.serverContent.inputTranscription) {
      console.debug('Received input transcription: %s\n', turn.serverContent.inputTranscription.text);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

پخش صدا و تصویر

صدا و زبان را تغییر دهید

مدل‌های Live API هر کدام از صداهای متفاوتی پشتیبانی می‌کنند. Half-Cascade از Puck، Charon، Kore، Fenrir، Aoede، Leda، Orus و Zephyr پشتیبانی می کند. صدای بومی از لیست بسیار طولانی‌تری (یکسان با لیست مدل TTS ) پشتیبانی می‌کند. می توانید به تمام صداها در AI Studio گوش دهید.

برای تعیین یک صدا، نام صدا را در شی speechConfig به عنوان بخشی از پیکربندی جلسه تنظیم کنید:

پایتون

config = {
    "response_modalities": ["AUDIO"],
    "speech_config": {
        "voice_config": {"prebuilt_voice_config": {"voice_name": "Kore"}}
    },
}

جاوا اسکریپت

const config = {
  responseModalities: [Modality.AUDIO],
  speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
};

Live API از چندین زبان پشتیبانی می کند.

برای تغییر زبان، کد زبان را در شی speechConfig به عنوان بخشی از پیکربندی جلسه تنظیم کنید:

پایتون

config = {
    "response_modalities": ["AUDIO"],
    "speech_config": {
        "language_code": "de-DE"
    }
}

جاوا اسکریپت

const config = {
  responseModalities: [Modality.AUDIO],
  speechConfig: { languageCode: "de-DE" }
};

قابلیت های صوتی بومی

قابلیت های زیر فقط با صدای بومی موجود است. می‌توانید در انتخاب مدل و تولید صدا درباره صدای بومی اطلاعات بیشتری کسب کنید.

نحوه استفاده از خروجی صوتی بومی

برای استفاده از خروجی صدای بومی، یکی از مدل های صوتی بومی را پیکربندی کنید و response_modalities روی AUDIO تنظیم کنید.

برای مثال کامل به ارسال و دریافت صدا مراجعه کنید.

پایتون

model = "gemini-2.5-flash-preview-native-audio-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])

async with client.aio.live.connect(model=model, config=config) as session:
    # Send audio input and receive audio

جاوا اسکریپت

const model = 'gemini-2.5-flash-preview-native-audio-dialog';
const config = { responseModalities: [Modality.AUDIO] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    config: config,
    callbacks: ...,
  });

  // Send audio input and receive audio

  session.close();
}

main();

گفتگوی تاثیرگذار

این ویژگی به Gemini اجازه می دهد تا سبک پاسخ خود را با عبارت ورودی و لحن تطبیق دهد.

برای استفاده از دیالوگ افکتیو، نسخه api را روی v1alpha تنظیم کنید و enable_affective_dialog در پیام راه‌اندازی روی true تنظیم کنید:

پایتون

client = genai.Client(http_options={"api_version": "v1alpha"})

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    enable_affective_dialog=True
)

جاوا اسکریپت

const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });

const config = {
  responseModalities: [Modality.AUDIO],
  enableAffectiveDialog: true
};

توجه داشته باشید که گفتگوی عاطفی در حال حاضر فقط توسط مدل های خروجی صوتی بومی پشتیبانی می شود.

صوتی فعال

وقتی این ویژگی فعال است، Gemini می‌تواند فعالانه تصمیم بگیرد که اگر محتوا مرتبط نیست، پاسخی ندهد.

برای استفاده از آن، نسخه api را روی v1alpha تنظیم کنید و قسمت proactivity را در پیام تنظیم پیکربندی کنید و proactive_audio روی true تنظیم کنید:

پایتون

client = genai.Client(http_options={"api_version": "v1alpha"})

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    proactivity={'proactive_audio': True}
)

جاوا اسکریپت

const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });

const config = {
  responseModalities: [Modality.AUDIO],
  proactivity: { proactiveAudio: true }
}

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

خروجی صوتی بومی با تفکر

خروجی صدای بومی از قابلیت‌های تفکر پشتیبانی می‌کند که از طریق یک مدل جداگانه gemini-2.5-flash-exp-native-audio-thinking-dialog در دسترس است.

برای مثال کامل به ارسال و دریافت صدا مراجعه کنید.

پایتون

model = "gemini-2.5-flash-exp-native-audio-thinking-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])

async with client.aio.live.connect(model=model, config=config) as session:
    # Send audio input and receive audio

جاوا اسکریپت

const model = 'gemini-2.5-flash-exp-native-audio-thinking-dialog';
const config = { responseModalities: [Modality.AUDIO] };

async function main() {

  const session = await ai.live.connect({
    model: model,
    config: config,
    callbacks: ...,
  });

  // Send audio input and receive audio

  session.close();
}

main();

تشخیص فعالیت صوتی (VAD)

Voice Activity Detection (VAD) به مدل اجازه می‌دهد تشخیص دهد که یک شخص در حال صحبت کردن است. این برای ایجاد مکالمات طبیعی ضروری است، زیرا به کاربر اجازه می دهد مدل را در هر زمان قطع کند.

هنگامی که VAD یک وقفه را تشخیص می دهد، نسل در حال انجام لغو و کنار گذاشته می شود. فقط اطلاعاتی که قبلاً برای مشتری ارسال شده است در تاریخچه جلسه حفظ می شود. سپس سرور یک پیام BidiGenerateContentServerContent برای گزارش وقفه ارسال می کند.

سپس سرور Gemini هرگونه تماس تابع معلق را کنار می‌گذارد و یک پیام BidiGenerateContentServerContent با شناسه تماس‌های لغو شده ارسال می‌کند.

پایتون

async for response in session.receive():
    if response.server_content.interrupted is True:
        # The generation was interrupted

        # If realtime playback is implemented in your application,
        # you should stop playing audio and clear queued playback here.

جاوا اسکریپت

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.serverContent && turn.serverContent.interrupted) {
    // The generation was interrupted

    // If realtime playback is implemented in your application,
    // you should stop playing audio and clear queued playback here.
  }
}

VAD اتوماتیک

به‌طور پیش‌فرض، مدل به‌طور خودکار VAD را روی یک جریان ورودی صوتی پیوسته انجام می‌دهد. VAD را می توان با فیلد realtimeInputConfig.automaticActivityDetection پیکربندی راه اندازی پیکربندی کرد.

هنگامی که جریان صوتی برای بیش از یک ثانیه متوقف می‌شود (مثلاً به دلیل خاموش کردن میکروفون توسط کاربر)، باید یک رویداد audioStreamEnd ارسال شود تا هر صدای ذخیره شده در حافظه پنهان پاک شود. مشتری می تواند در هر زمانی ارسال داده های صوتی را از سر بگیرد.

پایتون

# example audio file to try:
# URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
# !wget -q $URL -O sample.pcm
import asyncio
from pathlib import Path
from google import genai
from google.genai import types

client = genai.Client()
model = "gemini-live-2.5-flash-preview"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        audio_bytes = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(
            audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
        )

        # if stream gets paused, send:
        # await session.send_realtime_input(audio_stream_end=True)

        async for response in session.receive():
            if response.text is not None:
                print(response.text)

if __name__ == "__main__":
    asyncio.run(main())

جاوا اسکریپت

// example audio file to try:
// URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
// !wget -q $URL -O sample.pcm
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";

const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
  const responseQueue = [];

  async function waitMessage() {
    let done = false;
    let message = undefined;
    while (!done) {
      message = responseQueue.shift();
      if (message) {
        done = true;
      } else {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    return message;
  }

  async function handleTurn() {
    const turns = [];
    let done = false;
    while (!done) {
      const message = await waitMessage();
      turns.push(message);
      if (message.serverContent && message.serverContent.turnComplete) {
        done = true;
      }
    }
    return turns;
  }

  const session = await ai.live.connect({
    model: model,
    callbacks: {
      onopen: function () {
        console.debug('Opened');
      },
      onmessage: function (message) {
        responseQueue.push(message);
      },
      onerror: function (e) {
        console.debug('Error:', e.message);
      },
      onclose: function (e) {
        console.debug('Close:', e.reason);
      },
    },
    config: config,
  });

  // Send Audio Chunk
  const fileBuffer = fs.readFileSync("sample.pcm");
  const base64Audio = Buffer.from(fileBuffer).toString('base64');

  session.sendRealtimeInput(
    {
      audio: {
        data: base64Audio,
        mimeType: "audio/pcm;rate=16000"
      }
    }

  );

  // if stream gets paused, send:
  // session.sendRealtimeInput({ audioStreamEnd: true })

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.text) {
      console.debug('Received text: %s\n', turn.text);
    }
    else if (turn.data) {
      console.debug('Received inline data: %s\n', turn.data);
    }
  }

  session.close();
}

async function main() {
  await live().catch((e) => console.error('got error', e));
}

main();

با send_realtime_input ، API به طور خودکار بر اساس VAD به صدا پاسخ می دهد. در حالی که send_client_content پیام‌ها را به ترتیب به بافت مدل اضافه می‌کند، send_realtime_input برای پاسخگویی به هزینه ترتیب‌بندی قطعی بهینه می‌شود.

پیکربندی خودکار VAD

برای کنترل بیشتر بر فعالیت VAD، می توانید پارامترهای زیر را پیکربندی کنید. برای اطلاعات بیشتر به مرجع API مراجعه کنید.

پایتون

from google.genai import types

config = {
    "response_modalities": ["TEXT"],
    "realtime_input_config": {
        "automatic_activity_detection": {
            "disabled": False, # default
            "start_of_speech_sensitivity": types.StartSensitivity.START_SENSITIVITY_LOW,
            "end_of_speech_sensitivity": types.EndSensitivity.END_SENSITIVITY_LOW,
            "prefix_padding_ms": 20,
            "silence_duration_ms": 100,
        }
    }
}

جاوا اسکریپت

import { GoogleGenAI, Modality, StartSensitivity, EndSensitivity } from '@google/genai';

const config = {
  responseModalities: [Modality.TEXT],
  realtimeInputConfig: {
    automaticActivityDetection: {
      disabled: false, // default
      startOfSpeechSensitivity: StartSensitivity.START_SENSITIVITY_LOW,
      endOfSpeechSensitivity: EndSensitivity.END_SENSITIVITY_LOW,
      prefixPaddingMs: 20,
      silenceDurationMs: 100,
    }
  }
};

VAD خودکار را غیرفعال کنید

از طرف دیگر، VAD خودکار را می‌توان با تنظیم realtimeInputConfig.automaticActivityDetection.disabled روی true در پیام راه‌اندازی غیرفعال کرد. در این پیکربندی، کلاینت مسئول تشخیص گفتار کاربر و ارسال پیام های activityStart و activityEnd در زمان های مناسب است. یک audioStreamEnd در این پیکربندی ارسال نشده است. در عوض، هرگونه وقفه در جریان با یک پیام activityEnd مشخص می شود.

پایتون

config = {
    "response_modalities": ["TEXT"],
    "realtime_input_config": {"automatic_activity_detection": {"disabled": True}},
}

async with client.aio.live.connect(model=model, config=config) as session:
    # ...
    await session.send_realtime_input(activity_start=types.ActivityStart())
    await session.send_realtime_input(
        audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
    )
    await session.send_realtime_input(activity_end=types.ActivityEnd())
    # ...

جاوا اسکریپت

const config = {
  responseModalities: [Modality.TEXT],
  realtimeInputConfig: {
    automaticActivityDetection: {
      disabled: true,
    }
  }
};

session.sendRealtimeInput({ activityStart: {} })

session.sendRealtimeInput(
  {
    audio: {
      data: base64Audio,
      mimeType: "audio/pcm;rate=16000"
    }
  }

);

session.sendRealtimeInput({ activityEnd: {} })

شمارش توکن

می توانید تعداد کل نشانه های مصرف شده را در قسمت usageMetadata پیام سرور برگشتی پیدا کنید.

پایتون

async for message in session.receive():
    # The server will periodically send messages that include UsageMetadata.
    if message.usage_metadata:
        usage = message.usage_metadata
        print(
            f"Used {usage.total_token_count} tokens in total. Response token breakdown:"
        )
        for detail in usage.response_tokens_details:
            match detail:
                case types.ModalityTokenCount(modality=modality, token_count=count):
                    print(f"{modality}: {count}")

جاوا اسکریپت

const turns = await handleTurn();

for (const turn of turns) {
  if (turn.usageMetadata) {
    console.debug('Used %s tokens in total. Response token breakdown:\n', turn.usageMetadata.totalTokenCount);

    for (const detail of turn.usageMetadata.responseTokensDetails) {
      console.debug('%s\n', detail);
    }
  }
}

وضوح رسانه

می توانید با تنظیم فیلد mediaResolution به عنوان بخشی از پیکربندی جلسه، وضوح رسانه را برای رسانه ورودی مشخص کنید:

پایتون

from google.genai import types

config = {
    "response_modalities": ["AUDIO"],
    "media_resolution": types.MediaResolution.MEDIA_RESOLUTION_LOW,
}

جاوا اسکریپت

import { GoogleGenAI, Modality, MediaResolution } from '@google/genai';

const config = {
    responseModalities: [Modality.TEXT],
    mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};

محدودیت ها

هنگام برنامه ریزی پروژه خود، محدودیت های زیر را برای Live API در نظر بگیرید.

روش های پاسخگویی

در پیکربندی جلسه فقط می توانید یک حالت پاسخ ( TEXT یا AUDIO ) را در هر جلسه تنظیم کنید. تنظیم هر دو منجر به یک پیام خطای پیکربندی می شود. این بدان معناست که می‌توانید مدل را طوری پیکربندی کنید که با متن یا صدا پاسخ دهد، اما نه هر دو در یک جلسه.

احراز هویت مشتری

Live API فقط احراز هویت سرور به سرور را به طور پیش فرض ارائه می دهد. اگر برنامه Live API خود را با استفاده از رویکرد مشتری به سرور پیاده‌سازی می‌کنید، باید از نشانه‌های زودگذر برای کاهش خطرات امنیتی استفاده کنید.

مدت زمان جلسه

جلسات فقط صوتی به 15 دقیقه و جلسات صوتی به علاوه ویدیو محدود به 2 دقیقه است. با این حال، می‌توانید تکنیک‌های مختلف مدیریت جلسه را برای برنامه‌های افزودنی نامحدود در مدت جلسه پیکربندی کنید.

پنجره زمینه

یک جلسه دارای محدودیت پنجره زمینه است:

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

Live API از زبان های زیر پشتیبانی می کند.

زبان کد BCP-47 زبان کد BCP-47
آلمانی (آلمان) de-DE انگلیسی (استرالیا)* en-AU
انگلیسی (بریتانیا)* en-GB انگلیسی (هند) en-IN
انگلیسی (ایالات متحده) en-US اسپانیایی (ایالات متحده) es-US
فرانسوی (فرانسه) fr-FR هندی (هند) hi-IN
پرتغالی (برزیل) pt-BR عربی (عمومی) ar-XA
اسپانیایی (اسپانیا)* es-ES فرانسوی (کانادا)* fr-CA
اندونزیایی (اندونزی) id-ID ایتالیایی (ایتالیا) it-IT
ژاپنی (ژاپن) ja-JP ترکی (ترکیه) tr-TR
ویتنامی (ویتنام) vi-VN بنگالی (هند) bn-IN
گجراتی (هند)* gu-IN کانادا (هند)* kn-IN
مراتی (هند) mr-IN مالایالام (هند)* ml-IN
تامیل (هند) ta-IN تلوگو (هند) te-IN
هلندی (هلند) nl-NL کره ای (کره جنوبی) ko-KR
چینی ماندارین (چین)* cmn-CN لهستانی (لهستان) pl-PL
روسی (روسیه) ru-RU تایلندی (تایلند) th-TH

زبان‌های علامت‌گذاری شده با ستاره (*) برای صدای بومی در دسترس نیستند .

بعدش چی