You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何监听HTMLMediaElement(Audio)的播放结束事件?

监听音频播放完成的两种实用方案

嘿,这个需求太常见了!不用纠结ended属性的轮询方式,下面给你两种更优雅的实现思路,完全符合你想要的事件、Promise风格:

一、直接使用ended事件监听

这是HTML5 Audio元素原生支持的事件,当音频播放到末尾时会自动触发,简单又可靠:

const mySound = new Audio('/my-url');
mySound.play();

// 监听播放结束事件
mySound.addEventListener('ended', () => {
  console.log('音频已经播放完毕啦!');
  // 在这里写下你需要执行的后续逻辑,比如播放下一首、更新UI等
});

如果后续需要移除监听,也可以用removeEventListener方法,灵活性拉满。

二、封装为Promise(现代异步编程风格)

如果你更喜欢用Promise/async-await的方式来处理异步流程,可以把音频播放和结束监听封装成一个Promise函数,这样代码会更整洁,也方便和其他异步操作配合:

function playAndWaitForEnd(url) {
  return new Promise((resolve, reject) => {
    const audio = new Audio(url);
    
    // 处理播放失败的情况
    audio.play().catch(error => reject(`播放失败:${error.message}`));
    
    // 监听播放结束事件,成功resolve
    audio.addEventListener('ended', () => {
      resolve('音频播放完成');
    });
    
    // 额外处理音频加载出错的情况
    audio.addEventListener('error', (event) => {
      reject(`音频加载出错:${event.error.message}`);
    });
  });
}

// 使用方式1:then/catch
playAndWaitForEnd('/my-url')
  .then(result => {
    console.log(result);
    // 播放结束后的逻辑
  })
  .catch(error => {
    console.error(error);
  });

// 使用方式2:async/await(更简洁)
async function handleAudio() {
  try {
    await playAndWaitForEnd('/my-url');
    console.log('音频播放完毕,开始执行后续操作');
    // 这里写你的后续逻辑
  } catch (error) {
    console.error('处理音频时出错:', error);
  }
}

handleAudio();

为什么不推荐用ended属性?

ended是一个布尔值属性,你需要通过定时轮询(比如setInterval)去检查它的状态,这种方式既浪费浏览器性能,代码也不够优雅。而事件监听是被动触发,只有当播放结束时才会执行回调,效率和可读性都高得多。

内容的提问来源于stack exchange,提问作者Valentin Coudert

火山引擎 最新活动