四十年前,我为我的 Commodore PET 编写了自己的 6502 汇编语言 EEPROM,现在我很难“仅仅”为 Promise 实现中止方法:-(
为浏览器制作了一个程序,其中包含大量文本和许多声音剪辑链接(> 900)。单击链接会播放声音。 一切都很好,直到我想到有了这么多的声音,我可以制作一种自动点唱机,它可以以随机顺序循环播放这些声音。 现在使用 Promise 可以很好地工作,但有时我只是想跳过正在播放的声音,所以我需要一种方法来中止当前正在播放的声音,以便程序可以选择下一个声音。 我在Stackoverflow上找到了很多例子,主要是处理Fetch和Timeout,我研究并尝试了各种方法,但仍然无法跳到下一个声音...... 这可能是一些“简单”的错误,但目前我不知道哪一行是错误的,或者我必须在哪里添加更多编码,因此感谢任何帮助!
有以下功能,效果很好:它在“无限”循环中播放随机歌曲,但我只是找不到实现中止的正确方法,以便我可以跳过一首歌曲。
const ac = new AbortController();
…
async function jukebox({ signal } = {}) {
var jbsong = ''; // holds the song’s filename
var maxSongs = 5; // set max nr of songs to play in a row
jbplays = true; // global that tells system that jukebox is playing
for (var j = 0; j < maxSongs; j++) { // loop over songs
jbsong = getRandomSong();
try {
const answer = await playSound(jbsong));
}
catch (playerror) {
console.log(j + ". NOT found: " + jbsong);
console.log("PlayError: " + playerror);
}
}
jbplays = false; // indication that jukebox is not running anymore
stopMedia(); // hide some info that was displayed
console.log("Jukebox Finished");
};
…
function playSound(soundfile) {
audio.src = (soundfile); // rest of audio was already defined
if (jbplays) { // if called from julebox
return new Promise(function(resolve, reject) { // return a promise
audio.onerror = reject; // an error
audio.onended = resolve; // done playing
})
}
else { // called as a normal one-song play
… playing of a single song (by click on a link) plays OK
}
};
目前我尝试使用我的handleKeyboard中的键S来中止承诺,如下所示:
case 83: // S - Skip to next sound, so abort the promise
if (jbplays) { // jukebox is playing
console.log("Now trying to abort promise");
ac.abort(); // Doesn’t seem to do anything at the moment
}
break;
总结:
点击链接即可播放。
循环播放就可以了。
中止承诺,以便转到循环中的下一首歌曲是不可以。
显示消息“现在正在尝试中止承诺”。
我错过了什么?
非常感谢!
后续:
在我实施镇长建议的第二天,我注意到现在(当然)暂停音频(我的空格键,用于切换暂停播放)也会使程序跳过音频,因为使用pause()会触发audio.onpause事件,它解决了,从而播放循环中的下一个音频。
经过一番挖掘,我找到了以下跳过声音剪辑的解决方案:
audio.fastSeek(Math.round(audio.duration));
这会将音频“读取”位置设置在音频文件的末尾,然后它会自动触发audio.onished = resolve事件,这意味着在循环中下一个声音开始。
因此:当连续播放多个声音片段时,无需中止承诺,这一切都可以通过音频本身“内部”来完成。
请注意,目前 fastSeek 方法仅受 Firefox 和 Safari 支持,但由于我无论如何都使用 Firefox,所以这对我来说没问题 ☺