SwAudioPlayer

SwAudioPlayer 是基於 HLS.js + 原生 <audio> 的音訊播放器。 設計理念與 SwVideoPlayer 完全對齊, 適用於有聲小說、Podcast、廣播、背景音樂等場景。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)
<!-- 內建預設 -->
<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() {
  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 組合

加载中...
<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 已足夠,保持元件簡潔
  • switchLink 保留進度:與 SwVideoPlayer 一致,切換線路不會從頭開始
  • 事件只繫結一次:audio DOM 事件在 onMounted 時繫結一次,切換線路只動 hls 實例
  • autoplay 限制:瀏覽器通常要求 muted: true 才能自動播放
  • iOS Safari 原生支援 HLS(≥ 10),無需 Hls.js 即可運作

相關元件