HTML5 媒体播放器:从 audio 到播放列表 | 拾音
为什么用原生元素
个人播放页只需要播放/暂停、进度、音量、上一首/下一首。引入 hls.js 或 video.js 会增加数百 KB 的体积,而原生 <audio> 已经提供了完整的解码与播放能力。
<audio ref="audio" :src="current.url" preload="metadata" />
自定义控件
隐藏原生控件,用按钮与 range 输入实现自己的界面,核心是三个事件:
audio.addEventListener('timeupdate', () => {
progress.value = audio.currentTime / audio.duration || 0;
});
audio.addEventListener('ended', () => playNext());
audio.addEventListener('loadedmetadata', () => {
duration.value = audio.duration;
});
拖动进度条时要注意:拖动过程中不要被 timeupdate 覆盖,可以用 isSeeking 标志位。
播放列表状态
播放列表用索引管理,切换曲目时保留播放状态:
function playAt(index) {
currentIndex.value = index;
nextTick(() => {
audio.value.load();
audio.value.play();
});
}
在移动端锁屏界面显示标题与封面,并支持耳机按键控制:
navigator.mediaSession.metadata = new MediaMetadata({
title: current.value.title,
artist: '拾音电台',
artwork: [{ src: current.value.cover, sizes: '512x512', type: 'image/svg+xml' }],
});
navigator.mediaSession.setActionHandler('nexttrack', () => playNext());
播放计数与防刷
播放次数在 play 事件触发时上报,服务端按"同一 IP 对同一媒体 10 分钟内只计一次"去重,避免刷新刷量。
无障碍
- 所有按钮提供
aria-label;
- 进度条使用
role="slider" 与 aria-valuenow;
- 键盘支持空格播放/暂停、左右方向键快进快退。
小结
原生媒体元素的能力已经足够支撑个人播客场景。把精力放在交互细节、状态管理与无障碍上,比引入一个庞大的播放器库更有价值。