Live API

লাইভ এপিআই মিথুনের সাথে কম লেটেন্সি দ্বিমুখী ভয়েস এবং ভিডিও ইন্টারঅ্যাকশন সক্ষম করে, আপনাকে ভিডিও ইনপুট স্ট্রিমিং বা আপনার স্ক্রিন ভাগ করার সময় জেমিনীর সাথে লাইভ কথা বলতে দেয়। লাইভ API ব্যবহার করে, আপনি শেষ ব্যবহারকারীদের প্রাকৃতিক, মানুষের মতো ভয়েস কথোপকথনের অভিজ্ঞতা প্রদান করতে পারেন।

আপনি Google AI স্টুডিওতে লাইভ API ব্যবহার করে দেখতে পারেন। Google AI স্টুডিওতে লাইভ API ব্যবহার করতে, স্ট্রিম নির্বাচন করুন।

কিভাবে লাইভ API কাজ করে

স্ট্রিমিং

লাইভ API একটি WebSocket সংযোগের মাধ্যমে একটি স্ট্রিমিং মডেল ব্যবহার করে। আপনি যখন API এর সাথে ইন্টারঅ্যাক্ট করেন, তখন একটি স্থায়ী সংযোগ তৈরি হয়। আপনার ইনপুট (অডিও, ভিডিও বা টেক্সট) মডেলে ক্রমাগত স্ট্রিম করা হয় এবং মডেলের প্রতিক্রিয়া (টেক্সট বা অডিও) একই সংযোগের মাধ্যমে রিয়েল-টাইমে স্ট্রিম করা হয়।

এই দ্বিমুখী স্ট্রিমিং কম লেটেন্সি নিশ্চিত করে এবং ভয়েস অ্যাক্টিভিটি সনাক্তকরণ, টুল ব্যবহার এবং বক্তৃতা তৈরির মতো বৈশিষ্ট্যগুলিকে সমর্থন করে।

লাইভ API ওভারভিউ

অন্তর্নিহিত WebSockets API সম্পর্কে আরও তথ্যের জন্য, WebSockets API রেফারেন্স দেখুন।

আউটপুট প্রজন্ম

লাইভ এপিআই রিয়েল-টাইমে পাঠ্য বা অডিও তৈরি করতে মাল্টিমডাল ইনপুট (টেক্সট, অডিও, ভিডিও) প্রক্রিয়া করে। এটি অডিও তৈরি করার জন্য একটি অন্তর্নির্মিত পদ্ধতির সাথে আসে এবং আপনি যে মডেল সংস্করণটি ব্যবহার করেন তার উপর নির্ভর করে, এটি দুটি অডিও প্রজন্মের পদ্ধতির একটি ব্যবহার করে:

  • হাফ ক্যাসকেড : মডেলটি নেটিভ অডিও ইনপুট গ্রহণ করে এবং ইনপুট প্রক্রিয়া করতে এবং অডিও আউটপুট তৈরি করতে স্বতন্ত্র মডেলের একটি বিশেষ মডেল ক্যাসকেড ব্যবহার করে।
  • নেটিভ : জেমিনি 2.5 নেটিভ অডিও জেনারেশনের সাথে পরিচয় করিয়ে দেয়, যা সরাসরি অডিও আউটপুট তৈরি করে, আরও স্বাভাবিক শব্দযুক্ত অডিও, আরও অভিব্যক্তিপূর্ণ কণ্ঠস্বর, অতিরিক্ত প্রসঙ্গ সম্পর্কে আরও সচেতনতা, যেমন, টোন এবং আরও সক্রিয় প্রতিক্রিয়া প্রদান করে।

লাইভ API সহ বিল্ডিং

আপনি লাইভ এপিআই দিয়ে নির্মাণ শুরু করার আগে, আপনার প্রয়োজনের সাথে মানানসই অডিও জেনারেশন পদ্ধতি বেছে নিন।

একটি সংযোগ স্থাপন

নিম্নলিখিত উদাহরণ দেখায় কিভাবে একটি API কী দিয়ে একটি সংযোগ তৈরি করতে হয়:

