在JS页面未完全加载音频文件时播放

问题描述 投票:0回答:1

我目前正在研究通过单击按钮即可发出文本语音的功能。我有一个按钮,单击时应该播放文本。我在点击后通过API获取了音频文件,在这方面一切正常,我获取了音频文件的url。当我尝试使该音频在点击时工作时,就会出现问题。我的代码现在看起来像这样:

speech.addEventListener('click', () => {
  let speechText = "Привет!";
  const audio = new Audio();
  const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText);
  audio.src = audioURL;
  audio.play();
}

代码等待 URL 从 getOpenaiVoice 返回并将其分配给audio.src,然后调用audio.play();立即触发,导致错误:

NotSupportedError: Failed to load because no supported source was found.

如果稍后再点击按钮,音频就会正常播放,因为它已经完全上传到网站了,不会有错误。

我尝试用 Promise 重写代码,将元素包装在 async wait 中,但我对异步编程的了解太少,无法立即看出问题所在。我一整天都在解决这个问题,但我没有看到任何选择。

function audioLoad(audio, url) {
        let prom = new Promise((resolve, reject) => {
           audio.src = url;
           audio.addEventListener('loadeddata', () => {
                resolve(audio);
           });
        });
            
        prom.then((value) => {
            value.play();
        })
}
  
async function audioCreation() {
        let speechText = "Привет!";
        const audio = new Audio();
        const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText);
        audio.src = audioURL;
        audio.play();
}
        
audioCreation();

但是,只有在文件完全下载后单击,上面的代码才有效。第一次单击时总是会出现错误,因为它仅在单击后才开始下载。总体思路是:用户点击语音按钮,所有请求都发送到API等,代码等待响应返回,响应返回后,要么立即开始播放音频文件,要么就直接播放挂起等待完全下载,下载后开始播放。预先感谢您。

javascript asynchronous async-await html5-audio
1个回答
0
投票

您需要监听 canplaythrough 音频事件

speech.addEventListener('click', () => {
  let speechText = "Привет!";
  const audio = new Audio();
  const audioURL = await getOpenaiVoice(voiceAPI, voiceID, speechText);

  audio.addEventListener( "canplaythrough", event => {
    audio.play();
  } )

  // Triggers the canplaythrough event when the audio is done loading
  audio.src = audioURL;
} )
© www.soinside.com 2019 - 2024. All rights reserved.