-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.js
141 lines (115 loc) · 4.12 KB
/
init.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
let peerConnection = null;
let dataChannel = null;
async function init() {
try {
console.log("开始初始化...");
// Get an ephemeral key from your server
const tokenResponse = await fetch("/session");
if (!tokenResponse.ok) {
const errorText = await tokenResponse.text();
throw new Error(`服务器返回错误 ${tokenResponse.status}: ${errorText}`);
}
const data = await tokenResponse.json();
console.log("服务器返回数据:", data);
if (!data.client_secret || !data.client_secret.value) {
throw new Error("服务器返回的数据格式不正确: " + JSON.stringify(data));
}
const EPHEMERAL_KEY = data.client_secret.value;
console.log("获取到临时密钥");
// Create a peer connection
const pc = new RTCPeerConnection();
console.log("创建RTCPeerConnection");
// Set up to play remote audio from the model
const audioEl = document.createElement("audio");
audioEl.autoplay = true;
pc.ontrack = e => {
audioEl.srcObject = e.streams[0];
console.log("收到音频流");
};
// Add local audio track for microphone input
try {
const ms = await navigator.mediaDevices.getUserMedia({
audio: true
});
pc.addTrack(ms.getTracks()[0]);
console.log("添加本地音频轨道");
} catch (err) {
console.error("获取麦克风失败:", err);
alert("请允许使用麦克风");
return;
}
// Set up data channel for sending and receiving events
const dc = pc.createDataChannel("oai-events");
dc.addEventListener("message", (e) => {
// Realtime server events appear here!
console.log(e);
});
console.log("设置数据通道");
// Start the session using SDP
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
console.log("创建并设置本地描述");
const baseUrl = "https://api.openai.com/v1/realtime";
const model = "gpt-4o-realtime-preview-2024-12-17";
try {
const sdpResponse = await fetch(`${baseUrl}?model=${model}`, {
method: "POST",
body: offer.sdp,
headers: {
Authorization: `Bearer ${EPHEMERAL_KEY}`,
"Content-Type": "application/sdp"
},
});
if (!sdpResponse.ok) {
throw new Error(`OpenAI API returned ${sdpResponse.status}`);
}
const answer = {
type: "answer",
sdp: await sdpResponse.text(),
};
await pc.setRemoteDescription(answer);
console.log("连接建立成功");
// 启用发送按钮
document.getElementById('sendButton').disabled = false;
peerConnection = pc;
dataChannel = dc;
const connectButton = document.getElementById('connectButton');
const disconnectButton = document.getElementById('disconnectButton');
const status = document.getElementById('status');
connectButton.style.display = 'none';
disconnectButton.style.display = 'inline-block';
status.textContent = '状态:已连接';
} catch (err) {
console.error("连接OpenAI失败:", err);
alert("连接OpenAI失败,请检查API密钥是否正确");
return;
}
} catch (err) {
console.error("初始化失败:", err);
alert("初始化失败: " + err.message);
}
}
function disconnect() {
if (dataChannel) {
dataChannel.close();
dataChannel = null;
}
if (peerConnection) {
peerConnection.close();
peerConnection = null;
}
const connectButton = document.getElementById('connectButton');
const disconnectButton = document.getElementById('disconnectButton');
const status = document.getElementById('status');
const sendButton = document.getElementById('sendButton');
connectButton.style.display = 'inline-block';
disconnectButton.style.display = 'none';
status.textContent = '状态:未连接';
sendButton.disabled = true;
}
// 导出init函数到全局作用域
window.init = init;
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('disconnectButton').addEventListener('click', disconnect);
});
init();