import asyncio
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")

model = "gemini-2.0-flash-live-001"
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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();

টেক্সট পাঠানো এবং গ্রহণ

আপনি কীভাবে পাঠ্য পাঠাতে এবং গ্রহণ করতে পারেন তা এখানে:

import asyncio
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();

পাঠানো এবং অডিও গ্রহণ

আপনি এটিকে 16-বিট PCM, 16kHz, মনো ফরম্যাটে রূপান্তর করে অডিও পাঠাতে পারেন। এই উদাহরণটি একটি 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();

অডিও ফরম্যাট

লাইভ API-এ অডিও ডেটা সবসময় কাঁচা, সামান্য-এন্ডিয়ান, 16-বিট পিসিএম। অডিও আউটপুট সর্বদা 24kHz নমুনা হার ব্যবহার করে। ইনপুট অডিও নেটিভভাবে 16kHz, কিন্তু প্রয়োজন হলে লাইভ API পুনরায় নমুনা তৈরি করবে যাতে যেকোন নমুনা হার পাঠানো যায়। ইনপুট অডিওর নমুনা হার জানাতে, প্রতিটি অডিও-ধারণকারী ব্লবের MIME প্রকারকে audio/pcm;rate=16000 এর মতো একটি মান সেট করুন।

অডিও ট্রান্সক্রিপশন গ্রহণ করা হচ্ছে

আপনি সেটআপ কনফিগারেশনে output_audio_transcription পাঠিয়ে মডেলের অডিও আউটপুটের ট্রান্সক্রিপশন সক্ষম করতে পারেন। প্রতিলিপি ভাষা মডেলের প্রতিক্রিয়া থেকে অনুমান করা হয়.

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

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

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

অডিও এবং ভিডিও স্ট্রিমিং

সিস্টেম নির্দেশাবলী

সিস্টেম নির্দেশাবলী আপনাকে আপনার নির্দিষ্ট প্রয়োজন এবং ব্যবহারের ক্ষেত্রের উপর ভিত্তি করে একটি মডেলের আচরণ পরিচালনা করতে দেয়। সিস্টেম নির্দেশাবলী সেটআপ কনফিগারেশনে সেট করা যেতে পারে এবং পুরো সেশনের জন্য কার্যকর থাকবে।

config = {
    "system_instruction": "You are a helpful assistant and answer in a friendly tone.",
    "response_modalities": ["TEXT"],
}
const config = {
  responseModalities: [Modality.TEXT],
  systemInstruction: "You are a helpful assistant and answer in a friendly tone."
};

ইনক্রিমেন্টাল কন্টেন্ট আপডেট

টেক্সট ইনপুট পাঠাতে, সেশন প্রসঙ্গ স্থাপন বা সেশন প্রসঙ্গ পুনরুদ্ধার করতে ক্রমবর্ধমান আপডেট ব্যবহার করুন। সংক্ষিপ্ত প্রসঙ্গের জন্য আপনি ঘটনার সঠিক ক্রম উপস্থাপন করতে পালাক্রমে মিথস্ক্রিয়া পাঠাতে পারেন:

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

দীর্ঘ প্রসঙ্গগুলির জন্য পরবর্তী মিথস্ক্রিয়াগুলির জন্য প্রসঙ্গ উইন্ডোটি মুক্ত করতে একটি একক বার্তা সারাংশ প্রদান করার পরামর্শ দেওয়া হয়।

ভয়েস এবং ভাষা পরিবর্তন

লাইভ এপিআই নিম্নলিখিত ভয়েসগুলিকে সমর্থন করে: পাক, চ্যারন, কোর, ফেনরির, এওডি, লেডা, ওরাস এবং জেফির।

একটি ভয়েস নির্দিষ্ট করতে, সেশন কনফিগারেশনের অংশ হিসাবে 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" } } }
};

লাইভ API একাধিক ভাষা সমর্থন করে।

ভাষা পরিবর্তন করতে, সেশন কনফিগারেশনের অংশ হিসাবে speechConfig অবজেক্টের মধ্যে ভাষা কোড সেট করুন:

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

