Get started with Gemini Live API using WebSockets

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

সংক্ষিপ্ত বিবরণ

জেমিনি লাইভ এপিআই রিয়েল-টাইম যোগাযোগের জন্য ওয়েবসকেট ব্যবহার করে। এসডিকে ব্যবহারের বিপরীতে, এই পদ্ধতিতে ওয়েবসকেট সংযোগ সরাসরি পরিচালনা করা এবং এপিআই দ্বারা সংজ্ঞায়িত একটি নির্দিষ্ট JSON ফর্ম্যাটে বার্তা প্রেরণ/গ্রহণ করা জড়িত।

মূল ধারণা:

  • ওয়েবসকেট এন্ডপয়েন্ট : সংযোগ করার জন্য নির্দিষ্ট URL।
  • বার্তা বিন্যাস : সমস্ত যোগাযোগ LiveSessionRequest এবং LiveSessionResponse কাঠামোর সাথে সঙ্গতিপূর্ণ JSON বার্তাগুলির মাধ্যমে করা হয়।
  • সেশন ম্যানেজমেন্ট : ওয়েবসকেট সংযোগ বজায় রাখার জন্য আপনার দায়িত্ব।

প্রমাণীকরণ

ওয়েবসকেট URL-এ আপনার API কীকে একটি কোয়েরি প্যারামিটার হিসেবে অন্তর্ভুক্ত করে প্রমাণীকরণ পরিচালনা করা হয়।

এন্ডপয়েন্ট ফর্ম্যাটটি হল:

wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=YOUR_API_KEY

আপনার আসল API কী দিয়ে YOUR_API_KEY প্রতিস্থাপন করুন।

এফেমেরাল টোকেন দিয়ে প্রমাণীকরণ

যদি আপনি ক্ষণস্থায়ী টোকেন ব্যবহার করেন, তাহলে আপনাকে v1alpha এন্ডপয়েন্টের সাথে সংযোগ করতে হবে। ক্ষণস্থায়ী টোকেনটি একটি access_token কোয়েরি প্যারামিটার হিসেবে পাস করতে হবে।

ক্ষণস্থায়ী কীগুলির জন্য এন্ডপয়েন্ট ফর্ম্যাট হল:

wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContentConstrained?access_token={short-lived-token}

{short-lived-token} আসল ক্ষণস্থায়ী টোকেন দিয়ে প্রতিস্থাপন করুন।

লাইভ API-তে সংযোগ করা হচ্ছে

একটি লাইভ সেশন শুরু করতে, প্রমাণিত এন্ডপয়েন্টের সাথে একটি WebSocket সংযোগ স্থাপন করুন। WebSocket-এর মাধ্যমে প্রেরিত প্রথম বার্তাটি অবশ্যই একটি LiveSessionRequest হতে হবে যাতে config থাকে। সম্পূর্ণ কনফিগারেশন বিকল্পগুলির জন্য, Live API - WebSockets API রেফারেন্স দেখুন।

পাইথন

import asyncio
import websockets
import json

API_KEY = "YOUR_API_KEY"
MODEL_NAME = "gemini-2.5-flash-native-audio-preview-12-2025"
WS_URL = f"wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key={API_KEY}"

async def connect_and_configure():
    async with websockets.connect(WS_URL) as websocket:
        print("WebSocket Connected")

        # 1. Send the initial configuration
        config_message = {
            "config": {
                "model": f"models/{MODEL_NAME}",
                "responseModalities": ["AUDIO"],
                "systemInstruction": {
                    "parts": [{"text": "You are a helpful assistant."}]
                }
            }
        }
        await websocket.send(json.dumps(config_message))
        print("Configuration sent")

        # Keep the session alive for further interactions
        await asyncio.sleep(3600) # Example: keep open for an hour

async def main():
    await connect_and_configure()

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

জাভাস্ক্রিপ্ট

