JS点击按钮获取音频URL后立即播放报错问题求助
解决方案:等待音频资源加载完成后再播放
你的核心问题是:获取到音频URL后立即调用audio.play(),但此时浏览器还未完成音频资源的加载,导致无法识别有效播放源。需要在音频加载完成后再触发播放,同时修正异步代码的语法问题。
步骤1:修正点击事件的异步语法
原点击事件回调未声明async,直接使用await会报错,先补上:
speech.addEventListener('click', async () => { // 后续代码 });
步骤2:封装音频加载的Promise逻辑
监听音频的canplaythrough(表示音频已加载到可流畅播放的程度)事件,同时处理加载失败的情况,避免Promise一直处于pending状态:
function loadAudio(audio, url) { return new Promise((resolve, reject) => { // 清除之前的事件监听,避免重复绑定 audio.removeEventListener('canplaythrough', resolve); audio.removeEventListener('error', reject); audio.src = url; audio.addEventListener('canplaythrough', () => resolve(audio)); audio.addEventListener('error', (err) => reject(err)); // 主动触发加载 audio.load(); }); }
步骤3:整合完整逻辑
把API请求、音频加载、播放整合到点击事件中,同时处理可能的错误:
speech.addEventListener('click', async () => { try { const speechText = "Привет!"; // 等待API返回音频URL const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText); const audio = new Audio(); // 等待音频加载完成 await loadAudio(audio, audioURL); // 加载完成后播放 await audio.play(); } catch (err) { console.error('音频播放失败:', err); // 可在此添加用户提示,比如"音频加载失败,请重试" } });
额外优化建议
- 复用Audio实例:如果频繁点击按钮,可在外部创建一个Audio实例,避免重复创建提升性能:
const audioInstance = new Audio(); speech.addEventListener('click', async () => { try { const speechText = "Привет!"; const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText); // 停止当前播放并重置进度 audioInstance.pause(); audioInstance.currentTime = 0; await loadAudio(audioInstance, audioURL); await audioInstance.play(); } catch (err) { console.error('音频播放失败:', err); } }); - 添加加载状态:点击按钮后禁用按钮并显示加载提示,完成或失败后恢复,提升用户体验:
speech.addEventListener('click', async () => { try { speech.disabled = true; speech.textContent = '加载中...'; const speechText = "Привет!"; const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText); const audio = new Audio(); await loadAudio(audio, audioURL); await audio.play(); } catch (err) { console.error('音频播放失败:', err); } finally { speech.disabled = false; speech.textContent = '播放语音'; } });
内容的提问来源于stack exchange,提问作者Igor
相关产品推荐
相关产品推荐