নেটিভ অডিও আউটপুট

লাইভ API-এর মাধ্যমে, আপনি এমন মডেলগুলিও অ্যাক্সেস করতে পারেন যা নেটিভ অডিও ইনপুট ছাড়াও নেটিভ অডিও আউটপুটের অনুমতি দেয়। এটি আরও ভাল পেসিং, ভয়েস স্বাভাবিকতা, শব্দচয়ন এবং মেজাজ সহ উচ্চ মানের অডিও আউটপুটগুলির জন্য অনুমতি দেয়।

নেটিভ অডিও আউটপুট নিম্নলিখিত নেটিভ অডিও মডেল দ্বারা সমর্থিত:

  • gemini-2.5-flash-preview-native-audio-dialog
  • gemini-2.5-flash-exp-native-audio-thinking-dialog

কিভাবে নেটিভ অডিও আউটপুট ব্যবহার করবেন

নেটিভ অডিও আউটপুট ব্যবহার করতে, একটি নেটিভ অডিও মডেল কনফিগার করুন এবং AUDIO তে response_modalities সেট করুন।

একটি সম্পূর্ণ উদাহরণের জন্য অডিও পাঠানো এবং গ্রহণ করা দেখুন।

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

কার্যকরী সংলাপ

এই বৈশিষ্ট্যটি জেমিনিকে তার প্রতিক্রিয়া শৈলীকে ইনপুট অভিব্যক্তি এবং টোনের সাথে মানিয়ে নিতে দেয়৷

ইফেক্টিভ ডায়ালগ ব্যবহার করতে, এপিআই সংস্করণটিকে v1alpha এ সেট করুন এবং সেটআপ বার্তায় enable_affective_dialog কে true সেট করুন:

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

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    enable_affective_dialog=True
)
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY", httpOptions: {"apiVersion": "v1alpha"} });

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

মনে রাখবেন যে ইফেক্টিভ ডায়ালগ বর্তমানে শুধুমাত্র নেটিভ অডিও আউটপুট মডেল দ্বারা সমর্থিত।

সক্রিয় অডিও

যখন এই বৈশিষ্ট্যটি সক্ষম করা থাকে, তখন বিষয়বস্তু প্রাসঙ্গিক না হলে জেমিনি সক্রিয়ভাবে প্রতিক্রিয়া না দেওয়ার সিদ্ধান্ত নিতে পারে।

এটি ব্যবহার করতে, এপিআই সংস্করণটিকে v1alpha এ সেট করুন এবং সেটআপ বার্তায় proactivity ক্ষেত্রটি কনফিগার করুন এবং proactive_audio কে true সেট করুন:

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

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    proactivity={'proactive_audio': True}
)
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY", 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();

লাইভ API এর সাথে টুল ব্যবহার

আপনি লাইভ API এর সাথে ফাংশন কলিং , কোড এক্সিকিউশন এবং Google অনুসন্ধানের মতো সরঞ্জামগুলি সংজ্ঞায়িত করতে পারেন।

সমর্থিত টুলের ওভারভিউ

এখানে প্রতিটি মডেলের জন্য উপলব্ধ সরঞ্জামগুলির একটি সংক্ষিপ্ত বিবরণ রয়েছে:

টুল ক্যাসকেড মডেল
gemini-2.0-flash-live-001
gemini-2.5-flash-preview-native-audio-dialog gemini-2.5-flash-exp-native-audio-thinking-dialog
অনুসন্ধান করুন হ্যাঁ হ্যাঁ হ্যাঁ
ফাংশন কলিং হ্যাঁ হ্যাঁ না
কোড এক্সিকিউশন হ্যাঁ না না
ইউআরএল প্রসঙ্গ হ্যাঁ না না

ফাংশন কলিং

আপনি সেশন কনফিগারেশনের অংশ হিসাবে ফাংশন ঘোষণা সংজ্ঞায়িত করতে পারেন। আরও জানতে ফাংশন কলিং টিউটোরিয়াল দেখুন।

