You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:33:25