我目前正在研究通过单击按钮即可发出文本语音的功能。我有一个按钮,单击时应该播放文本。我在点击后通过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等,代码等待响应返回,响应返回后,要么立即开始播放音频文件,要么就直接播放挂起等待完全下载,下载后开始播放。预先感谢您。
您需要监听 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;
} )