VDO.Ninja SDK — API Reference

This page lists the primary methods, helpers, aliases, and events exposed by the SDK. It complements the short examples in README.

Tip: Avoid reserved application message types subscribe, unsubscribe, channelMessage, request, and response; the SDK uses them for pub/sub and RPC. Start with the guide chooser for complete workflows.

Constructor

const vdo = new VDONinjaSDK(options)

Connection

Publishing (Sender)

Viewing (Receiver)

Quick Helpers

Data Communication

Binary and Additional Channels

Turns the SDK from a messaging transport into a bulk transport: raw bytes, a second channel so bulk traffic stops head-of-line blocking control messages, partial reliability, and a real backpressure signal.

Everything here lives in the reserved x- namespace, which VDO.Ninja ignores by contract. A reserved channel is therefore safe to open toward any peer — verified with 4MB flooded at a live VDO.Ninja tab, which saw zero errors and kept its control channel.

Events:

// Bulk on its own channel, unreliable and unordered, with backpressure
const bulk = await vdo.openChannel(uuid, 'bulk', { ordered: false, maxRetransmits: 0 });
for (const chunk of chunks) {
    while (vdo.getBufferedAmount(uuid, 'bulk') > 1_000_000) {
        await new Promise(r => vdo.addEventListener('bufferedAmountLow', r, { once: true }));
    }
    bulk.send(chunk);
}

Implementation note: backpressure needs a transport that reports it

Some @roamhq/wrtc builds report bufferedAmount: 0 no matter how much is queued — 2.4MB in Windows testing. Other builds report queued bytes but omit the native bufferedamountlow event; the SDK polls as a fallback for those builds. If a build always reports zero, getBufferedAmount remains zero, bufferedAmountLow cannot observe a high-to-low transition, and waitForDrain is a no-op. Browsers report it correctly.

This is a limitation of the WebRTC implementation, not the SDK. If you need flow control in Node today, keep an application-level cap on outstanding sends rather than relying on the drain signal.

File Transfer

Implements VDO.Ninja's native file transfer, so an SDK peer and a VDO.Ninja browser tab can exchange files in either direction. Files move over their own data channel, never the control channel. See docs/compatibility.md for the wire format.

Hosting:

Receiving:

Events:

direction is 'inbound' or 'outbound' on every transfer event.

// Host a file and let a VDO.Ninja viewer download it from its chat feed
const vdo = new VDONinjaSDK();
await vdo.connect();
await vdo.joinRoom({ room: 'myroom' });
await vdo.announce({ streamID: 'mystream' });
const offered = vdo.hostFile(bytes, { name: 'report.pdf' });

// Or download what a peer is offering
vdo.addEventListener('fileList', async (e) => {
    const file = e.detail.files[0];
    const { bytes } = await vdo.requestFile(e.detail.uuid, file.id);
});

Resources

VDO.Ninja's resources channel carries images keyed by meta template name. The receiver turns each into an object URL and stores it under meta[templateName].value.

Event:

Pub/Sub

Events:

Utilities

TypeScript

Type definitions ship with the package (vdoninja-sdk.d.ts); no @types install needed.

import VDONinja, { PeerQuality, FileTransferResult } from '@vdoninja/sdk';

on/off/once are typed against the event map, so e.detail is inferred per event name. npm run test:types typechecks a consumer against the shipped declarations under --strict, so the definitions cannot silently drift from the implementation.

Aliases (Common Names)

Note: The viewing alias unsubscribe(streamID) that conflicted with pub/sub has been removed.

Events (Selected)

Connection & Room

Peer & Channel

Data

File Transfer & Resources (see the sections above for payloads)

Media

State & Errors

Compatibility Notes


WHIP/WHEP Clients

Standalone clients for standard WebRTC-HTTP streaming protocols. These work independently of the VDO.Ninja P2P system.

WHIPClient (whip-client.js)

Publish media streams to WHIP-compatible endpoints (Twitch, Meshcast, Cloudflare, etc.)

const client = new WHIPClient(endpoint, options)

Options:

Methods:

Events: connecting, connected, icestate, connectionstate, error, disconnected, stopped

WHEPClient (whep-client.js)

Consume media streams from WHEP-compatible endpoints.

const client = new WHEPClient(endpoint, options)

Options:

Methods:

Events: connecting, connected, track, icestate, connectionstate, error, disconnected, stopped

Supported WHIP/WHEP Services

Service WHIP URL WHEP URL
Meshcast.io https://cae1.meshcast.io/whip/{streamId} https://cae1.meshcast.io/whep/{streamId}
Twitch https://g.webrtc.live-video.net:4443/v2/offer N/A
Cloudflare Stream Your Stream endpoint Your Stream endpoint
Dolby.io Your Dolby endpoint Your Dolby endpoint

WHIP/WHEP Example

// Publish to Meshcast
const whip = new WHIPClient('https://cae1.meshcast.io/whip/mystream', {
    videoCodec: 'h264',
    videoBitrate: 2500
});
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
await whip.publish(stream);
// View at: https://meshcast.io/mystream

// Watch from Meshcast
const whep = new WHEPClient('https://cae1.meshcast.io/whep/mystream');
whep.addEventListener('track', (e) => {
    document.getElementById('video').srcObject = e.detail.streams[0];
});
await whep.view();

See README for end-to-end examples and the demos folder for runnable samples.