要在课堂互动里让学生通过语音向 GPT-Live 提问,完整链路是:从课堂端采集麦克风声音,在提问触发后把音频上传给 GPT-Live 服务端,再把返回的语音或文本结果送回课堂端播放。这里的难点不在大模型本身,而在音频采集范围、请求触发方式、播放结果与失败提示,以及最终在教室真实环境里做一次端到端确认。
适合在线课堂或本地小班课场景。操作动作:先固定课堂端的音频输入设备,再用按键触发录音并上传,最后播放返回结果并记录日志。验证方式:发起一次真实提问,检查请求日志和播放是否完成。风险边界:采集范围、网络延迟和播放设备音量都会影响可用性,需按实际课堂环境调整。
确定课堂端的音频采集范围
课堂端麦克风如果默认指向系统“立体声混音”或房间全向麦,会把教师讲课、学生讨论、空调噪声一起录进去,上传后 GPT-Live 很难识别出单独提问。所以第一件事是明确当前系统使用的是哪个音频输入源。
在 Windows 桌面端可以打开“声音设置 → 输入”,查看或修改默认麦克风;浏览器端需要检查 https 页面里的麦克风授权,并在调用 getUserMedia 时显式指定设备。比较稳妥的做法是在课堂开始前用系统工具列出可用设备,确认后固定使用同一设备。
# Linux 桌面端查看录音设备列表
arecord -l
# 输出示例(具体设备名需结合本机环境确认)
**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC257 Analog
Subdevices: 1/1
Subdevice #0: subdevice #0建议把采集设备名写入课堂端配置文件,避免每次上课都重新选择。如果现场出现回声或噪声,优先检查是不是选到了“立体声混音”——那是录制系统输出,不是麦克风。
编写提问触发与音频上传代码
课堂提问不能一直录音,否则请求内容混乱。更合理的做法是让学生按住某个按键(例如空格键)开始录音,松键后停止并上传。这样既控制音频长度,也避免把思考过程传到服务端。
下面是一个浏览器端按键触发录音的骨架,使用 MediaRecorder 采集音频,松键后生成 Blob 并 POST 到占位 URL。实际接入时把 uploadUrl 替换成你的 GPT-Live 服务地址。
let mediaRecorder;
let audioChunks = [];
let stream;
async function startRecording() {
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = e => audioChunks.push(e.data);
mediaRecorder.start();
}
async function stopAndUpload() {
mediaRecorder.stop();
mediaRecorder.onstop = async () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
const formData = new FormData();
formData.append('audio', audioBlob, 'question.webm');
const resp = await fetch('https://your-gptlive-endpoint.example.com/ask', {
method: 'POST',
body: formData
});
const data = await resp.json();
handleAnswer(data); // 交给播放逻辑
stream.getTracks().forEach(track => track.stop());
};
}
// 键盘绑定:按下开始,松开上传
document.addEventListener('keydown', e => {
if (e.code === 'Space' && !e.repeat) startRecording();
});
document.addEventListener('keyup', e => {
if (e.code === 'Space') stopAndUpload();
});代码里没有写死具体 GPT-Live SDK,因为接口地址和返回格式取决于你的部署版本。上传前可以先做一次音频时长检查,比如少于 0.5 秒就丢弃并提示“录音太短”,避免无效请求。
接收服务端回答并转为课堂播放
服务端返回的答案可能是音频文件 URL,也可能是文本。如果是文本,可以用浏览器 SpeechSynthesis 朗读,或者把文本交给 TTS 服务生成音频。优先使用服务端返回的音频,因为延迟可控且音色统一。
下面的片段处理“返回音频播放”和“文本超时/播放失败”两种情况。播放失败时至少要在界面显示文字,避免学生干等。
function handleAnswer(data) {
if (!data || !data.audioUrl) {
showTextAnswer(data && data.text ? data.text : '未收到回答');
return;
}
const audio = new Audio(data.audioUrl);
const timeout = setTimeout(() => {
showTextAnswer('音频加载超时,请查看文字回答');
}, 8000);
audio.onplay = () => clearTimeout(timeout);
audio.onerror = () => {
clearTimeout(timeout);
showTextAnswer(data.text || '音频播放失败,请重试');
};
audio.play();
}
function showTextAnswer(text) {
const box = document.getElementById('answerText');
if (box) box.textContent = text;
}课堂播放需要单独控制声音输出设备,不要用系统默认扬声器。如果教室有多个音响,建议在系统设置里把播放设备固定到主音箱,并在页面里加一个音量滑块。播放前先测一次音量,避免回答声音过小或突然放大。
验证课堂场景的端到端流程
组件写完后,必须按真实课堂流程跑一次,不能只看单段代码。课堂环境有背景噪声、多人距离、网络波动,和开发环境差异很大。建议用以下步骤验证,每一步都记录状态。
- 固定麦克风为教师近讲麦克风,确认系统录音音量在 60%~80% 之间。
- 点击或按空格发起一次提问,录音期间不要移动设备,松键后等待服务端响应。
- 检查浏览器 DevTools 的 Network 面板,确认上传请求(audio POST)已发出,并查看响应状态码是否为 200 或 202。
- 确认音频播放正常,记录回答文本是否完整、音频时长是否合理。
// 在 DevTools Console 里打印请求日志(示例)
console.log('upload: pending');
// 上传完成后
console.log('upload: success', response.status);
// 播放开始/失败
console.log('play: started');
console.log('play: failed', error);如果上传成功但没声音,先检查浏览器是否被系统静音,再看返回的音频 URL 是否可访问。如果请求超时或返回 502,先确认 GPT-Live 服务端的日志——有些问题出在课堂端,有些在服务端,日志能快速定位。验证通过后,再把这套流程固定成课堂端的开机自检脚本,以后每次上课前跑一遍即可。