টুল কল পাওয়ার পর, ক্লায়েন্টকে session.send_tool_response পদ্ধতি ব্যবহার করে FunctionResponse অবজেক্টের একটি তালিকা দিয়ে সাড়া দেওয়া উচিত।

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

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

# Simple function definitions
turn_on_the_lights = {"name": "turn_on_the_lights"}
turn_off_the_lights = {"name": "turn_off_the_lights"}

tools = [{"function_declarations": [turn_on_the_lights, turn_off_the_lights]}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "Turn on the lights please"
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

        async for chunk in session.receive():
            if chunk.server_content:
                if chunk.text is not None:
                    print(chunk.text)
            elif chunk.tool_call:
                function_responses = []
                for fc in chunk.tool_call.function_calls:
                    function_response = types.FunctionResponse(
                        id=fc.id,
                        name=fc.name,
                        response={ "result": "ok" } # simple, hard-coded function response
                    )
                    function_responses.append(function_response)

                await session.send_tool_response(function_responses=function_responses)

if __name__ == "__main__":
    asyncio.run(main())
import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

// Simple function definitions
const turn_on_the_lights = { name: "turn_on_the_lights" } // , description: '...', parameters: { ... }
const turn_off_the_lights = { name: "turn_off_the_lights" }

const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]

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

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;
      } else if (message.toolCall) {
        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 = 'Turn on the lights please';
  session.sendClientContent({ turns: inputTurns });

  let turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
      }
    }
    else if (turn.toolCall) {
      const functionResponses = [];
      for (const fc of turn.toolCall.functionCalls) {
        functionResponses.push({
          id: fc.id,
          name: fc.name,
          response: { result: "ok" } // simple, hard-coded function response
        });
      }

      console.debug('Sending tool response...\n');
      session.sendToolResponse({ functionResponses: functionResponses });
    }
  }

  // Check again for new messages
  turns = await handleTurn();

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

  session.close();
}

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

main();

একটি একক প্রম্পট থেকে, মডেলটি একাধিক ফাংশন কল এবং তাদের আউটপুট চেইন করার জন্য প্রয়োজনীয় কোড তৈরি করতে পারে। এই কোডটি একটি স্যান্ডবক্স পরিবেশে কার্যকর করে, পরবর্তী BidiGenerateContentToolCall বার্তা তৈরি করে।

অ্যাসিঙ্ক্রোনাস ফাংশন কলিং

ডিফল্টরূপে, প্রতিটি ফাংশন কলের ফলাফল উপলব্ধ না হওয়া পর্যন্ত এক্সিকিউশন বিরতি দেয়, যা ক্রমিক প্রক্রিয়াকরণ নিশ্চিত করে। এর মানে হল যে ফাংশনগুলি চালানোর সময় আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করা চালিয়ে যেতে পারবেন না।

আপনি যদি কথোপকথনটি ব্লক করতে না চান তবে আপনি মডেলটিকে অ্যাসিঙ্ক্রোনাসভাবে ফাংশনগুলি চালানোর জন্য বলতে পারেন৷

এটি করার জন্য, আপনাকে প্রথমে ফাংশন সংজ্ঞাগুলিতে একটি behavior যুক্ত করতে হবে:

  # Non-blocking function definitions
  turn_on_the_lights = {"name": "turn_on_the_lights", "behavior": "NON_BLOCKING"} # turn_on_the_lights will run asynchronously
  turn_off_the_lights = {"name": "turn_off_the_lights"} # turn_off_the_lights will still pause all interactions with the model
import { GoogleGenAI, Modality, Behavior } from '@google/genai';

// Non-blocking function definitions
const turn_on_the_lights = {name: "turn_on_the_lights", behavior: Behavior.NON_BLOCKING}

// Blocking function definitions
const turn_off_the_lights = {name: "turn_off_the_lights"}

const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]

NON-BLOCKING নিশ্চিত করবে যে ফাংশনটি অ্যাসিঙ্ক্রোনাসভাবে চলবে যখন আপনি মডেলের সাথে ইন্টারঅ্যাক্ট করা চালিয়ে যেতে পারেন।

