दुनिया ठहरी नहीं है।RSS
BIG CHANGE.

Markdown संस्करण

AI-translated from English; not yet reviewed by a fluent editor.

# OpenAI Realtime से स्थानीय ब्राउज़र में आवाज़ की बातचीत बनाएँ

> WebRTC पर OpenAI Realtime से स्थानीय ब्राउज़र माइक्रोफ़ोन बातचीत बनाएँ। पूरा सर्वर और पेज कोड API कुंजी सर्वर पर रखता है तथा आवाज़ चलना जाँचना, माइक्रोफ़ोन रोकना और विफलता संभालना दिखाता है।

By BIG CHANGE Editorial

Published: 2026-10-19T19:20:34.863Z
Updated: 2026-10-19T19:20:34.863Z
Canonical: https://bigchange.ai/blog/openai-realtime-browser-voice-webrtc-guide

![Conceptual charcoal illustration of a desktop microphone beside a blank browser on a monitor and a small speaker.](https://bigchange.ai/api/media/file/realtime-browser-voice-hero-v1.png)
AI-generated conceptual illustration by BIG CHANGE; no actual OpenAI interface, browser test or heard reply is depicted.

OpenAI का Realtime API ब्राउज़र को WebRTC से माइक्रोफ़ोन आवाज़ भेजने और बोला गया जवाब चलाने देता है। यह गाइड `gpt-realtime-2.1` से एक स्थानीय बातचीत बनाती है। API कुंजी आपके कंप्यूटर के Node सर्वर पर रहती है। मॉडल पहुँच और billing वाला OpenAI API project चाहिए; ChatGPT subscription API उपयोग का भुगतान नहीं करता। BIG CHANGE ने वर्तमान दस्तावेज और नमूना कोड जाँचा, लेकिन भुगतान वाला session नहीं खोला या जवाब नहीं सुना।

## बड़ा बदलाव

- **क्या बदला:** OpenAI ने लाइव Realtime बातचीत के लिए ब्राउज़र WebRTC मार्ग दिया है। स्थानीय सर्वर project कुंजी रखते हुए ब्राउज़र के connection offer के बदले answer लेता है।
- **यह महत्वपूर्ण क्यों है:** डेवलपर बड़ा आवाज़ उत्पाद बनाने से पहले एक स्थानीय पेज में माइक्रोफ़ोन से बोले गए जवाब तक पूरा मार्ग जाँच सकता है। Project मालिक कुंजी नियंत्रित करता और API खर्च देता है।
- **किस बात का ध्यान रखें:** स्थानीय बातचीत चलना production तैयारी का प्रमाण नहीं। साझा सेवा में caller authentication और खर्च नियंत्रण चाहिए; रद्द या timeout अनुरोध पहले ही OpenAI पहुँचा हो सकता है।

## शुरू करने से पहले

Node.js 22.6 या बाद का version और काम करते माइक्रोफ़ोन व speaker वाला वर्तमान ब्राउज़र लें। माइक्रोफ़ोन पहुँच के लिए सुरक्षित context चाहिए; `http://localhost` इस स्थानीय उदाहरण में मान्य है। `gpt-realtime-2.1` access और billing enabled वाला OpenAI API project key लें। पहले rate व spend limits देखें। मॉडल पेज Free tier को असमर्थित बताता है। सामान्य secret manager या स्थानीय shell व्यवस्था से कुंजी server process environment में रखें। इसे `index.html` में न रखें, `.env` फ़ाइल में commit न करें या transcript में न चिपकाएँ। [OpenAI WebRTC गाइड](https://developers.openai.com/api/docs/guides/voice-webrtc) भरोसेमंद सर्वर के आदान-प्रदान का विवरण देती है; [मॉडल पेज](https://developers.openai.com/api/docs/models/gpt-realtime-2.1) वर्तमान पहुँच और मूल्य बताता है।

यह Realtime API का unified `/v1/realtime/calls` route है। WebRTC गाइड `/v1/live/sessions` से GPT-Live भी बताती है, जिसका session protocol अलग है। नीचे route और payload साथ रखें। उदाहरण अपने कंप्यूटर तक सीमित है; स्थानीय Host और Origin जाँच साझा सेवा के उपयोगकर्ताओं का authentication नहीं करती।

1. डेमो के लिए खाली directory बनाएँ और उसी से Express install करें:

```bash
npm init -y
npm install express
```

Installation `package.json` बनाता और web-server dependency जोड़ता है। अगली दो फ़ाइलें उसी directory में रखें। कोड Node के अंतर्निहित `fetch`, `FormData` और `AbortSignal.timeout` इस्तेमाल करता है; जाँची व्यवस्था को Node.js 22.6 या बाद का version चाहिए।

2. इसे `server.mjs` नाम से सहेजें। यह ब्राउज़र का SDP offer (प्रस्तावित WebRTC connection का विवरण) लेकर Realtime session settings के साथ OpenAI भेजता है। मानक API कुंजी केवल इस सर्वर पर पढ़ी जाती है।

```javascript
import express from "express";

const app = express();
// This demo accepts only the local page, including protection against DNS rebinding.
app.use((req, res, next) => {
  const hosts = ["localhost:3000", "127.0.0.1:3000"];
  if (!hosts.includes(req.get("host"))) return res.status(403).send("Local host required");
  if (req.method === "POST" && req.get("origin") !== `http://${req.get("host")}`) {
    return res.status(403).send("Same-origin local page required");
  }
  next();
});
app.use(express.text({ type: "application/sdp", limit: "64kb" }));