const API_KEY = "YOUR_API_KEY";
const MODEL_NAME = "gemini-2.5-flash-native-audio-preview-12-2025";
const WS_URL = `wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=${API_KEY}`;

const websocket = new WebSocket(WS_URL);

websocket.onopen = () => {
  console.log('WebSocket Connected');

  // 1. Send the initial configuration
  const configMessage = {
    config: {
      model: `models/${MODEL_NAME}`,
      responseModalities: ['AUDIO'],
      systemInstruction: {
        parts: [{ text: 'You are a helpful assistant.' }]
      }
    }
  };
  websocket.send(JSON.stringify(configMessage));
  console.log('Configuration sent');
};

websocket.onmessage = (event) => {
  const response = JSON.parse(event.data);
  console.log('Received:', response);
  // Handle different types of responses here
};

websocket.onerror = (error) => {
  console.error('WebSocket Error:', error);
};

websocket.onclose = () => {
  console.log('WebSocket Closed');
};

টেক্সট পাঠানো হচ্ছে

টেক্সট ইনপুট পাঠাতে, realtimeInput ফিল্ডে টেক্সট ভরাট করে একটি LiveSessionRequest তৈরি করুন।

পাইথন

# Inside the websocket context
async def send_text(websocket, text):
    text_message = {
        "realtimeInput": {
            "text": text
        }
    }
    await websocket.send(json.dumps(text_message))
    print(f"Sent text: {text}")

# Example usage: await send_text(websocket, "Hello, how are you?")

জাভাস্ক্রিপ্ট

function sendTextMessage(text) {
  if (websocket.readyState === WebSocket.OPEN) {
    const textMessage = {
      realtimeInput: {
        text: text
      }
    };
    websocket.send(JSON.stringify(textMessage));
    console.log('Text message sent:', text);
  } else {
    console.warn('WebSocket not open.');
  }
}

// Example usage:
sendTextMessage("Hello, how are you?");

অডিও পাঠানো হচ্ছে

অডিওকে কাঁচা PCM ডেটা হিসেবে পাঠাতে হবে (কাঁচা ১৬-বিট PCM অডিও, ১৬kHz, লিটল-এন্ডিয়ান)। realtimeInput ফিল্ড ব্যবহার করে একটি LiveSessionRequest তৈরি করুন, যাতে অডিও ডেটা সহ একটি Blob থাকে। mimeType অত্যন্ত গুরুত্বপূর্ণ।

পাইথন

# Inside the websocket context
async def send_audio_chunk(websocket, chunk_bytes):
    import base64
    encoded_data = base64.b64encode(chunk_bytes).decode('utf-8')
    audio_message = {
        "realtimeInput": {
            "audio": {
                "data": encoded_data,
                "mimeType": "audio/pcm;rate=16000"
            }
        }
    }
    await websocket.send(json.dumps(audio_message))
    # print("Sent audio chunk") # Avoid excessive logging

# Assuming 'chunk' is your raw PCM audio bytes
# await send_audio_chunk(websocket, chunk)

জাভাস্ক্রিপ্ট

// Assuming 'chunk' is a Buffer of raw PCM audio
function sendAudioChunk(chunk) {
  if (websocket.readyState === WebSocket.OPEN) {
    const audioMessage = {
      realtimeInput: {
        audio: {
          data: chunk.toString('base64'),
          mimeType: 'audio/pcm;rate=16000'
        }
      }
    };
    websocket.send(JSON.stringify(audioMessage));
    // console.log('Sent audio chunk');
  }
}
// Example usage: sendAudioChunk(audioBuffer);

ক্লায়েন্ট ডিভাইস (যেমন ব্রাউজার) থেকে অডিও কীভাবে পাবেন তার একটি উদাহরণের জন্য GitHub- এ এন্ড-টু-এন্ড উদাহরণটি দেখুন।

ভিডিও পাঠানো হচ্ছে

