44 lines
No EOL
1.1 KiB
TypeScript
44 lines
No EOL
1.1 KiB
TypeScript
import { RefObject } from "react";
|
|
|
|
export async function createRealtimeConnection(
|
|
EPHEMERAL_KEY: string,
|
|
audioElement: RefObject<HTMLAudioElement | null>
|
|
): Promise<{ pc: RTCPeerConnection; dc: RTCDataChannel }> {
|
|
const pc = new RTCPeerConnection();
|
|
|
|
pc.ontrack = (e) => {
|
|
if (audioElement.current) {
|
|
audioElement.current.srcObject = e.streams[0];
|
|
}
|
|
};
|
|
|
|
const ms = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
pc.addTrack(ms.getTracks()[0]);
|
|
|
|
const dc = pc.createDataChannel("oai-events");
|
|
|
|
const offer = await pc.createOffer();
|
|
await pc.setLocalDescription(offer);
|
|
|
|
const baseUrl = "https://api.openai.com/v1/realtime";
|
|
const model = "gpt-realtime-1.5";
|
|
|
|
const sdpResponse = await fetch(`${baseUrl}?model=${model}`, {
|
|
method: "POST",
|
|
body: offer.sdp,
|
|
headers: {
|
|
Authorization: `Bearer ${EPHEMERAL_KEY}`,
|
|
"Content-Type": "application/sdp",
|
|
},
|
|
});
|
|
|
|
const answerSdp = await sdpResponse.text();
|
|
const answer: RTCSessionDescriptionInit = {
|
|
type: "answer",
|
|
sdp: answerSdp,
|
|
};
|
|
|
|
await pc.setRemoteDescription(answer);
|
|
|
|
return { pc, dc };
|
|
}
|