app.get("/", (_req, res) => res.sendFile("index.html", { root: process.cwd() }));

app.post("/session", async (req, res) => {
  if (!process.env.OPENAI_API_KEY) return res.status(500).send("Server API key missing");
  if (typeof req.body !== "string" || !req.body.startsWith("v=")) {
    return res.status(400).send("Expected an SDP offer");
  }

  const form = new FormData();
  form.set("sdp", req.body);
  form.set("session", JSON.stringify({
    type: "realtime",
    model: "gpt-realtime-2.1",
    output_modalities: ["audio"],
    audio: { output: { voice: "marin" } },
    instructions: "Be a concise, helpful voice assistant. Do not claim access to external tools."
  }));

  try {
    const upstream = await fetch("https://api.openai.com/v1/realtime/calls", {
      method: "POST",
      headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
      body: form,
      signal: AbortSignal.timeout(25000)
    });
    const answer = await upstream.text();
    if (!upstream.ok) {
      console.error("Realtime session rejected", upstream.status);
      return res.status(502).send(`OpenAI session request failed (${upstream.status})`);
    }
    res.type("application/sdp").send(answer);
  } catch (error) {
    console.error("Realtime session network failure", error.name);
    res.status(502).send("Could not reach the Realtime API");
  }
});

app.listen(3000, "127.0.0.1", () => console.log("Open http://localhost:3000"));
```

सर्वर `127.0.0.1:3000` से bind होता, स्थानीय पेज के host व POST origin ही स्वीकार करता और SDP answer लौटाता है। 25 सेकंड का upstream request limit इस उदाहरण का चुनाव है। Timeout या ब्राउज़र टूटना यह साबित नहीं करता कि OpenAI ने request स्वीकार नहीं की; अनिश्चित शुरुआत दोहराने से पहले उपयोग देखें।

3. इसे `index.html` नाम से सहेजें। पेज **Start voice** के बाद माइक्रोफ़ोन अनुमति माँगता, स्थानीय सर्वर को offer भेजता और आया audio चलाता है। **Stop** connection बंद कर माइक्रोफ़ोन tracks रोकता है, setup के दौरान भी। 30 सेकंड setup timer भी उदाहरण का चुनाव है, API guarantee नहीं।

```html
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Local Realtime voice check</title>
<button id="start">Start voice</button>
<button id="stop" disabled>Stop</button>
<p id="status" role="status">Idle</p>
<audio id="reply" autoplay controls></audio>
<script type="module">
  const start = document.querySelector("#start");
  const stop = document.querySelector("#stop");
  const status = document.querySelector("#status");
  const reply = document.querySelector("#reply");
  let current;

  function closeSession(session = current, message = "Stopped") {
    if (!session) return;
    session.closed = true;
    clearTimeout(session.timer);
    session.abort.abort();
    session.mic?.getTracks().forEach(track => track.stop());
    if (session.pc) session.pc.onconnectionstatechange = null;
    session.dc?.close();
    session.pc?.close();
    if (current === session) {
      current = null;
      reply.srcObject = null;
      start.disabled = false;
      stop.disabled = true;
      status.textContent = message;
    }
  }

  start.onclick = async () => {
    const session = { abort: new AbortController(), closed: false };
    current = session;
    start.disabled = true;
    stop.disabled = false;
    status.textContent = "Requesting microphone";
    session.timer = setTimeout(() => closeSession(session, "Setup timed out; microphone stopped"), 30000);
    try {
      const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
      if (session.closed) { mic.getTracks().forEach(track => track.stop()); return; }
      session.mic = mic;
      const pc = session.pc = new RTCPeerConnection();
      pc.ontrack = event => { if (!session.closed) reply.srcObject = event.streams[0]; };
      pc.onconnectionstatechange = () => {
        if (session.closed) return;
        status.textContent = `Connection: ${pc.connectionState}`;
        if (pc.connectionState === "connected") clearTimeout(session.timer);
        if (["failed", "closed", "disconnected"].includes(pc.connectionState)) {
          closeSession(session, "Connection ended; microphone stopped. Start a new session.");
        }
      };
      pc.addTrack(mic.getAudioTracks()[0], mic);
      const dc = session.dc = pc.createDataChannel("oai-events");
      dc.onmessage = message => {
        if (session.closed) return;
        try {
          const event = JSON.parse(message.data);
          if (event.type === "session.created") status.textContent = "Session ready: speak when connected";
          if (event.type === "response.done") {
            status.textContent = `Response status: ${event.response?.status || "unknown"}; verify audible playback`;
          }
          if (event.type === "error") closeSession(session, `Realtime error: ${event.error?.message || "unknown"}; stopped`);
        } catch { closeSession(session, "Invalid event; stopped"); }
      };
      dc.onclose = () => { if (!session.closed) closeSession(session, "Event channel closed; stopped"); };
      dc.onerror = () => closeSession(session, "Event channel failed; stopped");
      const offer = await pc.createOffer();
      await pc.setLocalDescription(offer);
      if (session.closed) return;
      // The official WebRTC example submits the generated offer directly.
      const response = await fetch("/session", {
        method: "POST",
        headers: { "Content-Type": "application/sdp" },
        body: offer.sdp,
        signal: session.abort.signal
      });
      if (!response.ok) throw new Error(await response.text());
      const answer = await response.text();
      if (session.closed) return;
      await pc.setRemoteDescription({ type: "answer", sdp: answer });
      if (!session.closed && pc.connectionState !== "connected") status.textContent = "Signaling complete; waiting for connection";
    } catch (error) {
      if (!session.closed) closeSession(session, `Start failed: ${error.message}`);
    }
  };
  stop.onclick = () => closeSession();
  window.addEventListener("pagehide", () => closeSession());
