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.

Source is the abstract base class that all WebRTS transport implementations extend. It provides the wiring between the network layer (HTTP adaptive, WebSocket, etc.) and the Player’s MSE pipeline: protocol registration, sample ingestion helpers, timestamp continuity correction, byte-rate accounting, CMCD telemetry, and track management. Concrete subclasses — HTTPAdaptiveSource, WSSource, and HTTPSource — override three abstract methods (play, setReliability, setTracks) to implement their transport strategy. Source implements ICMCD and extends EventEmitter from @ceeblue/web-utils.
import { Source, SourceError } from '@ceeblue/wrts-client';

Static Methods

Source.registerClass()

static registerClass(
  ...protocols: [string, ...string[]]
): <Class extends SourceType>(SourceClass: Class, context?: unknown) => Class
A TypeScript decorator factory that registers the decorated Source subclass for one or more protocol names. When Player resolves a source class from an endPoint URL, it calls Source.getClass(protocol) to retrieve the registered implementation.
The return type is a TypeScript 5–compatible decorator function (not the legacy ClassDecorator type). No experimentalDecorators compiler option is needed — just apply @Source.registerClass('myproto') directly on the class.
protocols
[string, ...string[]]
required
One or more protocol strings (e.g., 'https', 'http', 'wss', 'ws'). At least one is required. Strings are normalised to lowercase.

Source.getClass()

static getClass(protocol: string): SourceType | undefined
Retrieves the Source subclass registered for the given protocol, or undefined if none is registered.
protocol
string
required
Protocol name to look up (case-insensitive).
@Source.registerClass('myproto', 'myprotos')
class MySource extends Source {
  constructor(playing: IPlaying, params: Connect.Params) {
    super(playing, 'myprotos', params);
  }

  protected play(url: URL, tracks: Media.Tracks, playing: IPlaying): void {
    // connect and stream…
  }

  protected setReliability(reliable: boolean): void { /* … */ }
  protected setTracks(tracks: Media.Tracks): void { /* … */ }
}

// Retrieve later:
const Cls = Source.getClass('myproto');
if (Cls) {
  const source = new Cls(playing, params);
}

Constructor

The constructor is called by Player (or directly when building a custom source). It must be invoked from the subclass constructor via super.
constructor(
  playing: IPlaying,
  protocol: string,
  params: Connect.Params,
  type?: Connect.Type
)
playing
IPlaying
required
The IPlaying instance provided by the Player. Used to read buffer metrics, fire skip events, and receive the abort signal.
protocol
string
required
Protocol string used to build the connection URL via Connect.buildURL (e.g., 'https', 'wss').
params
Connect.Params
required
Connection parameters passed from Player.start().
type
Connect.Type
Optional connection type. Defaults to Connect.Type.WRTS.
The Source constructor schedules play() asynchronously via Promise.resolve().then(...), so the subclass constructor returns synchronously and the network connection is initiated in the next microtask.

Abstract Methods

Subclasses must implement all three of these methods.

play()

protected abstract play(url: URL, tracks: Media.Tracks, playing: IPlaying): void
Establishes the media connection and begins delivering samples. Implementations may be fully asynchronous (returning a Promise) or fire-and-forget. The method is called automatically by the base class on the next microtask after construction.
url
URL
Built endpoint URL (protocol + host + path + query).
tracks
Media.Tracks
Initial track selection computed from onMetadata or auto-selection.
playing
IPlaying
The same IPlaying instance passed to the constructor.

setReliability()

protected abstract setReliability(reliable: boolean): void
Called when the reliable flag is toggled on the Player. Implementations should reconfigure their transport to enforce or relax frame-skipping behaviour.

setTracks()

protected abstract setTracks(tracks: Media.Tracks): void
Called when a manual track selection is requested (e.g., player.videoTrack = id). Implementations should request the new rendition from the server or reconfigure their demux pipeline.

Public Method

close()

close(error?: SourceError): void
Closes the source. Once closed, all ingestion helpers become no-ops. Fires onClose with the optional error. Certain request errors (e.g., HTTP 404 or 'stream open failed') are automatically morphed into a 'Resource unavailable' error before calling onClose.
error
SourceError
Optional error describing why the source closed improperly. Omit for clean closure.

Protected Helper Methods

These methods are available to subclass implementations.

Events (Overridable Methods)

The Player overrides these when it attaches to a Source instance. Custom Source subclasses can also call them.

onClose()

onClose(error?: SourceError): void
Fired when the source closes. error is set for abnormal closures. The Player hooks this to call player.stop(error).

onTrackChange()

onTrackChange(audioTrack: number, videoTrack: number, dataTrack: Set<number>): void
Fired when the effective track selection changes. The Player hooks this to enable/disable the corresponding SourceBuffer in MediaPlayback.

onMetadata()

onMetadata(metadata: Metadata): Media.Tracks | void
Fired when stream metadata is parsed. Return a Media.Tracks object to specify initial track selection; the Player forwards this to player.onMetadata.

onAudio() / onVideo() / onData()

onAudio(trackId: number, sample: Media.Sample): void
onVideo(trackId: number, sample: Media.Sample): void
onData(trackId: number, sample: Media.Sample): void
Fired for each ingested audio, video, or data sample. The Player hooks these to append data to the MSE SourceBuffer via MediaPlayback.

onFinalizeRequest()

onFinalizeRequest(url: URL, headers: Headers): void
Fired before every outgoing request. Override to inject authentication headers or rewrite URLs.

Properties

