@solumon/media
v0.1.2
Published
Unified media playback manager for Vue 3: mutual-exclusive playback and auto pause/resume on page visibility changes.
Maintainers
Readme
@solumon/media
Vue 3 页面级媒体播放管理库:
- 统一管理:页面内可播放的媒体统一注册到单例
MediaManager - 互斥播放:同一时刻最多一个媒体在播,播放新的自动暂停旧的
- 后台自动暂停:页面切入后台自动暂停,回前台恢复播放(用户主动暂停的不会被误恢复)
- 音视频通用:基于
MediaController抽象与HTMLMediaElement,<audio>/<video>均可接入
架构
components(UI 层,不发布)
↓
hooks/useMedia.ts(适配层:注册/注销 + 响应式播放态)
↓
core/media-manager.ts(核心层:注册表、互斥、后台打断记录)
core/lifecycle-watcher.ts(visibilitychange + pagehide/pageshow 去重)
plugin.ts(Vue 插件:安装生命周期监听)核心层为纯 TS(仅依赖 Vue 响应式 API),不依赖任何组件体系;依赖方向单向:components → hooks → core。
安装
npm install @solumon/media
# 或
pnpm add @solumon/media要求
vue >= 3.3(peerDependency)。
使用
应用入口以 Vue 插件方式安装(一次即可):
import { createApp } from 'vue'
import { MediaManagerPlugin } from '@solumon/media'
import App from './App.vue'
createApp(App).use(MediaManagerPlugin).mount('#app')组件内接入媒体元素:
<script setup lang="ts">
import { ref } from 'vue'
import { useMedia } from '@solumon/media'
const audioEl = ref<HTMLAudioElement | null>(null)
const { isPlaying, isLoading, toggle } = useMedia('my-track', audioEl)
</script>
<template>
<audio ref="audioEl" src="/song.mp3" preload="none" />
<button @click="toggle">
{{ isLoading ? '加载中' : isPlaying ? '暂停' : '播放' }}
</button>
</template>非插件场景也可手动安装生命周期监听:
import { installLifecycleWatcher, mediaManager } from '@solumon/media'
installLifecycleWatcher(mediaManager)API
| 导出 | 说明 |
| ---------------------------------- | -------------------------------------------------------------------------- |
| MediaManagerPlugin | Vue 插件,app.use 后自动安装前后台监听 |
| mediaManager | 页面级单例,currentId(只读响应式)、play(id)、pause(id)、register(id, controller) |
| useMedia(id, elementRef) | 组件适配 hook,返回 isPlaying / isLoading / play / pause / toggle |
| installLifecycleWatcher(manager) | 安装前后台监听,返回卸载函数 |
| MediaController | 控制器接口(play(): Promise<void> / pause(): void),用于接入自定义媒体实现 |
音频列表建议 preload="none",进页面零请求,点播放才加载;音频数量达到几十上百时建议改用共享单播放器(MediaManager 内部实现可替换,组件层 API 不变)。
开发
在 monorepo 根目录:
pnpm install
pnpm dev:media # 启动 packages/media/playground,修改 src/ 即时热更新
pnpm --filter @solumon/media build # vue-tsc 类型检查 + tsdown 打包playground 验证清单:
- 互斥:播放 A 后点击 B,A 自动暂停
- 后台暂停:播放中切换标签页,音频暂停;切回自动恢复
- 不误恢复:手动暂停后切后台再回来,不会自动播放
- 加载态:点播放大文件时按钮先转圈(
isLoading),缓冲足够后切为暂停图标