</script>
</html>
```

Peer या event-channel विफलता और पेज छोड़ने पर भी ब्राउज़र session बंद करता है। Stop या timeout के बाद अनुमति आ सकती है; देर का track रोक दिया जाता है। Status line `response.done` और उसकी बताई स्थिति दिखाती है। केवल यह event जवाब सुनाई देने या cancelled/failed response के सफल होने का प्रमाण नहीं।

4. दोनों फ़ाइलों की directory से सर्वर शुरू करें; उसके process environment में `OPENAI_API_KEY` पहले से set हो:

```bash
node server.mjs
```

खोलें: `http://localhost:3000`. आपको **Start voice**, **Stop**, **Idle** स्थिति और audio player दिखने चाहिए। **Start voice** क्लिक कर माइक्रोफ़ोन अनुमति दें और छोटा, संवेदनशीलता-रहित सवाल बोलें। OpenAI की [Realtime conversations गाइड](https://developers.openai.com/api/docs/guides/realtime-conversations) कहती है कि default voice activity detection बोलने के बाद विराम से जवाब शुरू कर सकता है। सफल पाठक run के लिए सक्रिय माइक्रोफ़ोन, `connected` connection, `session.created` event, सुनाई देने वाली आवाज़ और `response.done` में completed response देखें। **Stop** क्लिक करके माइक्रोफ़ोन indicator बंद होने की जाँच करें। ये जाँच आपको करनी है; BIG CHANGE ने भुगतान वाला browser session नहीं चलाया।