Identity & State

name
string
Read-only. Derived source name, e.g., 'https-mp4' for an HTTP adaptive source fetching MP4 segments, or the Connect.Type string for non-WRTS connections.
closed
boolean
Read-only. true after close() has been called.
streamName
string
Read-only. Stream name extracted from Connect.Params.streamName, e.g., 'as+bc3f535f-37f3-458b-8171-b4c5e77a6137'.
url
string
Read-only. The fully-built endpoint URL string.
metadata
Metadata | undefined
Read-only. The most recently received Metadata object, or undefined before metadata is received.

Timeline

audioTime
number
Read-only. Current end-of-buffer time for audio in milliseconds (source domain).
videoTime
number
Read-only. Current end-of-buffer time for video in milliseconds (source domain).
dataTime
number
Read-only. Current end-of-buffer time for data in milliseconds (source domain).
currentTime
number
Read-only. Maximum of audioTime, videoTime, and dataTime — the furthest point any track has reached.

Track Selection

audioTrack
number | undefined
Read/write. Effective audio track ID currently being received, or undefined before initialisation. -1 means disabled. Setting triggers setTracks().
videoTrack
number | undefined
Read/write. Effective video track ID. Setting triggers setTracks() and disables MBR.
dataTrack
Set<number> | undefined
Read/write. Set of effective data track IDs. Accepts number, number[], Set<number>, or undefined (all tracks).
audioSelected
number | undefined
Read-only. The manually-selected audio track index (undefined = automatic / MBR).
videoSelected
number | undefined
Read-only. The manually-selected video track index (undefined = automatic / MBR).
dataSelected
Set<number> | undefined
Read-only. The manually-selected data tracks (undefined = all tracks).
trackSelectable
boolean
Read-only. true if the subclass overrides setTracks (indicating it supports manual track selection).

Byte Rates

audioByteRate
number
Read-only. Audio payload byte rate in bytes per second, averaged over the last GOP.
videoByteRate
number
Read-only. Video payload byte rate in bytes per second, averaged over the last GOP.
dataByteRate
number
Read-only. Estimated data/overhead byte rate: max(0, recvByteRate - audioByteRate - videoByteRate).
recvByteRate
ByteRate
Read-only. The raw ByteRate accumulator for all received bytes (audio + video + overhead). Access .value() for the current bytes-per-second figure.

Frame Rates

audioPerSecond
number
Read-only. Audio frames decoded per second.
videoPerSecond
number
Read-only. Video frames decoded per second.

Skip Counters

skippedAudio
number
Read-only. Cumulative duration of audio skipped in milliseconds since the source opened.
skippedVideo
number
Read-only. Cumulative duration of video skipped in milliseconds since the source opened.

Reliability & Format

reliable
boolean
Read/write. Whether the source is in reliable (no-skip) mode. Calls setReliable() on write.
mediaExt
string
Read-only. Media extension string extracted from Connect.Params.mediaExt (e.g., 'mp4', 'rts'). Determines which Reader is created by newReader().

Tracks Combinability

tracksCombinable
boolean
Read/write. When true (default), requests for audio and video tracks are combined into a single HTTP request. Automatically set to false when passthroughCMAF is active.

ICMCD Properties

cmcd
CMCD
Read/write. CMCD payload level. Base implementation always returns CMCD.NONE and rejects non-null writes (override in subclasses that support CMCD, like HTTPAdaptiveSource).
cmcdMode
CMCDMode
Read/write. CMCD delivery mode (CMCDMode.HEADER or CMCDMode.QUERY). Defaults to CMCDMode.HEADER.
cmcdSid
string
Read/write. CMCD session identifier.

SourceError Type

SourceError is a discriminated union on { type: 'SourceError', name: string }. Match error.name after confirming error.type === 'SourceError': SourceError also wraps errors from lower layers:
  • ReaderError — parsing errors from CMAFReader or RTSReader.
  • WebSocketReliableError — WebSocket-level transport errors (when using WSSource).
source.onClose = (error) => {
  if (!error) return;
  if (error.type === 'SourceError') {
    switch (error.name) {
      case 'Resource unavailable':
        console.warn('Stream is offline');
        break;
      case 'Request error':
        console.error('HTTP error:', error.detail);
        break;
    }
  }
};

Writing a Custom Source

import { Source, SourceError } from '@ceeblue/wrts-client';
import { Connect } from '@ceeblue/web-utils';
import * as Media from '@ceeblue/wrts-client';

@Source.registerClass('myproto')
export class MySource extends Source {
  private _controller = new AbortController();

  constructor(playing: IPlaying, params: Connect.Params) {
    super(playing, 'myproto', params);
    // Abort transport when Player stops
    playing.signal.addEventListener('abort', () => this._controller.abort(), { once: true });
  }

  protected async play(url: URL, tracks: Media.Tracks, playing: IPlaying): Promise<void> {
    const response = await this.fetch(url, { signal: this._controller.signal });
    if (!response.ok) {
      this.close({ type: 'SourceError', name: 'Request error', detail: response.statusText });
      return;
    }
    // Read and demux the response stream…
    const reader = this.newReader();
    const body = response.body!.getReader();
    while (true) {
      const { done, value } = await body.read();
      if (done) break;
      reader.read(value);
    }
  }

  protected setReliability(reliable: boolean): void {
    // Configure transport reliability mode
  }

  protected setTracks(tracks: Media.Tracks): void {
    // Request new rendition from server
  }
}

Build docs developers (and LLMs) love