wrplayer
v1.1.0
Published
A unified web video player SDK supporting WebRTC, HLS, DASH and other formats with PTZ camera control
Maintainers
Readme
WRPlayer
WRPlayer 是一个统一的 Web 视频播放器 SDK,提供一致的 API 来播放多种流媒体协议(WebRTC、HLS、DASH、MP4 等),并可在原生 HTML、Next.js/React 与 Vue 3 环境中复用同一套核心代码。
团队集成文档(npm 安装、Vue/React 示例、PTZ/对讲、生产部署):见 docs/INTEGRATION.md
npm 包:https://www.npmjs.com/package/wrplayer
特性
- 多协议支持: WebRTC、HLS、DASH、MP4 等
- 自动类型检测: 可从 URL 自动识别播放类型
- 统一 API:
play/pause/stop/on/off等一致方法与事件 - UMD + ESM 构建: 一次构建,既可
<script>引入(UMD),也可模块化import(ESM) - SSR 友好: 核心兼容 SSR,Next.js 适配器按需在客户端初始化
- 模块化架构:
core(核心)与adapters(框架适配)清晰分离 - WebRTC 增强: 支持禁用音频(规避特定浏览器/流的音频解复用问题),并内置防重复协商的状态管理
项目结构
wrplayer/
├── core/ # 核心播放器逻辑
│ ├── WRPlayer.js # 播放器主类(直接内置 ZLMRTCClient)
│ └── ZLMRTCClient.js # WebRTC 客户端库(已作为模块被 WRPlayer 引入)
├── adapters/
│ ├── next/ # Next.js / React 适配器组件
│ ├── react/ # React Hook 适配器
│ ├── vue/ # Vue 3 组合式 API 适配器
│ └── vanilla/ # 原生 JS 包装工具
├── demo/
│ ├── html/ # 原生 HTML + UMD 示例(可直接双击打开)
│ ├── next/ # Next.js 示例项目
│ ├── vue/ # Vue 3 + Vite 示例项目
│ └── shared/ # 演示页共享样式
├── dist/ # 构建产物(UMD / ESM)
├── rollup.config.js # Rollup 构建配置
├── package.json # 根项目脚本与依赖
└── README.md构建
在项目根目录执行:
npm install
npm run build生成产物:
dist/wrplayer.umd.js(浏览器<script>直接引入)dist/wrplayer.esm.js(ES 模块)
提示:若要消除 Node 关于 ESM 的提示,可在根
package.json增加"type": "module"。
安装
WRPlayer 目前通过 Git 仓库或本地路径分发(尚未发布到 npm)。接入方需先获取源码并构建:
# 方式一:克隆仓库
git clone https://gitee.com/warom-org/wrplayer.git
cd wrplayer
npm install && npm run build
# 方式二:在业务项目的 package.json 中引用
# "wrplayer": "git+https://gitee.com/warom-org/wrplayer.git"
# 或 "wrplayer": "file:../wrplayer"
npm install
cd node_modules/wrplayer && npm install && npm run build构建完成后,dist/wrplayer.esm.js 与 dist/wrplayer.umd.js 即可被引用。
使用方法
A. 原生 HTML(通过 UMD 包)
无需打包工具,只需在页面引入 UMD 文件:
<!-- 1) 引入 UMD 包 -->
<script src="./dist/wrplayer.umd.js"></script>
<!-- 2) 视频与脚本 -->
<video id="player" controls autoplay muted style="width: 800px; height: 450px;"></video>
<script>
const player = new WRPlayer({
element: document.getElementById('player'),
url: 'http://your-host/index/api/webrtc?...',
// 可选:明确类型,也可不写走自动识别
type: 'webrtc',
autoplay: true,
debug: true
// 注意:ZLMRTCClient 已内置到 UMD 包,无需手动传入
});
player.on('ready', () => console.log('ready'));
player.on('play', () => console.log('play'));
player.on('connectionstatechange', ({ state }) => console.log('conn:', state));
player.on('error', (err) => console.error('error', err));
</script>音频控制策略:为避免常见的 SDP 协商问题,默认禁用音频。若需要音频,可手动启用:
<script>
// 方案一:默认配置(推荐)- 仅视频,避免 SDP 协商问题
const player = new WRPlayer({
element: document.getElementById('player'),
url: 'http://your-host/index/api/webrtc?...',
autoplay: true,
debug: true
// recvAudio 默认为 false,避免 "Failed to set up audio demuxing" 错误
});
// 方案二:明确禁用音频(与默认行为相同)
const playerVideoOnly = new WRPlayer({
element: document.getElementById('player'),
url: 'http://your-host/index/api/webrtc?...',
autoplay: true,
debug: true,
recvAudio: false, // 明确禁用音频
recvVideo: true // 明确启用视频(默认值)
});
// 方案三:启用音频(实验性,有自动回退策略)
const playerWithAudio = new WRPlayer({
element: document.getElementById('player'),
url: 'http://your-host/index/api/webrtc?...',
autoplay: true,
debug: true,
recvAudio: true // 启用音频,如失败会自动回退到仅视频
});
</script>常见的 WebRTC 音频问题:
如果您遇到类似的错误:
Failed to set up audio demuxing for mid='1'Session error description: Failed to set up audio demuxing
这通常是由于客户端与流媒体服务器的音频编解码器不匹配导致的。解决方案:
- 推荐:使用
recvAudio: false禁用音频接收 - 强制方案:如果仍有问题,使用
webrtcConfig强制禁用:const player = new WRPlayer({ element: document.getElementById('player'), url: 'http://your-host/index/api/webrtc?...', recvAudio: false, webrtcConfig: { audioEnable: false, // 强制禁用音频 transceiver videoEnable: true, // 确保视频启用 recvOnly: true // 确保仅接收模式 } }); - 检查流媒体服务器是否正确配置音频编码
- 如果必须使用音频,播放器会自动进行回退重试
B. Next.js / React
示例项目位于 demo/next/:
cd demo/next
npm install
npm run dev # 开发模式
# 或
npm run build && npm run start # 生产模式在页面中使用适配器组件:
'use client';
import WRPlayerComponent from '../../../adapters/next';
export default function Page() {
return (
<WRPlayerComponent
url="http://your-host/index/api/webrtc?..."
type="webrtc"
autoplay={true}
controls={true}
muted={true}
recvAudio={false} // 推荐禁用音频,避免 SDP 协商问题
recvVideo={true}
// 如果仍有音频协商问题,使用强制配置
webrtcConfig={{
audioEnable: false, // 强制禁用音频
videoEnable: true, // 确保视频启用
recvOnly: true // 确保仅接收模式
}}
onReady={() => console.log('播放器准备就绪')}
onError={(err) => console.error('播放错误:', err)}
debug={true}
/>
);
}说明:适配器已封装客户端初始化流程,SSR 环境下不会触发浏览器 API。
C. Vue 3
1. 在现有 Vue 3 项目中安装
# 假设已通过 Git 或 file: 方式安装 wrplayer(见上方「安装」章节)
npm install wrplayer
# 或 pnpm add wrplayer在 package.json 中确保 vue 版本 ≥ 3.0(wrplayer 将其声明为 optional peerDependency,按需安装即可)。
2. 运行官方示例
示例项目位于 demo/vue/:
cd demo/vue
cp .env.example .env.local # 配置 WVP_BASE_URL 与 SIP_DEFAULT_TOKEN
pnpm install # 或 npm install
pnpm dev # 开发模式,访问 http://localhost:51733. 使用 useWRPlayer(推荐)
useWRPlayer 是 Vue 3 组合式 API,封装了播放器生命周期、PTZ 与语音对讲能力:
<script setup>
import { reactive } from 'vue';
import { useWRPlayer } from 'wrplayer/adapters/vue';
const playerConfig = reactive({
url: 'http://your-host/index/api/webrtc?...',
type: 'webrtc', // 可选,省略时自动检测
autoplay: true,
debug: false,
recvAudio: false, // 推荐 false,避免 WebRTC 音频协商问题
// 可选:PTZ 云台(useProxy: true 时 apiUrl 走开发代理)
ptz: {
apiUrl: '/api/ptz',
apiKey: 'token',
deviceId: '34020000001320000009',
channelId: '34020000001320000009',
useProxy: true
},
// 可选:语音对讲
voiceIntercom: {
apiUrl: '/api/voice-intercom',
apiKey: 'token',
useProxy: true
}
});
const {
elementRef, // 绑定到 <video ref="elementRef">
player, // 底层 WRPlayer 实例(computed)
isReady, // 是否就绪
error, // 错误信息
ptzAvailable, // PTZ 是否可用
voiceIntercomAvailable, // 语音对讲是否可用
voiceIntercomStatus, // 对讲状态
play, pause, stop, // 播放控制
ptz, // PTZ API(computed,不可用时为 null)
voiceIntercom // 语音对讲 API(computed,不可用时为 null)
} = useWRPlayer(playerConfig);
// PTZ 示例
async function moveUp() {
if (ptz.value) await ptz.value.move('up', 50);
}
// 语音对讲示例
async function startTalk() {
if (voiceIntercom.value) {
await voiceIntercom.value.start('34020000001320000009', '34020000001320000009', false);
}
}
</script>
<template>
<video ref="elementRef" controls autoplay muted />
<button @click="moveUp" :disabled="!ptzAvailable">云台上</button>
<button @click="startTalk" :disabled="!voiceIntercomAvailable">开始对讲</button>
</template>切换播放地址时,修改 playerConfig.url 即可,Hook 会自动销毁并重建播放器:
playerConfig.url = ''; // 先清空可停止当前流
playerConfig.url = 'http://new-stream-url'; // 加载新地址4. 使用 WRPlayerComponent
适合快速嵌入、通过事件监听 PTZ/对讲回调的场景:
<script setup>
import { WRPlayerComponent } from 'wrplayer/adapters/vue';
const config = {
url: 'http://your-host/index/api/webrtc?...',
type: 'webrtc',
autoplay: true,
recvAudio: false
};
</script>
<template>
<WRPlayerComponent
:config="config"
class-name="my-player"
@ready="(player) => console.log('ready', player)"
@error="(err) => console.error('error', err)"
@ptz-event="({ event, data }) => console.log(event, data)"
@voice-intercom-event="({ event, data }) => console.log(event, data)"
/>
</template>5. Vite 开发代理(PTZ / 语音对讲)
浏览器直接请求 SIP 服务器会遇到 CORS,开发环境可在 vite.config.js 中配置代理(完整示例见 demo/vue/vite.config.js):
export default defineConfig({
server: {
proxy: {
'/api/ptz': {
target: 'http://your-sip-server:18082',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/ptz/, '/api/front-end')
},
'/api/voice-intercom': {
target: 'http://your-sip-server:18082',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/voice-intercom\/?/, '/')
}
}
}
});生产环境请用 Nginx 或后端网关实现相同转发,并在请求头注入 api-key。
6. Vue 3 集成注意事项
useWRPlayer在onMounted后初始化,onUnmounted时自动stop()释放资源config.url或config.type变化时会自动重建实例- WebRTC 自动播放需
<video muted autoplay>,或用户交互后再播放 - PTZ / 语音对讲配置建议在首次设置
url前写入playerConfig - 也可使用
WRPlayerVue2兼容 Vue 2 Options API(见wrplayer/adapters/vue导出)
API(核心类 WRPlayer)
构造函数
new WRPlayer(options)| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| options.element | HTMLVideoElement | 是 | 用于播放的 <video> 元素 |
| options.url | string | 是 | 流/视频 URL |
| options.type | string | 否 | webrtc/hls/dash/mp4,缺省自动检测 |
| options.autoplay | boolean | 否 | 默认 true |
| options.debug | boolean | 否 | 默认 false |
| options.dependencies.hlsPath | string | 否 | hls.js CDN 或本地路径(按需) |
| options.dependencies.dashPath | string | 否 | dash.js CDN 或本地路径(按需) |
| options.recvAudio | boolean | 否 | WebRTC 是否接收音频(默认 false,可设为 true 启用,支持回退策略) |
| options.recvVideo | boolean | 否 | WebRTC 是否接收视频(默认 true) |
| options.webrtcConfig | Object | 否 | 透传给 ZLMRTCClient.Endpoint 的高级配置 |
注意:
ZLMRTCClient已在内部以 ES 模块方式引入并随构建打包,无需在外部传入。
方法
| 方法 | 说明 |
| --- | --- |
| play() | 开始/继续播放(WebRTC 下防重复协商) |
| pause() | 暂停(对 WebRTC 无效) |
| stop() | 停止并清理资源(WebRTC 下会重置内部状态) |
| on(event, cb) | 绑定事件 |
| off(event, cb) | 解绑事件 |
| getPlayer() | 获取底层实例(如 Hls.js) |
事件
| 事件 | 数据 | 说明 |
| --- | --- | --- |
| ready | { streams? } | 播放器就绪 |
| play | void | 开始播放 |
| pause | void | 暂停 |
| ended | void | 播放结束 |
| error | { type, details } | 错误事件 |
| connectionstatechange | { state } | WebRTC 连接状态:connecting/connected/failed/disconnected |
常见问题
- 浏览器自动播放策略:若需自动播放,建议设置
muted=true,或在用户交互后再调用play()。 - 音频解复用报错(WebRTC):默认已禁用音频以避免此问题。如需音频可设
recvAudio: true,遇错误时播放器会自动回退到仅视频模式。 - CDN 动态依赖:仅 HLS/DASH 按需加载
hls.js/dash.js,可通过dependencies.hlsPath/dashPath指定路径。
许可证
MIT