তারপরে আপনাকে মডেলটিকে বলতে হবে কিভাবে আচরণ করতে হবে যখন এটি scheduling পরামিতি ব্যবহার করে FunctionResponse পায়। এটি হতে পারে:

  • এটি যা করছে তাতে বাধা দিন এবং এটির প্রতিক্রিয়া সম্পর্কে আপনাকে বলুন ( scheduling="INTERRUPT" ),
  • এটি বর্তমানে যা করছে তা শেষ না হওয়া পর্যন্ত অপেক্ষা করুন ( scheduling="WHEN_IDLE" ),
  • অথবা কিছুই করবেন না এবং সেই জ্ঞানটি পরে আলোচনায় ব্যবহার করুন ( scheduling="SILENT" )

# for a non-blocking function definition, apply scheduling in the function response:
  function_response = types.FunctionResponse(
      id=fc.id,
      name=fc.name,
      response={
          "result": "ok",
          "scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
      }
  )
import { GoogleGenAI, Modality, Behavior, FunctionResponseScheduling } from '@google/genai';

// for a non-blocking function definition, apply scheduling in the function response:
const functionResponse = {
  id: fc.id,
  name: fc.name,
  response: {
    result: "ok",
    scheduling: FunctionResponseScheduling.INTERRUPT  // Can also be WHEN_IDLE or SILENT
  }
}

কোড এক্সিকিউশন

আপনি সেশন কনফিগারেশনের অংশ হিসাবে কোড এক্সিকিউশন সংজ্ঞায়িত করতে পারেন। আরও জানতে কোড এক্সিকিউশন টিউটোরিয়াল দেখুন।

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

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

tools = [{'code_execution': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "Compute the largest prime palindrome under 100000."
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

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

                model_turn = chunk.server_content.model_turn
                if model_turn:
                    for part in model_turn.parts:
                      if part.executable_code is not None:
                        print(part.executable_code.code)

                      if part.code_execution_result is not None:
                        print(part.code_execution_result.output)

if __name__ == "__main__":
    asyncio.run(main())
import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

const tools = [{codeExecution: {}}]
const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

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;
      } else if (message.toolCall) {
        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 = 'Compute the largest prime palindrome under 100000.';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
        else if (part.executableCode) {
          console.debug('executableCode: %s\n', part.executableCode.code);
        }
        else if (part.codeExecutionResult) {
          console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
        }
      }
    }
  }

  session.close();
}

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

main();

আপনি সেশন কনফিগারেশনের অংশ হিসাবে Google অনুসন্ধানের সাথে গ্রাউন্ডিং সক্ষম করতে পারেন। আরও জানতে গ্রাউন্ডিং টিউটোরিয়াল দেখুন।

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

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

tools = [{'google_search': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "When did the last Brazil vs. Argentina soccer match happen?"
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

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

                # The model might generate and execute Python code to use Search
                model_turn = chunk.server_content.model_turn
                if model_turn:
                    for part in model_turn.parts:
                      if part.executable_code is not None:
                        print(part.executable_code.code)

                      if part.code_execution_result is not None:
                        print(part.code_execution_result.output)

if __name__ == "__main__":
    asyncio.run(main())
import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

const tools = [{googleSearch: {}}]
const config = {
  responseModalities: [Modality.TEXT],
  tools: tools
}

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;
      } else if (message.toolCall) {
        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 = 'When did the last Brazil vs. Argentina soccer match happen?';
  session.sendClientContent({ turns: inputTurns });

  const turns = await handleTurn();

  for (const turn of turns) {
    if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
      for (const part of turn.serverContent.modelTurn.parts) {
        if (part.text) {
          console.debug('Received text: %s\n', part.text);
        }
        else if (part.executableCode) {
          console.debug('executableCode: %s\n', part.executableCode.code);
        }
        else if (part.codeExecutionResult) {
          console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
        }
      }
    }
  }

  session.close();
}

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

main();

একাধিক টুল একত্রিত করা

আপনি লাইভ API-এর মধ্যে একাধিক টুল একত্রিত করতে পারেন:

prompt = """
Hey, I need you to do three things for me.

1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights

Thanks!
"""

