文档目录
Web SDK
@rerinku/player 是 Rerinku View SDK 的网页部分:纯 TypeScript,不依赖任何前端框架,以 Apache-2.0 开源。
OnboardClient:Rerinku View 开放接口的客户端,负责设备、码流、缩略图、运行状态和 WebRTC 信令。RerinkuPlayer:在你提供的<video>上播放设备的实时画面(WebRTC)或录像(HLS),断线自动重连。它不带任何界面,状态通过 DOM 事件发出,用法和HTMLMediaElement一样。@rerinku/player/engine:底层引擎,给自己管理信令和生命周期的场景用。
安装
npm install @rerinku/player
ES 模块与类型定义约 10 KB(gzip)。hls.js 只在播放录像时才按需加载。不用打包工具的页面可以直接引入 IIFE 版本,它会挂一个全局对象 Rerinku:
<script src="https://unpkg.com/@rerinku/player/dist/rerinku-player.iife.js"></script>
快速开始
import { OnboardClient, RerinkuPlayer } from "@rerinku/player";
// 1. 连接一台 Rerinku View。查看令牌只读,可以放在公开网页里。
const client = new OnboardClient({
baseUrl: "https://n1234.nodes.rerinku.com",
token: "<查看令牌>",
});
// 2. 在 <video> 上创建播放器。它会把元素设成静音自动播放。
const video = document.querySelector("video")!;
const player = new RerinkuPlayer(video, { client });
player.addEventListener("statuschange", (e) => console.log(e.detail.state));
// 3. 选一台设备开始播放。出第一帧时 load() 完成;断线后播放器自己重连。
const devices = await client.listDevices();
await player.load({ kind: "live", device: devices[0] });
// 不再需要时
player.destroy();
不用打包工具时,写法完全一样,只是从全局对象取类:
<video muted playsinline autoplay></video>
<script src="https://unpkg.com/@rerinku/player/dist/rerinku-player.iife.js"></script>
<script>
const { OnboardClient, RerinkuPlayer } = Rerinku;
const client = new OnboardClient({ baseUrl: "https://n1234.nodes.rerinku.com", token: "<查看令牌>" });
const player = new RerinkuPlayer(document.querySelector("video"), { client });
client.listDevices().then((devices) => player.load({ kind: "live", device: devices[0] }));
</script>
SDK 仓库的 examples/quickstart/ 里有完整的网页版(index.html,带摄像头切换和状态显示,直接打开即可)和 TypeScript 版(main.ts)。
认证
任何网站的网页都可以跨域调用 Rerinku View,但来自别的网站的请求必须带令牌:
- 公开网页(官网演示、门店大屏、你自己的网站):在 Rerinku View 的 设置 → 开发者 里生成只读查看令牌,用
token传入,不要调用login()。它只能列设备(敏感字段已去掉)、取缩略图、读运行状态、拉实时画面。 - 服务端程序和原生 App:调用
client.login(password),和手机 App 一样完成绑定;Rerinku View 没设访问密码时不需要密码。 - 别的网站的网页只有在 Rerinku View 设了访问密码时,才能通过
login()拿到完整令牌。
令牌只保存在内存里,要不要持久化由你决定:构造时用 token 传入,并监听 tokenchange 事件,它会在登录、退出,以及服务端判定令牌已被撤销时触发。
const client = new OnboardClient({ baseUrl: "http://192.168.1.10:8080", token: saved });
client.addEventListener("tokenchange", (e) => save(e.detail)); // 撤销后 e.detail 为 null
if (!client.token) {
await client.login("", { name: "门店看板", installId: "dash-0001" }); // 设了访问密码就填密码
}
同一个 installId 再次登录只会换新令牌,不会多出一条授权。所有令牌都列在 设置 → 开发者 → 已授权的应用 里,可以随时撤销。
OnboardClient
new OnboardClient({ baseUrl, token, fetch })
| 选项 | 说明 |
|---|---|
baseUrl |
Rerinku View 的地址,如 https://n1234.nodes.rerinku.com;空串表示与页面同源 |
token |
之前登录得到的令牌,或查看令牌 |
fetch |
自定义 fetch(测试、服务端渲染时用) |
所有方法都返回 Promise,最后一个参数都接受 { signal }(AbortSignal)用于取消。请求失败时抛出 OnboardAPIError(带 status 和 code,如 invalid_token),信令失败时抛出 SignalingError。
| 方法 | 说明 |
|---|---|
getInfo() |
服务器的 ID、名称、接口版本;不需要令牌 |
login(password, { name, installId, appVersion }) |
用访问密码换令牌 |
logout() |
撤销当前令牌 |
listDevices() |
设备列表 OnboardDevice[] |
listStreams(deviceId) |
设备的码流(主码流、子码流、通道) |
getThumbnail(deviceId) |
缩略图 JPEG 的 Blob;<img> 带不了令牌,用 URL.createObjectURL 显示 |
getRuntime(deviceId) |
设备此刻的运行状态(tempC、cpuPct 等);平台对同一台设备 2 秒内复用结果,轮询别比这更快 |
getIceServers() |
实时画面用的 STUN/TURN;凭据会过期,不要长期缓存 |
sendOffer(deviceId, sdp, { streamId }) |
WebRTC 信令:提交 offer,返回 answer |
属性:baseUrl、token(可赋值)。事件:tokenchange(detail 是新令牌或 null)。
RerinkuPlayer
new RerinkuPlayer(video, { client, manageVideo })
| 选项 | 说明 |
|---|---|
client |
OnboardClient,或任何实现了 sendOffer 和 getIceServers 的对象;播放实时画面必须提供 |
manageVideo |
默认 true:把元素设为静音、行内、自动播放(浏览器只允许静音自动播放)。传 false 则完全不动元素 |
| 成员 | 说明 |
|---|---|
load(source) |
播放 { kind: "live", device, streamId? } 或 { kind: "hls", url };传 null 停止 |
unload() |
停止播放并释放连接 |
retry() |
立刻重连:设备离线等待期间,或可重试的错误之后 |
destroy() |
释放全部资源 |
status |
当前状态 PlayerStatus |
source |
最近一次 load() 传入的源 |
load() 在第一帧出现在画面上时完成;播放器停在错误上时以 PlayerError 拒绝;被新的 load()、unload() 或 destroy() 打断时以名为 AbortError 的 DOMException 拒绝。实时源在等待离线设备时 Promise 保持未完成,这期间请看 statuschange。
| 事件 | detail |
|---|---|
statuschange |
新的 PlayerStatus |
stats |
实时连接的统计 LiveConnectionStats(大约每 2 秒一次),结束时为 null |
error |
PlayerError(code、detail、retryable) |
streamId 选择设备的某一路码流,例如分辨率较低的子码流;不传就播放设备的默认码流。每次重连之前,播放器都会重新获取 TURN 凭据。
播放状态
state |
含义 |
|---|---|
idle |
没有源 |
connecting |
正在建立连接,code 说明在等什么 |
playing |
画面已经出来 |
offline |
正在自动重连。reason 为 device(服务端确认设备离线)或 network;还有 retryInMs、attempt |
error |
需要处理。retryable 表示 retry() 能否恢复 |
message 是英文的兜底文案;需要本地化时,按 code 选择你自己的文案:
code |
含义 |
|---|---|
connecting、waiting_frame、waiting_keyframe |
正在建立连接、等待画面 |
stalled |
出过画面后流停了,画面停在最后一帧 |
relay_switch |
直连质量差,正在切换到云端转发 |
no_signaling |
没有提供 client |
signaling_rejected |
服务端拒绝了这次会话,detail 是服务端的错误码 |
codec_unsupported |
浏览器不支持这种编码,detail 是编码名 |
h265_unsupported |
浏览器没有 WebRTC 的 H.265 解码(Safari 有,Chrome 需要硬件解码) |
hls_failed、hls_media_failed、hls_unsupported、hls_player_load_failed |
录像播放失败 |
浏览器与限制
- 实时画面需要支持 WebRTC 的现代浏览器。H.264 各浏览器都能播;H.265 取决于浏览器的 WebRTC 解码能力,SDK 会在建立连接前检查,不支持时直接给出
h265_unsupported,不会白白拉流。 - 画面默认静音自动播放;需要声音时,在用户操作之后取消静音。
- 录像(HLS)的地址需要由你自己的后端提供并处理认证:浏览器里的 HLS 请求带不了
Authorization请求头。
底层引擎
@rerinku/player/engine 导出 createWebRTCEngine(video, source, callbacks, options) 和 createHLSEngine(video, source, callbacks)。一个引擎对应一次会话,信令通过 options.offer 注入,状态通过回调返回。RerinkuPlayer 就建立在它们之上;只有在你需要自己管理信令和生命周期时才用得到。