Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CeeblueTV/wrts-client/llms.txt

Use this file to discover all available pages before exploring further.

WSSource is a push-based streaming source that receives media over a persistent WebSocket connection. Unlike the HTTP-based sources, which poll the server for new sequences, WSSource keeps a single connection open and processes messages as they arrive. It is automatically selected by the Player when the endpoint URL starts with wss:// or ws://.

Import

import { WSSource } from '@ceeblue/wrts-client';

Registration

WSSource is registered via the @Source.registerClass('wss', 'ws') decorator. The Player resolves the source class from the endpoint protocol at startup — no explicit configuration is required for WebSocket endpoints.
// WSSource is selected automatically for wss:// endpoints
const player = new Player(videoElement);
player.start({ endPoint: 'wss://example.com/stream' });

Constructor

constructor(playing: IPlaying, params: Connect.Params)
Creates a new WSSource. Internally calls super(playing, 'wss', params, Connect.Type.DIRECT_STREAMING) — note the DIRECT_STREAMING connection type, which changes how the URL is constructed compared to the default WRTS type.
playing
IPlaying
required
The playback context providing buffer state, stall events, and the stop signal.
params
Connect.Params
required
Connection parameters including endPoint, streamName, and optional query parameters.

Protocol Behavior

Track Negotiation via Query Parameters

Before opening the WebSocket, WSSource appends audio and video query parameters to the URL to negotiate initial track selection with the server:
  • ?audio=<id> — if a specific audio track is requested; otherwise aac,|bestbps (best-bitrate AAC track)
  • ?video=<id> — if a specific video track is requested; otherwise h264,|bestbps (best-bitrate H264 track)

First Message — Stream Metadata

The first message received from the server is a JSON string containing stream metadata. WSSource parses this into a Metadata object and immediately applies two codec filters:
  • metadata.filterAudios([Media.Codec.AAC]) — only AAC audio tracks are kept
  • metadata.filterVideos([Media.Codec.H264]) — only H264 video tracks are kept
The live clock (metadata.liveTime) is then corrected by adding half the measured round-trip time (_rtt / 2) to compensate for connection latency. The RTT is measured as the elapsed time from when _ws.open() is called to when the onOpen callback fires.
WSSource filters out all audio codecs except AAC and all video codecs except H264. If your stream contains other codecs (e.g. Opus audio or H265 video), those tracks will be silently removed from the metadata and will not be available for selection.

Subsequent Messages — Binary Media Data

All messages after the first metadata message are ArrayBuffer binary data. Each buffer is passed directly to an RTSReader instance created with isStream: false — meaning the reader treats each message as a complete, non-streaming RTS data unit rather than a continuous byte stream.

Reader Mode

WSSource overrides newReader() to always create a reader with isStream: false, regardless of the params argument. This matches the framed nature of WebSocket messages.

Track Selection

WSSource supports dynamic track selection via setTracks(). When called, it sends a JSON control message over the open WebSocket:
{ "type": "tracks", "audio": <audioTrackId>, "video": <videoTrackId> }
If no track is currently active for a given type, the last known audioTrack or videoTrack value from the source state is used as a fallback. The trackSelectable property inherited from Source returns true for WSSource.

Automatic Reconnection

WSSource handles unexpected disconnections gracefully. On WebSocket close, it inspects the error:
  • If the close is intentional (this.closed === true) — the source closes and does not reconnect.
  • If the error name is 'Socket disconnection' — treated as an explicit server-side termination; the source closes without reconnecting.
  • For all other close reasons — the source waits 500 ms and then re-opens the WebSocket to the same URL.

Reliability

WSSource does not support partial reliability. Calling setReliability(false) (or setting player.reliable = false) throws an error:
WS doesn't support partial reliability
The WebSocket transport is inherently reliable — all messages are delivered in order and without loss by the underlying TCP layer. Frame skipping and sequence skipping, which are features of HTTPAdaptiveSource in unreliable mode, are not available via WSSource.

Usage Example

import { Player, WSSource } from '@ceeblue/wrts-client';

const player = new Player(videoElement, WSSource);

player.onMetadata = (metadata) => {
  console.log('Audio tracks (AAC only):', metadata.audioTracks);
  console.log('Video tracks (H264 only):', metadata.videoTracks);
};

player.start({ endPoint: 'wss://example.com/stream' });
import { Player, WSSource } from '@ceeblue/wrts-client';

const player = new Player(videoElement, WSSource);
player.start({ endPoint: 'wss://example.com/wrts/out+<id>' });

Summary of Differences from HTTPAdaptiveSource

FeatureWSSourceHTTPAdaptiveSource
TransportWebSocket (push)HTTP/2 (pull)
Protocol registrationwss, wshttps, http
Adaptive bitrate❌ Not supported✅ Full MBR
CMCD telemetry❌ Not supported✅ NONE / SHORT / FULL
Unreliable mode❌ Throws error✅ Supported
Sequence skipping❌ Not supported✅ Supported
Audio codecsAAC onlyAll (per manifest)
Video codecsH264 onlyAll (per manifest)
Reconnection✅ Automatic (500 ms)✅ Automatic (500 ms)

Build docs developers (and LLMs) love