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

名称类型必填默认值说明
urlstring—单直链(与 links 二选一,优先)
typestring'm3u8'与 url 配套
linksPlayLink[][]多线路列表(主入口)
linkCodestring—当前线路 code,支持 v-model:linkCode
startTimenumber0初始跳转秒数
volumenumber1音量 0-1
mutedbooleanfalse静音
autoplaybooleanfalse自动播放
loopbooleanfalse循环
preload'none' | 'metadata' | 'auto''metadata'预加载策略
controlsbooleantrue是否渲染原生 <audio controls>
onHistory((p: AudioHistoryParams) => void) | nullundefined三态:undefined 内置 /audio/doHistory、null 禁用、function 覆盖

Events

事件名载荷说明
readyel: HTMLAudioElementaudio 元素就绪并 HLS attach 完成
loadedmetadata—元数据加载完成
canplay—可播放
play—播放
pause—暂停
seekedcurrentTime: number跳转完成(整数秒)
timeupdatecurrentTime: number1s 节流的播放进度
update:currentTimecurrentTime: number500ms 节流,供 v-model:currentTime
ended—播放结束
errorerr: unknown播放错误。只报致命错误 —— 非致命(分片 404 / 网络抖动)由 hls.js 自行重试,不再打扰业务
update:linkCodecode: string切换线路后同步 v-model

defineExpose

方法说明
play()开始播放
pause()暂停
seek(time: number)跳转到指定秒数
destroy()销毁 hls 实例
switchLink(code: string)切换到指定 code 的线路(保留进度)
getElement()获取原生 <audio> DOM 引用
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 即可工作

相关组件