Hinahayaan ng Realtime API ng OpenAI na ipadala ng browser ang microphone audio at magpatugtog ng pasalitang sagot sa WebRTC. Bubuo ang gabay ng isang lokal na pag-uusap gamit ang gpt-realtime-2.1. Nananatili ang API key sa Node server sa iyong computer. Kailangan ang OpenAI API project na may model access at billing; hindi binabayaran ng ChatGPT subscription ang API usage. Sinuri ng BIG CHANGE ang kasalukuyang dokumentasyon at sample code, ngunit hindi nagbukas ng bayad na session o nakarinig ng sagot.
Ang malaking pagbabago
- Ano ang nagbago: Dokumentado ng OpenAI ang browser WebRTC para sa live Realtime conversation, na may lokal na server na nagpapalit ng connection offer ng browser sa answer habang hawak ang project key.
- Bakit mahalaga: Maaaring suriin ng developer ang buong landas mula mikropono hanggang pasalitang sagot sa isang lokal na page bago bumuo ng mas malaking voice product. Kinokontrol ng project owner ang key at binabayaran ang API usage.
- Ano ang dapat bantayan: Hindi patunay ng production readiness ang gumaganang lokal na palitan. Kailangan ng shared na bersiyon ang caller authentication at spending controls; maaaring nakarating na sa OpenAI ang nakansela o nag-timeout na request.
Bago magsimula
I-install ang Node.js 22.6 o mas bago at gumamit ng kasalukuyang browser na may gumaganang mikropono at speaker. Nangangailangan ng secure context ang browser microphone access; ang http://localhost ay angkop sa lokal na halimbawang ito. Maghanda ng OpenAI API project key na may gpt-realtime-2.1 access at aktibong billing. Tingnan muna ang rate at spend limits. Hindi suportado ang Free tier ayon sa model page. Itago ang key sa environment ng server process gamit ang normal na secret manager o lokal na shell setup. Huwag ilagay sa index.html, i-commit sa isang .env file, o i-paste sa transcript. Ang WebRTC guide ng OpenAI ay nagdodokumento ng trusted-server exchange; ang model page ang may kasalukuyang access at presyo.
Ito ang unified /v1/realtime/calls route ng Realtime API. Inilalarawan din ng WebRTC guide ang GPT-Live sa /v1/live/sessions, na ibang session protocol. Panatilihing magkapareha ang route at payload sa ibaba. Nakatali ang sample sa sarili mong computer; hindi pinatutunayan ng lokal na Host at Origin checks ang pagkakakilanlan ng shared-service users.
- Gumawa ng bakanteng directory para sa demo. Mula roon, i-install ang Express:
npm init -y
npm install expressLumilikha ang installation ng package.json at nagdaragdag ng web-server dependency. I-save ang susunod na dalawang file sa iisang directory. Ginagamit ng code ang built-in Node fetch, FormData at AbortSignal.timeout; kailangan ng sinuring setup ang Node.js 22.6 o mas bago.
- I-save ang sumusunod bilang
server.mjs. Tinatanggap nito ang SDP offer ng browser (paglalarawan ng mungkahing WebRTC connection) at ipinadadala sa OpenAI kasama ang Realtime session settings. Sa server na ito lamang binabasa ang karaniwang API key.
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"));Nagbi-bind ang server sa 127.0.0.1:3000, tumatanggap lang ng host at POST origin ng lokal na page, at ibinabalik ang SDP answer sa browser. Pinili para sa halimbawa ang 25-second upstream deadline. Hindi patunay ang timeout o browser disconnect na hindi tinanggap ng OpenAI ang request; tingnan ang usage bago ulitin ang hindi tiyak na simula.
- I-save ang sumusunod bilang
index.html. Humihingi ang page ng microphone permission pagkatapos ng Start voice, ipinadadala ang offer sa lokal na server at pinatutugtog ang papasok na audio. Stop ang nagsasara ng connection at humihinto sa microphone tracks kahit nagsi-setup pa. Piniling halimbawa rin ang 30-second setup timer, hindi 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>Isinasara rin ng browser ang session kapag pumalya ang peer o event channel at kapag iniwan ang page. Maaaring dumating ang microphone permission matapos huminto o mag-timeout; ititigil ang late track. Ipinapakita ng status line ang response.done kasama ang iniulat na status. Hindi nito mag-isang pinatutunayan na narinig ang sagot o nagtagumpay ang nakansela o nabigong response.
- Simulan ang server mula sa directory ng dalawang file, na nakatakda na ang
OPENAI_API_KEYsa environment ng server process:
node server.mjsBuksan ang http://localhost:3000. Dapat makita ang Start voice, Stop, isang Idle status at audio player. I-click ang Start voice, payagan ang mikropono at magsalita ng maikling tanong na walang sensitibong laman. Ayon sa Realtime conversations guide ng OpenAI, maaaring gawing trigger ng sagot ang paghinto matapos magsalita ng default voice activity detection. Para sa matagumpay mong run, tiyaking aktibo ang mic sa browser, umabot ang connection sa connected, may session.created event, naririnig ang boses, at ang response.done ay nag-uulat ng completed response. I-click ang Stop at tiyaking namatay ang microphone indicator. Ikaw ang gagawa ng mga pagsusuring ito; hindi pinatakbo ng BIG CHANGE ang bayad na browser session.
Kapag nabigo ang pagsusuri
Kung tinanggihan ang microphone permission o walang input device, tingnan ang browser permission at device, pagkatapos gamitin ang lokal na localhost URL o HTTPS. Kung may /session failure, tingnan ang server HTTP status at tiyakin ang key, project model access, billing, rate limits at endpoint. Sadyang hindi pini-print ang key o OpenAI response body. Maaaring network failure o 25-second deadline din ang 502; hindi nito sinasabi kung tinanggap ang hindi tiyak na upstream request.
Kung matagumpay ang signaling ngunit pumalya ang connection, tingnan ang page connection status, network restrictions at ibinalik na SDP answer. Kung live pero tahimik, tingnan ang microphone input at napiling output device. Maaaring harangin ang autoplay: i-click ang Play sa audio control, saka huminto at magsimula ng bagong session kung kailangan. Sa anumang pagkabigo, gamitin ang Stop at tiyaking patay ang microphone indicator. Tingnan ang project usage bago paulit-ulit na simula kung hindi tiyak ang request.
Gastos, privacy at limitasyon
Inililista ng OpenAI ang gpt-realtime-2.1 noncached text input/output sa $4/$24 bawat milyong tokens at audio input/output sa $32/$64 bawat milyong tokens, sinuri noong 19 Oktubre 2026. Nakadepende sa tokens ang bayad, kasama ang susunod na turns na maaaring may dating conversation context. Tingnan ang model pricing at limits at project usage bago gamitin; hindi makukuwenta ang bill mula sa tagal lamang. Ayon sa Realtime conversations guide, hanggang 60 minuto ang session.
Napupunta sa OpenAI ang microphone audio habang may session. Gumamit ng salitang may pahintulot kang ipadala at iwasan ang pribado o third-party audio sa test. Walang sign-in o per-user budget control ang page. Kailangan ng shared service ang authenticated, rate-limited /session access at server-derived safety identifier; hindi sapat ang lokal na Host at Origin checks. Hindi tumatawag ng outside tools o telepono ang halimbawa. Walang sinukat na latency, reliability, kalidad ng boses, pagtitipid o production deployment result.
Mga sanggunian at karagdagang babasahin
- OpenAI WebRTC guide: unified Realtime server exchange, browser audio path at hiwalay na GPT-Live protocol.
- OpenAI Realtime conversations guide: session events, turn behavior, response status at duration limit.
- OpenAI
gpt-realtime-2.1model page: model access, token prices at rate limits. Suriin muli ang presyo at access sa aktuwal na paggamit.