tools = [
    {"google_search": {}},
    {"code_execution": {}},
    {"function_declarations": [turn_on_the_lights, turn_off_the_lights]},
]

config = {"response_modalities": ["TEXT"], "tools": tools}
const prompt = `Hey, I need you to do three things for me.

1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights

Thanks!
`

const tools = [
  { googleSearch: {} },
  { codeExecution: {} },
  { functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }
]

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

হ্যান্ডলিং বাধা

ব্যবহারকারীরা যে কোনো সময় মডেলের আউটপুট ব্যাহত করতে পারেন. যখন ভয়েস অ্যাক্টিভিটি ডিটেকশন (VAD) কোনো বাধা শনাক্ত করে, তখন চলমান জেনারেশন বাতিল করা হয় এবং বাতিল করা হয়। শুধুমাত্র ক্লায়েন্টকে ইতিমধ্যে পাঠানো তথ্য সেশন ইতিহাসে রাখা হয়। সার্ভার তখন বিডিজেনারেট কনটেন্টসার্ভার কনটেন্ট বার্তা পাঠায় বিঘ্নের রিপোর্ট করতে।

এছাড়াও, জেমিনি সার্ভার কোনো মুলতুবি থাকা ফাংশন কল বাতিল করে এবং বাতিল করা কলগুলির আইডি সহ একটি BidiGenerateContentServerContent বার্তা পাঠায়।

async for response in session.receive():
    if response.server_content.interrupted is True:
        # The generation was interrupted
const turns = await handleTurn();

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

ভয়েস কার্যকলাপ সনাক্তকরণ (VAD)

আপনি ভয়েস কার্যকলাপ সনাক্তকরণ (VAD) কনফিগার বা অক্ষম করতে পারেন।

স্বয়ংক্রিয় 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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 অক্ষম করা হচ্ছে

বিকল্পভাবে, সেটআপ মেসেজে realtimeInputConfig.automaticActivityDetection.disabled সেট করে স্বয়ংক্রিয় VAD অক্ষম করা যেতে পারে 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: {} })

টোকেন গণনা

প্রত্যাবর্তিত সার্ভার বার্তার মেটাডেটা ক্ষেত্রে আপনি মোট ভোক্ত টোকেনের সংখ্যা খুঁজে পেতে পারেন।

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

অধিবেশনের মেয়াদ বাড়ানো হচ্ছে

সর্বাধিক সেশনের সময়কাল দুটি প্রক্রিয়ার সাথে সীমাহীন পর্যন্ত বাড়ানো যেতে পারে:

উপরন্তু, সেশন শেষ হওয়ার আগে আপনি একটি GoAway বার্তা পাবেন, যা আপনাকে আরও পদক্ষেপ নিতে অনুমতি দেবে।

প্রসঙ্গ উইন্ডো কম্প্রেশন

দীর্ঘতর সেশনগুলি সক্ষম করতে এবং আকস্মিক সংযোগ বন্ধ হওয়া এড়াতে, আপনি সেশন কনফিগারেশনের অংশ হিসাবে প্রসঙ্গ উইন্ডো কম্প্রেশন ক্ষেত্র সেট করে প্রসঙ্গ উইন্ডো কম্প্রেশন সক্ষম করতে পারেন।

ContextWindowCompressionConfig- এ, আপনি একটি স্লাইডিং-উইন্ডো মেকানিজম এবং কম্প্রেশন ট্রিগার করে এমন টোকেনের সংখ্যা কনফিগার করতে পারেন।

from google.genai import types

config = {
    "response_modalities": ["AUDIO"],
    "context_window_compression": (
        # Configures compression with default parameters.
        types.ContextWindowCompressionConfig(
            sliding_window=types.SlidingWindow(),
        )
    ),
}
const config = {
  responseModalities: [Modality.AUDIO],
  contextWindowCompression: { slidingWindow: {} }
};

অধিবেশন পুনঃসূচনা

