Skip to content
Esc

Web SDK

On this page

@rerinku/player is the web part of the Rerinku View SDK: plain TypeScript with no dependency on any front-end framework, open source under Apache-2.0.

  • OnboardClient: a client for Rerinku View’s open API. It handles devices, streams, thumbnails, runtime status and WebRTC signaling.
  • RerinkuPlayer: plays a device’s live video (WebRTC) or recordings (HLS) on a <video> you provide, and reconnects automatically after a disconnect. It has no UI of its own. Its status comes as DOM events, and you use it the same way as an HTMLMediaElement.
  • @rerinku/player/engine: the low-level engines, for cases where you manage signaling and lifecycle yourself.

Installation

npm install @rerinku/player

The ES modules and type definitions are about 10 KB (gzip). hls.js is loaded on demand, only when a recording plays. Pages without a bundler can load the IIFE build directly. It adds a global object, Rerinku:

<script src="https://unpkg.com/@rerinku/player/dist/rerinku-player.iife.js"></script>

Quick start

import { OnboardClient, RerinkuPlayer } from "@rerinku/player";

// 1. Connect to a Rerinku View. A view token is read-only, so it can go in a public web page.
const client = new OnboardClient({
  baseUrl: "https://n1234.nodes.rerinku.com",
  token: "<view token>",
});

// 2. Create a player on a <video>. It sets the element to muted autoplay.
const video = document.querySelector("video")!;
const player = new RerinkuPlayer(video, { client });
player.addEventListener("statuschange", (e) => console.log(e.detail.state));

// 3. Pick a device and start playing. load() resolves on the first frame; after a disconnect, the player reconnects by itself.
const devices = await client.listDevices();
await player.load({ kind: "live", device: devices[0] });

// When you no longer need it
player.destroy();

Without a bundler, the code is exactly the same, except that the classes come from the global object:

<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: "<view token>" });
  const player = new RerinkuPlayer(document.querySelector("video"), { client });
  client.listDevices().then((devices) => player.load({ kind: "live", device: devices[0] }));
</script>

examples/quickstart/ in the SDK repository has a complete web page version (index.html, with camera switching and a status display; just open it) and a TypeScript version (main.ts).

Authentication

Web pages on any website can call Rerinku View across origins, but requests from other websites must carry a token:

  • Public web pages (a demo on an official website, a store display screen, your own website): generate a read-only view token under Settings → Developer in Rerinku View and pass it as token. Don’t call login(). A view token can only list devices (with sensitive fields removed), fetch thumbnails, read runtime status and pull live video.
  • Server-side programs and native apps: call client.login(password) to bind, just like the mobile app. No password is needed when Rerinku View has no access password.
  • Web pages on other websites can get a full token through login() only when Rerinku View has an access password set.

The token is kept only in memory; whether to persist it is up to you. Pass it in with token when you construct the client, and listen for the tokenchange event. It fires on login, on logout, and when the server determines that the token has been revoked.

const client = new OnboardClient({ baseUrl: "http://192.168.1.10:8080", token: saved });
client.addEventListener("tokenchange", (e) => save(e.detail)); // e.detail is null after revocation
if (!client.token) {
  await client.login("", { name: "Store dashboard", installId: "dash-0001" }); // pass the access password if one is set
}

Logging in again with the same installId only replaces the token; it doesn’t add another authorization. Every token is listed under Settings → Developer → Authorized apps, where you can revoke it at any time.

OnboardClient

new OnboardClient({ baseUrl, token, fetch })

Option Description
baseUrl Rerinku View’s address, such as https://n1234.nodes.rerinku.com. An empty string means the same origin as the page
token A token from an earlier login, or a view token
fetch A custom fetch (for tests and server-side rendering)

Every method returns a Promise, and every method accepts { signal } (an AbortSignal) as its last argument for cancellation. Failed requests throw OnboardAPIError (with status and code, such as invalid_token). Failed signaling throws SignalingError.

