OpenAI Realtime API వల్ల బ్రౌజర్ WebRTCతో మైక్రోఫోన్ శబ్దం పంపి వాయిస్ సమాధానం వినిపించగలదు. ఈ మార్గదర్శిని gpt-realtime-2.1 తో ఒక స్థానిక సంభాషణ నిర్మిస్తుంది. API key మీ కంప్యూటర్ Node serverలోనే ఉంటుంది. Model access, billing గల OpenAI API project అవసరం; ChatGPT subscription API వినియోగానికి చెల్లించదు. BIG CHANGE ప్రస్తుత పత్రాలు, నమూనా code చూసింది; paid session ప్రారంభించలేదు లేదా సమాధానం వినలేదు.
పెద్ద మార్పు
- ఏమి మారింది: OpenAI live Realtime సంభాషణకు browser WebRTC మార్గాన్ని పత్రబద్ధం చేసింది. స్థానిక server project keyని ఉంచి browser connection offerకు బదులుగా answer తీసుకుంటుంది.
- ఇది ఎందుకు ముఖ్యం: పెద్ద వాయిస్ ఉత్పత్తి రూపకల్పనకు ముందు developer ఒక స్థానిక pageలో మైక్రోఫోన్ నుంచి వాయిస్ సమాధానం వరకూ తనిఖీ చేయవచ్చు. Project యజమాని key నియంత్రించి API ఖర్చు చెల్లిస్తారు.
- గమనించాల్సినది: స్థానిక మార్పిడి పని చేయడం production సిద్ధతకు రుజువు కాదు. పంచుకునే సేవకు caller authentication, ఖర్చు నియంత్రణలు అవసరం; cancelled లేదా timeout request ఇప్పటికే OpenAIకి చేరవచ్చు.
ప్రారంభించే ముందు
Node.js 22.6 లేదా కొత్త version, పని చేసే మైక్రోఫోన్, speaker గల ప్రస్తుత browser వాడండి. మైక్రోఫోన్ accessకు సురక్షిత context కావాలి; http://localhost ఈ స్థానిక ఉదాహరణకు సరిపోతుంది. gpt-realtime-2.1 access, billing enabled ఉన్న OpenAI API project key సిద్ధం చేయండి. మొదట rate, spend limits చూడండి. Model page Free tier మద్దతు లేదని చెబుతుంది. సాధారణ secret manager లేదా స్థానిక shell అమరికతో keyని server process environmentలో ఉంచండి. దాన్ని index.html లో పెట్టవద్దు, .env ఫైల్లో commit లేదా transcriptలో paste చేయవద్దు. OpenAI WebRTC మార్గదర్శిని విశ్వసనీయ server మార్పిడిని వివరిస్తుంది; model page ప్రస్తుత access, ధరలను ఇస్తుంది.
ఇది 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లో ఉంచండి. Code Node అంతర్నిర్మిత fetch, FormData, AbortSignal.timeout వాడుతుంది; తనిఖీ చేసిన అమరికకు Node.js 22.6 లేదా కొత్త version కావాలి.
- క్రిందిదాన్ని
server.mjsగా భద్రపరచండి. ఇది browser SDP offer (ప్రతిపాదిత WebRTC connection వివరణ) స్వీకరించి Realtime session settingsతో OpenAIకి పంపుతుంది. సాధారణ API key ఈ serverలోనే చదవబడుతుంది.
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"));Server 127.0.0.1:3000 కు bind అయి, స్థానిక page host, POST origin మాత్రమే అనుమతించి SDP answer తిరిగిస్తుంది. 25 సెకన్ల upstream deadline ఈ ఉదాహరణ ఎంపిక. Timeout లేదా browser disconnect అంటే OpenAI request స్వీకరించలేదని కాదు; అనిశ్చిత ప్రారంభం మళ్లీ చేసే ముందు వినియోగం చూడండి.
- క్రిందిదాన్ని
index.htmlగా భద్రపరచండి. Page Start voice తర్వాత మైక్రోఫోన్ అనుమతి అడిగి, స్థానిక serverకు offer పంపి వచ్చిన audio వినిపిస్తుంది. Stop setup జరుగుతున్నప్పటికీ connection మూసి microphone tracks ఆపుతుంది. 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 వైఫల్యం, page వదిలినప్పుడు కూడా browser session మూస్తుంది. Stop లేదా timeout తర్వాత అనుమతి రావచ్చు; ఆలస్యమైన track ఆపబడుతుంది. Status line response.done , నివేదించిన స్థితిని చూపుతుంది. ఆ event ఒక్కటే సమాధానం వినిపించిందని లేదా cancelled/failed response విజయవంతమైందని చెప్పదు.
- రెండు ఫైళ్ల directory నుంచి server ప్రారంభించండి; దాని 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 ఈ paid browser session నడపలేదు.
తనిఖీ విఫలమైతే
మైక్రోఫోన్ అనుమతి తిరస్కరించినా లేదా device కనిపించకపోయినా browser permission, device చూసి స్థానిక localhost URL లేదా HTTPS వాడండి. Page /session failure చూపితే server HTTP status, key, project model access, billing, rate limits, endpoint చూడండి. Server key లేదా OpenAI response body ఉద్దేశపూర్వకంగా ముద్రించదు. 502 అనేది network వైఫల్యం లేదా 25 సెకన్ల deadline కావచ్చు; అనిశ్చిత upstream request స్వీకరించిందో తెలియజేయదు.
Signaling విజయవంతమైనా connection విఫలమైతే page status, network restrictions, తిరిగొచ్చిన SDP answer చూడండి. Connection చురుకుగా ఉండి శబ్దం లేకపోతే mic input, ఎంచుకున్న output చూడండి. Autoplay అడ్డుకోవచ్చు: audio controlలో Play నొక్కి అవసరమైతే ఆపి కొత్త session ప్రారంభించండి. ప్రతి వైఫల్యంలో Stop వాడి మైక్రోఫోన్ 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తో సహా. వాడే ముందు model ధరలు, పరిమితులు , మీ project usage చూడండి; గడిచిన సమయంతో మాత్రమే session bill అంచనా వేయలేం. Realtime conversations మార్గదర్శిని గరిష్ఠ session 60 నిమిషాలుగా చెబుతుంది.
Sessionలో మైక్రోఫోన్ audio OpenAIకి వెళ్తుంది. పంపే అధికారం ఉన్న మాటలు వాడి, వ్యక్తిగత లేదా ఇతరుల audio నివారించండి. స్థానిక pageలో 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.1model page: model access, token ధరలు, rate limits. ఉదాహరణ నడిపేటప్పుడు ధరలు, access మళ్లీ చూడండి.



