跳到主要内容
Esc

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 就建立在它们之上;只有在你需要自己管理信令和生命周期时才用得到。