ভিডিও ফ্রেমগুলি পৃথক ছবি (যেমন, JPEG বা PNG) হিসাবে পাঠানো হয়। অডিওর মতো, সঠিক mimeType উল্লেখ করে একটি Blob দিয়ে realtimeInput ব্যবহার করুন।

পাইথন

# Inside the websocket context
async def send_video_frame(websocket, frame_bytes, mime_type="image/jpeg"):
    import base64
    encoded_data = base64.b64encode(frame_bytes).decode('utf-8')
    video_message = {
        "realtimeInput": {
            "video": {
                "data": encoded_data,
                "mimeType": mime_type
            }
        }
    }
    await websocket.send(json.dumps(video_message))
    # print("Sent video frame")

# Assuming 'frame' is your JPEG-encoded image bytes
# await send_video_frame(websocket, frame)

জাভাস্ক্রিপ্ট

// Assuming 'frame' is a Buffer of JPEG-encoded image data
function sendVideoFrame(frame, mimeType = 'image/jpeg') {
  if (websocket.readyState === WebSocket.OPEN) {
    const videoMessage = {
      realtimeInput: {
        video: {
          data: frame.toString('base64'),
          mimeType: mimeType
        }
      }
    };
    websocket.send(JSON.stringify(videoMessage));
    // console.log('Sent video frame');
  }
}
// Example usage: sendVideoFrame(jpegBuffer);

ক্লায়েন্ট ডিভাইস (যেমন ব্রাউজার) থেকে ভিডিওটি কীভাবে পাবেন তার একটি উদাহরণের জন্য GitHub- এ এন্ড-টু-এন্ড উদাহরণটি দেখুন।

প্রতিক্রিয়া গ্রহণ

WebSocket LiveSessionResponse বার্তাগুলি ফেরত পাঠাবে। আপনাকে এই JSON বার্তাগুলি বিশ্লেষণ করতে হবে এবং বিভিন্ন ধরণের সামগ্রী পরিচালনা করতে হবে।

পাইথন

# Inside the websocket context, in a receive loop
async def receive_loop(websocket):
    async for message in websocket:
        response = json.loads(message)
        print("Received:", response)

        if "serverContent" in response:
            server_content = response["serverContent"]
            # Receiving Audio
            if "modelTurn" in server_content and "parts" in server_content["modelTurn"]:
                for part in server_content["modelTurn"]["parts"]:
                    if "inlineData" in part:
                        audio_data_b64 = part["inlineData"]["data"]
                        # Process or play the base64 encoded audio data
                        # audio_data = base64.b64decode(audio_data_b64)
                        print(f"Received audio data (base64 len: {len(audio_data_b64)})")

            # Receiving Text Transcriptions
            if "inputTranscription" in server_content:
                print(f"User: {server_content['inputTranscription']['text']}")
            if "outputTranscription" in server_content:
                print(f"Gemini: {server_content['outputTranscription']['text']}")

        # Handling Tool Calls
        if "toolCall" in response:
            await handle_tool_call(websocket, response["toolCall"])

# Example usage: await receive_loop(websocket)

প্রতিক্রিয়া কীভাবে পরিচালনা করবেন তার একটি উদাহরণের জন্য, GitHub- এ এন্ড-টু-এন্ড উদাহরণটি দেখুন।

জাভাস্ক্রিপ্ট

websocket.onmessage = (event) => {
  const response = JSON.parse(event.data);
  console.log('Received:', response);

  if (response.serverContent) {
    const serverContent = response.serverContent;
    // Receiving Audio
    if (serverContent.modelTurn?.parts) {
      for (const part of serverContent.modelTurn.parts) {
        if (part.inlineData) {
          const audioData = part.inlineData.data; // Base64 encoded string
          // Process or play audioData
          console.log(`Received audio data (base64 len: ${audioData.length})`);
        }
      }
    }

    // Receiving Text Transcriptions
    if (serverContent.inputTranscription) {
      console.log('User:', serverContent.inputTranscription.text);
    }
    if (serverContent.outputTranscription) {
      console.log('Gemini:', serverContent.outputTranscription.text);
    }
  }

  // Handling Tool Calls
  if (response.toolCall) {
    handleToolCall(response.toolCall);
  }
};