সার্ভার যখন পর্যায়ক্রমে WebSocket সংযোগ পুনরায় সেট করে তখন সেশন সমাপ্তি প্রতিরোধ করতে, সেটআপ কনফিগারেশনের মধ্যে সেশন রিজাম্পশন ক্ষেত্রটি কনফিগার করুন।

এই কনফিগারেশনটি পাস করার ফলে সার্ভারটি SessionResumptionUpdate বার্তা পাঠাতে পারে, যা পরবর্তী সংযোগের SessionResumptionConfig.handle হিসাবে শেষ পুনঃসূচনা টোকেনটি পাস করে সেশন পুনরায় শুরু করতে ব্যবহার করা যেতে পারে।

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

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

async def main():
    print(f"Connecting to the service with handle {previous_session_handle}...")
    async with client.aio.live.connect(
        model=model,
        config=types.LiveConnectConfig(
            response_modalities=["AUDIO"],
            session_resumption=types.SessionResumptionConfig(
                # The handle of the session to resume is passed here,
                # or else None to start a new session.
                handle=previous_session_handle
            ),
        ),
    ) as session:
        while True:
            await session.send_client_content(
                turns=types.Content(
                    role="user", parts=[types.Part(text="Hello world!")]
                )
            )
            async for message in session.receive():
                if message.session_resumption_update:
                    update = message.session_resumption_update
                    if update.resumable and update.new_handle:
                        newHandle = update.new_handle
                        # TODO: store newHandle and start new session with this handle
                        # ...

if __name__ == "__main__":
    asyncio.run(main())
import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';

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

  console.debug('Connecting to the service with handle %s...', previousSessionHandle)
  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: {
      responseModalities: [Modality.TEXT],
      sessionResumption: { handle: previousSessionHandle }
      // The handle of the session to resume is passed here, or else null to start a new session.
    }
  });

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

  const turns = await handleTurn();
  for (const turn of turns) {
    if (turn.sessionResumptionUpdate) {
      if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {
        let newHandle = turn.sessionResumptionUpdate.newHandle
        // TODO: store newHandle and start new session with this handle
        // ...
      }
    }
  }

  session.close();
}

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

main();

সেশন সংযোগ বিচ্ছিন্ন হওয়ার আগে একটি বার্তা গ্রহণ করা হচ্ছে

সার্ভার একটি GoAway বার্তা পাঠায় যা সংকেত দেয় যে বর্তমান সংযোগটি শীঘ্রই বন্ধ হয়ে যাবে। এই বার্তাটিতে টাইমলেফ্ট অন্তর্ভুক্ত রয়েছে, বাকি সময় নির্দেশ করে এবং সংযোগটি বন্ধ হয়ে যাওয়ার আগে আপনাকে আরও পদক্ষেপ নিতে দেয়।

async for response in session.receive():
    if response.go_away is not None:
        # The connection will soon be terminated
        print(response.go_away.time_left)
const turns = await handleTurn();

for (const turn of turns) {
  if (turn.goAway) {
    console.debug('Time left: %s\n', turn.goAway.timeLeft);
  }
}

প্রজন্ম সম্পূর্ণ হলে একটি বার্তা গ্রহণ করা

সার্ভার একটি জেনারেশন কমপ্লিট মেসেজ পাঠায় যা ইঙ্গিত দেয় যে মডেলটি প্রতিক্রিয়া তৈরি করা শেষ করেছে।

async for response in session.receive():
    if response.server_content.generation_complete is True:
        # The generation is complete
const turns = await handleTurn();

for (const turn of turns) {
  if (turn.serverContent && turn.serverContent.generationComplete) {
    // The generation is complete
  }
}

মিডিয়া রেজোলিউশন

আপনি সেশন কনফিগারেশনের অংশ হিসাবে 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,
};

সীমাবদ্ধতা

আপনি যখন আপনার প্রকল্পের পরিকল্পনা করেন তখন লাইভ API-এর নিম্নলিখিত সীমাবদ্ধতাগুলি বিবেচনা করুন৷

প্রতিক্রিয়া পদ্ধতি