Method Description
getInfo() The server’s ID, name and API version; needs no token
login(password, { name, installId, appVersion }) Exchanges the access password for a token
logout() Revokes the current token
listDevices() The device list, OnboardDevice[]
listStreams(deviceId) The device’s streams (main stream, sub-stream, channels)
getThumbnail(deviceId) The thumbnail JPEG as a Blob. <img> can’t carry a token, so display it with URL.createObjectURL
getRuntime(deviceId) The device’s current runtime status (tempC, cpuPct and so on). The platform reuses the result for the same device within 2 seconds, so don’t poll faster than that
getIceServers() STUN/TURN for live video. The credentials expire, so don’t cache them for long
sendOffer(deviceId, sdp, { streamId }) WebRTC signaling: submits an offer and returns the answer

Properties: baseUrl, token (assignable). Event: tokenchange (detail is the new token or null).

RerinkuPlayer

new RerinkuPlayer(video, { client, manageVideo })

Option Description
client An OnboardClient, or any object that implements sendOffer and getIceServers. Required for live video
manageVideo Default true: sets the element to muted, inline and autoplay (browsers only allow muted autoplay). Pass false to leave the element completely alone
Member Description
load(source) Plays { kind: "live", device, streamId? } or { kind: "hls", url }. Pass null to stop
unload() Stops playback and releases the connection
retry() Reconnects right away: while waiting for an offline device, or after a retryable error
destroy() Releases all resources
status The current status, a PlayerStatus
source The source passed to the most recent load()

load() resolves when the first frame appears on screen. It rejects with a PlayerError when the player stops on an error, and with a DOMException named AbortError when it’s interrupted by a new load(), unload() or destroy(). While a live source is waiting for an offline device, the Promise stays pending; follow statuschange during that time.

Event detail
statuschange The new PlayerStatus
stats Live connection statistics, LiveConnectionStats (about every 2 seconds); null when it ends
error PlayerError (code, detail, retryable)

streamId picks one of the device’s streams, such as a lower-resolution sub-stream. Without it, the device’s default stream plays. Before every reconnection, the player fetches TURN credentials again.

Playback status

state Meaning
idle No source
connecting Setting up the connection; code says what it’s waiting for
playing Video is on screen
offline Reconnecting automatically. reason is device (the server confirmed the device is offline) or network. There are also retryInMs and attempt
error Needs handling. retryable says whether retry() can recover

message is an English fallback text. To localize, choose your own text by code:

code Meaning
connecting, waiting_frame, waiting_keyframe Setting up the connection, waiting for video
stalled The stream stopped after video had played; the picture stays on the last frame
relay_switch The direct connection is poor; switching to the cloud relay
no_signaling No client was provided
signaling_rejected The server rejected this session; detail is the server’s error code
codec_unsupported The browser doesn’t support this codec; detail is the codec name
h265_unsupported The browser has no WebRTC H.265 decoding (Safari has it; Chrome needs hardware decoding)
hls_failed, hls_media_failed, hls_unsupported, hls_player_load_failed Recording playback failed

Browsers and limitations

  • Live video needs a modern browser with WebRTC support. H.264 plays in every browser. H.265 depends on the browser’s WebRTC decoding; the SDK checks before connecting and reports h265_unsupported right away when it isn’t supported, instead of pulling a stream for nothing.
  • Video is muted and autoplays by default. If you need sound, unmute it after a user action.
  • Recording (HLS) URLs must come from your own backend, which also handles authentication: HLS requests in the browser can’t carry an Authorization header.

Low-level engines

@rerinku/player/engine exports createWebRTCEngine(video, source, callbacks, options) and createHLSEngine(video, source, callbacks). One engine handles one session. Signaling is injected through options.offer, and status comes back through callbacks. RerinkuPlayer is built on them; you only need them if you manage signaling and lifecycle yourself.