SwAudioPlayer
SwAudioPlayer 是基于 HLS.js + 原生 <audio> 的音频播放器。
设计哲学与 SwVideoPlayer 完全对齐,
适用于有声小说、播客、广播、背景音乐等场景。SSR 安全。
音频源(二选一)
- 直链模式:通过
url+type指定单个音频地址 - 多线路模式:通过
links提供线路列表,配合v-model:linkCode切换
基础用法
最简用法:本地 m4a 直链 + 原生 controls(type 与 url 配套;docs 站无后端故 :on-history="null")。
基础播放(m4a 直链 + 原生控件)
加载中...
<!-- 多线路模式(推荐:与后端 API 形态一致) -->
<SwAudioPlayer :links="audio.play_links" />
<!-- 直链模式;autoplay 必配 muted(移动端浏览器硬性要求,否则被静默拒绝,见 SVP-001) -->
<SwAudioPlayer url="https://example.com/song.m3u8" autoplay muted />
多线路切换 + v-model:linkCode
<script setup lang="ts">
const currentCode = ref('hq')
const links = [
{ code: 'hq', id: 1, lid: 1, m3u8_url: 'https://cdn.example.com/hq.m3u8' },
{ code: 'lq', id: 1, lid: 2, m3u8_url: 'https://cdn.example.com/lq.m3u8' },
]
</script>
<template>
<SwAudioPlayer v-model:link-code="currentCode" :links="links" />
<button @click="currentCode = 'lq'">切换标清</button>
</template>
切换线路时自动保留当前进度——记录 currentTime → 销毁旧 hls 实例 → 重建并 attach 新源 → 恢复进度并 play。
断点续播
<script setup lang="ts">
const savedTime = ref(Number(localStorage.getItem('audio_seek') || 0))
function handleTimeupdate(currentTime: number) {
localStorage.setItem('audio_seek', String(currentTime))
}
</script>
<template>
<SwAudioPlayer
:links="links"
:start-time="savedTime"
@timeupdate="handleTimeupdate"
/>
</template>
事件监听
play / pause / 1s 节流 timeupdate / ended + v-model:currentTime。
事件日志 + v-model:currentTime
加载中...
播放记录上报(onHistory 三态)
onHistory 默认零配置——内置走 POST /audio/doHistory(旧后端约定,不带 event 字段)。
undefined(默认):内置上报null:完全关闭上报function:覆盖内置实现,业务侧自行处理(接收完整AudioHistoryParams,含event/view_time/code)
<!-- 内置默认 -->
<SwAudioPlayer :links="links" />
<!-- 关闭上报 -->
<SwAudioPlayer :links="links" :on-history="null" />
<!-- 自定义上报 -->
<SwAudioPlayer
:links="links"
:on-history="(p) => stat.report('audio_play', p)"
/>
通过 ref 命令式控制
<script setup lang="ts">
const audioRef = ref()
function pause() {
audioRef.value?.pause()
}
function jumpToBookmark() {
audioRef.value?.seek(120)
}
function switchLine() {
audioRef.value?.switchLink('lq')
}
function getNativeElement() {
// 拿到原生 <audio> 元素,可调用任意原生 API
const el = audioRef.value?.getElement()
if (el) console.log(el.duration)
}
</script>
<template>
<SwAudioPlayer ref="audioRef" :links="links" />
</template>
隐藏原生控件(自定义 UI)
:controls=false + ref 自绘控制
加载中...
多线路 v-model:linkCode 续播
加载中...
loop + volume + preload 组合
加载中...
<!-- controls=false 后业务可基于 emit 事件 + ref 方法实现自定义播放面板 -->
<SwAudioPlayer
ref="audioRef"
:links="links"
:controls="false"
@play="isPlaying = true"
@pause="isPlaying = false"
@timeupdate="(t) => (currentTime = t)"
/>
Props
| 名称 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
url | string | — | 单直链(与 links 二选一,优先) | |
type | string | 'm3u8' | 与 url 配套 | |
links | PlayLink[] | [] | 多线路列表(主入口) | |
linkCode | string | — | 当前线路 code,支持 v-model:linkCode | |
startTime | number | 0 | 初始跳转秒数 | |
volume | number | 1 | 音量 0-1 | |
muted | boolean | false | 静音 | |
autoplay | boolean | false | 自动播放 | |
loop | boolean | false | 循环 | |
preload | 'none' | 'metadata' | 'auto' | 'metadata' | 预加载策略 | |
controls | boolean | true | 是否渲染原生 <audio controls> | |
onHistory | ((p: AudioHistoryParams) => void) | null | undefined | 三态:undefined 内置 /audio/doHistory、null 禁用、function 覆盖 |
Events
| 事件名 | 载荷 | 说明 |
|---|---|---|
ready | el: HTMLAudioElement | audio 元素就绪并 HLS attach 完成 |
loadedmetadata | — | 元数据加载完成 |
canplay | — | 可播放 |
play | — | 播放 |
pause | — | 暂停 |
seeked | currentTime: number | 跳转完成(整数秒) |
timeupdate | currentTime: number | 1s 节流的播放进度 |
update:currentTime | currentTime: number | 500ms 节流,供 v-model:currentTime |
ended | — | 播放结束 |
error | err: unknown | 播放错误。只报致命错误 —— 非致命(分片 404 / 网络抖动)由 hls.js 自行重试,不再打扰业务 |
update:linkCode | code: string | 切换线路后同步 v-model |
defineExpose
| 方法 | 说明 |
|---|---|
play() | 开始播放 |
pause() | 暂停 |
seek(time: number) | 跳转到指定秒数 |
destroy() | 销毁 hls 实例 |
switchLink(code: string) | 切换到指定 code 的线路(保留进度) |
getElement() | 获取原生 <audio> DOM 引用 |
PlayLink / AudioHistoryParams 类型
interface PlayLink {
code: string
id: number | string
lid: number | string
m3u8_url: string
}
interface AudioHistoryParams {
event: 'audio_play' | 'audio_complete'
view_time: number
id?: number | string
lid?: number | string
code: string
time: number
}
注意事项
- 不带 Artplayer:audio 用原生
<audio>+ Hls.js 已经足够(无需控制条菜单、画中画、全屏等 video 能力),保持组件简洁 - switchLink 保留进度:与 SwVideoPlayer 一致,切换线路不会从头开始
- 事件只绑定一次:audio DOM 事件在
onMounted时绑定一次,切换线路只动 hls 实例(避免监听堆叠) - autoplay 限制:浏览器通常要求
muted: true才能自动播放 - iOS Safari 原生支持 HLS(≥ 10),无需 Hls.js 即可工作
相关组件
- SwVideoPlayer — 视频播放器(Artplayer + HLS)
- SwVideoPreview — 静音循环预览