আপনি সেশন কনফিগারেশনে প্রতি সেশনে শুধুমাত্র একটি রেসপন্স মোডালিটি ( TEXT বা AUDIO ) সেট করতে পারেন। একটি কনফিগার ত্রুটি বার্তা উভয় ফলাফল সেট. এর মানে হল যে আপনি টেক্সট বা অডিওর সাথে সাড়া দেওয়ার জন্য মডেলটি কনফিগার করতে পারেন, কিন্তু একই সেশনে উভয়ই নয়।

ক্লায়েন্ট প্রমাণীকরণ

লাইভ API শুধুমাত্র সার্ভারকে সার্ভার প্রমাণীকরণ প্রদান করে এবং সরাসরি ক্লায়েন্ট ব্যবহারের জন্য সুপারিশ করা হয় না। লাইভ API-এর সাথে নিরাপদ প্রমাণীকরণের জন্য ক্লায়েন্ট ইনপুট একটি মধ্যবর্তী অ্যাপ্লিকেশন সার্ভারের মাধ্যমে রুট করা উচিত।

সেশনের সময়কাল

সেশন কম্প্রেশন সক্ষম করে সেশনের সময়সীমা সীমাহীন পর্যন্ত বাড়ানো যেতে পারে। কম্প্রেশন ছাড়া, শুধুমাত্র অডিও সেশন 15 মিনিটের মধ্যে সীমাবদ্ধ, এবং অডিও প্লাস ভিডিও সেশন 2 মিনিটের মধ্যে সীমাবদ্ধ। কম্প্রেশন ছাড়াই এই সীমা অতিক্রম করলে সংযোগটি বন্ধ হয়ে যাবে।

অতিরিক্তভাবে, আপনি ক্লায়েন্টকে বন্ধ করা সেশন পুনরায় শুরু করার অনুমতি দেওয়ার জন্য সেশন পুনঃসূচনা কনফিগার করতে পারেন।

প্রসঙ্গ উইন্ডো

একটি সেশনের একটি প্রসঙ্গ উইন্ডো সীমা রয়েছে:

সমর্থিত ভাষা

লাইভ API নিম্নলিখিত ভাষা সমর্থন করে।

ভাষা BCP-47 কোড
জার্মান (জার্মানি) ডি-ডিই
ইংরেজি (অস্ট্রেলিয়া) en-AU
ইংরেজি (যুক্তরাজ্য) en-GB
ইংরেজি (ভারত) en-IN
ইংরেজি (মার্কিন) en-US
স্প্যানিশ (মার্কিন যুক্তরাষ্ট্র) es-মার্কিন
ফরাসি (ফ্রান্স) fr-FR
হিন্দি (ভারত) হাই-ইন
পর্তুগিজ (ব্রাজিল) pt-BR
আরবি (জেনারিক) ar-XA
স্প্যানিশ (স্পেন) es-ES
ফরাসি (কানাডা) fr-CA
ইন্দোনেশিয়া (ইন্দোনেশিয়া) আইডি-আইডি
ইতালীয় (ইতালি) এটা-আইটি
জাপানিজ (জাপান) ja-জেপি
তুর্কি (তুরস্ক) tr-TR
ভিয়েতনামী (ভিয়েতনাম) vi-VN
বাংলা (ভারত) bn-IN
গুজরাটি (ভারত) gu-IN
কন্নড় (ভারত) kn-IN
মালায়লাম (ভারত) ml-IN
মারাঠি (ভারত) মিস্টার-আইএন
তামিল (ভারত) ta-IN
তেলেগু (ভারত) te-IN
ডাচ (নেদারল্যান্ডস) nl-NL
কোরিয়ান (দক্ষিণ কোরিয়া) ko-KR
ম্যান্ডারিন চাইনিজ (চীন) cmn-CN
পোলিশ (পোল্যান্ড) pl-PL
রাশিয়ান (রাশিয়া) ru-RU
থাই (থাইল্যান্ড) th-TH

তৃতীয় পক্ষের ইন্টিগ্রেশন

ওয়েব এবং মোবাইল অ্যাপ স্থাপনার জন্য, আপনি এখান থেকে বিকল্পগুলি অন্বেষণ করতে পারেন:

এরপর কি