## जाँच असफल हो तो

माइक्रोफ़ोन अनुमति न मिले या device न दिखे तो browser permission व device देखें, फिर स्थानीय `localhost` URL या HTTPS लें। पेज `/session` failure बताए तो server HTTP status, कुंजी, project model access, billing, rate limits और endpoint जाँचें। सर्वर कुंजी या OpenAI response body जानबूझकर print नहीं करता। 502 नेटवर्क विफलता या 25 सेकंड deadline भी हो सकता है; अनिश्चित upstream request स्वीकार हुई या नहीं, इससे पता नहीं चलता।

Signaling सफल पर connection विफल हो तो page status, network restrictions और SDP answer देखें। Connection सक्रिय पर शांत हो तो mic input और चुना output देखें। Autoplay रुक सकता है: audio control पर **Play** क्लिक करें, फिर जरूरत पर रोककर नया session शुरू करें। हर विफलता में **Stop** लें और microphone indicator बंद होने की पुष्टि करें। Request परिणाम अनिश्चित हो तो बार-बार शुरू करने से पहले project usage देखें।

## लागत, गोपनीयता और सीमाएँ

OpenAI के अनुसार `gpt-realtime-2.1` के noncached text input/output का मूल्य **प्रति दस लाख tokens $4/$24** और audio input/output **प्रति दस लाख tokens $32/$64** है; 19 अक्टूबर 2026 को जाँचा। शुल्क उपयोग किए tokens पर निर्भर है, बाद के turns में पिछले conversation context सहित। इस्तेमाल से पहले [मॉडल मूल्य और सीमाएँ](https://developers.openai.com/api/docs/models/gpt-realtime-2.1) तथा अपने project usage देखें; सिर्फ बीते समय से session bill नहीं निकाला जा सकता। [Realtime conversations गाइड](https://developers.openai.com/api/docs/guides/realtime-conversations) अधिकतम session 60 मिनट बताती है।

Session में माइक्रोफ़ोन आवाज़ OpenAI जाती है। वही बोलें जिसे भेजने का अधिकार हो और निजी या तीसरे पक्ष का audio न लें। स्थानीय पेज में sign-in या प्रति उपयोगकर्ता budget control नहीं। साझा सेवा को authenticated, rate-limited `/session` access और server-derived safety identifier चाहिए; स्थानीय Host व Origin जाँच काफी नहीं। उदाहरण बाहर के tools या phone calls नहीं करता। Latency, विश्वसनीयता, आवाज़ गुणवत्ता, बचत या production deployment का परिणाम नहीं मापा गया।

## स्रोत और आगे पढ़ें

- [OpenAI WebRTC गाइड](https://developers.openai.com/api/docs/guides/voice-webrtc): unified Realtime server exchange, browser audio path और अलग GPT-Live protocol।
- [OpenAI Realtime conversations गाइड](https://developers.openai.com/api/docs/guides/realtime-conversations): session events, turn behavior, response status और अवधि सीमा।
- [OpenAI `gpt-realtime-2.1` मॉडल पेज](https://developers.openai.com/api/docs/models/gpt-realtime-2.1): model access, token मूल्य और rate limits। उदाहरण चलाते समय मूल्य व पहुँच फिर देखें।

## Sources

- [OpenAI WebRTC गाइड](https://developers.openai.com/api/docs/guides/voice-webrtc) — Realtime unified calls interface, trusted key, SDP, browser audio और अलग GPT-Live protocol।
- [OpenAI Realtime conversations](https://developers.openai.com/api/docs/guides/realtime-conversations) — Session events, VAD, response status और 60 मिनट अवधि।
- [OpenAI gpt-realtime-2.1 मॉडल](https://developers.openai.com/api/docs/models/gpt-realtime-2.1) — मॉडल आधारित token मूल्य और पहुँच।
- [OpenAI आवाज़ लागत अनुकूलन](https://developers.openai.com/api/docs/guides/voice-latency-cost) — Context और प्रति response उपयोग।
- [OpenAI API और ChatGPT billing](https://help.openai.com/en/articles/9039756-managing-billing-for-chatgpt-and-the-api-platform) — अलग-अलग billing।