dahua-webrtc
v1.0.9
Published
WebRTC Video Player — 基于 HTTP 信令协议的 WebRTC 直播播放器,兼容 @liveqing/liveplayer-v3 API 风格
Maintainers
Readme
WebRTC Player
基于 HTTP 信令协议的 WebRTC 直播播放器 — API 兼容
@liveqing/liveplayer-v3风格
特性
- ✅ 纯 WebRTC — 基于 HTTP POST 信令协议,
RTCPeerConnection+ SDP 交换 + ICE - ✅ 零依赖 — 核心库无外部运行时依赖(仅需浏览器 WebRTC API)
- ✅ API 兼容 — 方法、事件命名与
@liveqing/liveplayer-v3保持一致 - ✅ EventEmitter —
on()/off()/once()事件模型 - ✅ 支持 ESM / UMD — 支持 import、require、全局变量三种引入方式
- ✅ 框架无关 — 原生 JS 编写,可在 Vue / React / Angular / Svelte 中直接使用
安装
npm install dahua-webrtc或直接引入:
<script type="module">
import WebRTCPlayer from './node_modules/dahua-webrtc/src/player.js';
</script>快速开始
import WebRTCPlayer from 'dahua-webrtc';
import 'dahua-webrtc/src/style.css';
const player = new WebRTCPlayer({
videoUrl: 'webrtc://192.168.1.100:9001/cam/realmonitor?channel=1&subtype=0',
el: '#player-container',
muted: false,
autoplay: true,
});
player.on('play', () => console.log('开始播放'));
player.on('error', (err) => console.error('播放错误:', err));信令协议
播放器自动从 webrtc://host:port/path 截取信令服务器地址 (http://host:port),通过 HTTP POST 与服务器通信:
| 步骤 | 方法 | 请求体 | 说明 |
|------|------|--------|------|
| 1. Offer | POST /webrtc/play/ | { streamurl, sdp, mediatype } | 发送本地 Offer SDP |
| 2. Answer | ← 响应 | { code, sessionid, sdp } | 接收远端 Answer SDP |
| 3. ICE | POST /webrtc/play/ | { sessionid, candidate } | 交换 ICE Candidate |
| 4. Close | POST /webrtc/play/ | { sessionid, close: true } | 关闭会话 |
API 文档
构造函数
new WebRTCPlayer(options)Options
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| videoUrl | string | '' | WebRTC 拉流地址 (webrtc://host:port/path) |
| el | string\|HTMLElement | null | 挂载容器(CSS 选择器或 DOM 元素) |
| autoplay | boolean | true | 是否自动播放 |
| muted | boolean | false | 默认静音 |
| controls | boolean | true | 显示原生 video controls |
| aspect | string | '16:9' | 宽高比:'16:9' / '4:3' / 'fullscreen' |
| poster | string | '' | 封面图 URL |
| stretch | boolean | false | 拉伸填充 |
| live | boolean | true | 直播模式 |
| timeout | number | 15000 | 信令请求超时 (ms) |
| iceServers | object[] | Google STUN | 自定义 ICE 服务器列表 |
| signalingPath | string | '/webrtc/play/' | 信令 API 路径 |
| videoAttrs | object | {} | 额外 video 元素属性 |
方法
| 方法 | 返回值 | 说明 |
|------|--------|------|
| play(url?) | Promise<this> | 开始播放。可选传入拉流地址 |
| pause() | this | 暂停播放(不关闭 WebRTC 连接) |
| resume() | this | 恢复播放 |
| stop() | this | 停止播放并关闭 WebRTC 连接 |
| destroy() | this | 销毁播放器(完全清理,不可恢复) |
| mount(el) | this | 挂载到指定容器 |
| snap(opts?) | string\|null | 截取当前帧,返回 Base64 数据 |
| paused() | boolean | 是否暂停 |
| getCurrentTime() | number | 获取当前播放时间(秒) |
| getDuration() | number | 获取时长(直播返回 Infinity) |
| getMuted() | boolean | 获取静音状态 |
| setMuted(v) | this | 设置静音 |
| getVolume() | number | 获取音量 (0~1) |
| setVolume(v) | this | 设置音量 (0~1) |
| isFullscreen() | boolean | 是否全屏 |
| requestFullscreen() | this | 进入全屏 |
| exitFullscreen() | this | 退出全屏 |
| toggleFullscreen() | this | 切换全屏 |
| getState() | string | 获取播放器状态 |
| getVideoElement() | HTMLVideoElement\|null | 获取底层 video 元素 |
| getPeerConnection() | RTCPeerConnection\|null | 获取 RTCPeerConnection 实例 |
snap() 选项
player.snap({
type: 'image/jpeg', // 图片格式
quality: 0.9, // 压缩质量
download: false, // 是否自动下载
});事件
使用 EventEmitter 模式注册:
player.on('eventName', callback);
player.off('eventName', callback);
player.once('eventName', callback);| 事件名 | 参数 | 说明 |
|--------|------|------|
| play | currentTime | 开始 / 恢复播放 |
| pause | currentTime | 暂停 |
| ended | — | 播放结束 |
| error | Error | 播放器错误 |
| snapOutside | dataUrl | 调用 snap() 后触发 |
| fullscreen | isFullscreen | 全屏状态变化 |
| timeupdate | currentTime | 播放进度更新 (250ms) |
| message | { type, message } | 日志消息 |
| iceConnectionStateChange | state | ICE 连接状态变化 |
| connectionStateChange | state | 连接状态变化 |
状态枚举
import { PLAYER_STATES } from 'dahua-webrtc';
PLAYER_STATES.IDLE; // 'idle' — 空闲 / 已停止
PLAYER_STATES.CONNECTING; // 'connecting' — 建立连接中
PLAYER_STATES.PLAYING; // 'playing' — 播放中
PLAYER_STATES.PAUSED; // 'paused' — 已暂停
PLAYER_STATES.ERROR; // 'error' — 错误工具函数
import {
parseServerUrl, // 从 webrtc:// 提取信令服务器地址
cleanSdp, // 清洗 SDP 非标准行
isValidWebrtcUrl, // 验证 URL 格式
extractUfrag, // 提取 SDP 中的 ICE ufrag
captureFrame, // 从 <video> 截取图片帧
downloadImage, // 下载 Base64 图片
checkWebRTCSupport, // 检测浏览器 WebRTC 支持
} from 'dahua-webrtc';CSS 样式
播放器生成以下 DOM 结构,可通过 CSS 类名自定义样式:
<div class="webrtc-player webrtc-player--16-9" data-state="playing">
<div class="webrtc-player__placeholder">
<div class="webrtc-player__placeholder-icon">📡</div>
<div class="webrtc-player__placeholder-text">等待连接...</div>
</div>
<video class="webrtc-player__video" muted autoplay playsinline controls></video>
</div>Vue 3 示例
<template>
<div>
<div ref="playerContainer"></div>
<button @click="play">播放</button>
<button @click="snap">截图</button>
<button @click="destroy">销毁</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import WebRTCPlayer from 'dahua-webrtc';
import 'dahua-webrtc/src/style.css';
const playerContainer = ref(null);
let player = null;
onMounted(() => {
player = new WebRTCPlayer({
el: playerContainer.value,
videoUrl: 'webrtc://192.168.1.100:9001/cam/realmonitor',
});
player.on('error', (err) => console.error(err));
player.on('snapOutside', (dataUrl) => {
// 处理截图
});
});
const play = () => player.play();
const snap = () => player.snap();
const destroy = () => player.destroy();
onBeforeUnmount(() => {
player?.destroy();
});
</script>React 示例
import { useEffect, useRef } from 'react';
import WebRTCPlayer from 'dahua-webrtc';
import 'dahua-webrtc/src/style.css';
function App() {
const containerRef = useRef(null);
const playerRef = useRef(null);
useEffect(() => {
playerRef.current = new WebRTCPlayer({
el: containerRef.current,
videoUrl: 'webrtc://192.168.1.100:9001/cam/realmonitor',
});
playerRef.current.on('error', console.error);
return () => playerRef.current?.destroy();
}, []);
return <div ref={containerRef} />;
}浏览器兼容性
| 浏览器 | 最低版本 | |--------|----------| | Chrome | 56+ | | Edge | 79+ | | Firefox | 44+ | | Safari | 11+ | | Opera | 43+ |
需要浏览器支持 RTCPeerConnection API。
License
MIT
Copyright © dahua 2024
