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 गाइड भरोसेमंद सर्वर के आदान-प्रदान का विवरण देती है; मॉडल पेज वर्तमान पहुँच और मूल्य बताता है।
यह Realtime API का unified /v1/realtime/calls route है। WebRTC गाइड /v1/live/sessions से GPT-Live भी बताती है, जिसका session protocol अलग है। नीचे route और payload साथ रखें। उदाहरण अपने कंप्यूटर तक सीमित है; स्थानीय Host और Origin जाँच साझा सेवा के उपयोगकर्ताओं का authentication नहीं करती।
- डेमो के लिए खाली directory बनाएँ और उसी से Express install करें:
npm init -y
npm install expressInstallation package.json बनाता और web-server dependency जोड़ता है। अगली दो फ़ाइलें उसी directory में रखें। कोड Node के अंतर्निहित fetch, FormData और AbortSignal.timeout इस्तेमाल करता है; जाँची व्यवस्था को Node.js 22.6 या बाद का version चाहिए।
- इसे
server.mjsनाम से सहेजें। यह ब्राउज़र का SDP offer (प्रस्तावित WebRTC connection का विवरण) लेकर Realtime session settings के साथ OpenAI भेजता है। मानक API कुंजी केवल इस सर्वर पर पढ़ी जाती है।
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 स्वीकार नहीं की; अनिश्चित शुरुआत दोहराने से पहले उपयोग देखें।
- इसे
index.htmlनाम से सहेजें। पेज Start voice के बाद माइक्रोफ़ोन अनुमति माँगता, स्थानीय सर्वर को offer भेजता और आया audio चलाता है। Stop connection बंद कर माइक्रोफ़ोन tracks रोकता है, setup के दौरान भी। 30 सेकंड setup timer भी उदाहरण का चुनाव है, API guarantee नहीं।
<!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 के सफल होने का प्रमाण नहीं।
- दोनों फ़ाइलों की directory से सर्वर शुरू करें; उसके process environment में
OPENAI_API_KEYपहले से set हो:
node server.mjsखोलें: http://localhost:3000. आपको Start voice, Stop, Idle स्थिति और audio player दिखने चाहिए। Start voice क्लिक कर माइक्रोफ़ोन अनुमति दें और छोटा, संवेदनशीलता-रहित सवाल बोलें। OpenAI की 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 सहित। इस्तेमाल से पहले मॉडल मूल्य और सीमाएँ तथा अपने project usage देखें; सिर्फ बीते समय से session bill नहीं निकाला जा सकता। 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 गाइड: unified Realtime server exchange, browser audio path और अलग GPT-Live protocol।
- OpenAI Realtime conversations गाइड: session events, turn behavior, response status और अवधि सीमा।
- OpenAI
gpt-realtime-2.1मॉडल पेज: model access, token मूल्य और rate limits। उदाहरण चलाते समय मूल्य व पहुँच फिर देखें।