টুল কল পরিচালনা করা

যখন মডেলটি একটি টুল কলের অনুরোধ করে, তখন LiveSessionResponse এ একটি toolCall ফিল্ড থাকবে। আপনাকে স্থানীয়ভাবে ফাংশনটি কার্যকর করতে হবে এবং toolResponse ফিল্ডের সাথে একটি LiveSessionRequest ব্যবহার করে ফলাফলটি WebSocket-এ ফেরত পাঠাতে হবে।

পাইথন

# Placeholder for your tool function
def my_tool_function(args):
    print(f"Executing tool with args: {args}")
    # Implement your tool logic here
    return {"status": "success", "data": "some result"}

async def handle_tool_call(websocket, tool_call):
    function_responses = []
    for fc in tool_call["functionCalls"]:
        # 1. Execute the function locally
        try:
            result = my_tool_function(fc.get("args", {}))
            response_data = {"result": result}
        except Exception as e:
            print(f"Error executing tool {fc['name']}: {e}")
            response_data = {"error": str(e)}

        # 2. Prepare the response
        function_responses.append({
            "name": fc["name"],
            "id": fc["id"],
            "response": response_data
        })

    # 3. Send the tool response back to the session
    tool_response_message = {
        "toolResponse": {
            "functionResponses": function_responses
        }
    }
    await websocket.send(json.dumps(tool_response_message))
    print("Sent tool response")

# This function is called within the receive_loop when a toolCall is detected.

জাভাস্ক্রিপ্ট

// Placeholder for your tool function
function myToolFunction(args) {
  console.log(`Executing tool with args:`, args);
  // Implement your tool logic here
  return { status: 'success', data: 'some result' };
}

function handleToolCall(toolCall) {
  const functionResponses = [];
  for (const fc of toolCall.functionCalls) {
    // 1. Execute the function locally
    let result;
    try {
      result = myToolFunction(fc.args || {});
    } catch (e) {
      console.error(`Error executing tool ${fc.name}:`, e);
      result = { error: e.message };
    }

    // 2. Prepare the response
    functionResponses.push({
      name: fc.name,
      id: fc.id,
      response: { result }
    });
  }

  // 3. Send the tool response back to the session
  if (websocket.readyState === WebSocket.OPEN) {
    const toolResponseMessage = {
      toolResponse: {
        functionResponses: functionResponses
      }
    };
    websocket.send(JSON.stringify(toolResponseMessage));
    console.log('Sent tool response');
  } else {
    console.warn('WebSocket not open to send tool response.');
  }
}
// This function is called within websocket.onmessage when a toolCall is detected.

এরপর কি?

  • ভয়েস অ্যাক্টিভিটি ডিটেকশন এবং নেটিভ অডিও বৈশিষ্ট্য সহ মূল ক্ষমতা এবং কনফিগারেশনের জন্য সম্পূর্ণ লাইভ এপিআই সক্ষমতা নির্দেশিকাটি পড়ুন।
  • টুল এবং ফাংশন কলিংয়ের সাথে লাইভ API কীভাবে সংহত করতে হয় তা শিখতে টুল ব্যবহারের নির্দেশিকাটি পড়ুন।
  • দীর্ঘমেয়াদী কথোপকথন পরিচালনার জন্য সেশন ব্যবস্থাপনা নির্দেশিকাটি পড়ুন।
  • Read the Ephemeral tokens guide for secure authentication in client-to-server applications.
  • অন্তর্নিহিত WebSockets API সম্পর্কে আরও তথ্যের জন্য, WebSockets API রেফারেন্স দেখুন।