TheDocumentation 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 abstract class is the extension point for custom media transports. You might build a custom source to integrate a proprietary ingest protocol, drive a WebSocket-based push feed, perform specialized pre-processing, or mock a stream for testing — all while keeping the full Player API (track selection, ABR, statistics, DRM) working unchanged above it.
The Source Abstract Class
A concreteSource subclass must implement exactly three abstract methods:
play(url, tracks, playing)
Called once when the source should begin fetching and delivering media. Use the protected
readAudio(), readVideo(), readData(), and readMetadata() helpers to push samples and metadata into the player. May return immediately (non-blocking) or remain running for the lifetime of the stream (blocking).setReliability(reliable)
Called when
player.reliable is changed at runtime. Toggle frame skipping behaviour in your transport accordingly.setTracks(tracks)
Called when the player requests a track change — either by the user or by the ABR algorithm. Update your transport to fetch the new track IDs.
Registering a Custom Source
Use the@Source.registerClass decorator to map one or more protocol names to your class. When player.start() is called with an endpoint whose protocol matches, the player instantiates your source automatically.
Source.registerClass is a TypeScript decorator. In TypeScript 5.0 and later (which this library requires), class decorators are supported natively — no experimentalDecorators flag is needed. If you are using an older TypeScript version you would need to enable "experimentalDecorators": true in tsconfig.json, but upgrading to TypeScript 5.x is strongly recommended. If you prefer to avoid decorators entirely, pass the class directly to the Player constructor instead (see Option A below).Using the Custom Source with Player
Option A — pass the class to the constructor
The safest option: pass your
Source subclass directly to the Player constructor. This does not require the decorator or a matching protocol prefix in the endpoint URL.Protected Helper Methods
TheSource base class provides a rich set of protected helpers that your implementation can call:
Ingesting media samples
Ingesting media samples
| Method | Description |
|---|---|
readAudio(trackId, sample) | Push an audio sample into the player pipeline |
readVideo(trackId, sample) | Push a video sample into the player pipeline |
readData(trackId, sample) | Push a data or metadata sample into the player pipeline |
readSample(type, trackId, sample) | Convenience dispatcher — routes to the correct read* method by Media.Type |
Metadata and track management
Metadata and track management
| Method | Description |
|---|---|
readMetadata(metadata) | Announce stream metadata; triggers onMetadata on the player |
initTracks(tracks) | Declare which tracks will be received; must be called after readMetadata |
HTTP fetch helpers
HTTP fetch helpers
| Method | Description |
|---|---|
fetch(url, init?) | Fetch a URL with request finalization via onFinalizeRequest |
fetchMedia(url, trackIds, options?) | Fetch with optional CMCD instrumentation attached |
fetchWithRTT(url, init?) | Fetch and measure round-trip time |
finalizeRequest(url, headers) | Invoke onFinalizeRequest and return the finalized URL |
Skipping and timestamp utilities
Skipping and timestamp utilities
| Method | Description |
|---|---|
skipAudio(duration) | Signal that duration ms of audio was skipped; fires onAudioSkipping |
skipVideo(duration) | Signal that duration ms of video was skipped; fires onVideoSkipping |
fixTimestamp(type, trackId, currentTime, sample) | Correct timestamp discontinuities to maintain monotonic time |
Reader creation
Reader creation
| Method | Description |
|---|---|
newReader(params?) | Create a Reader (RTS or CMAF) matching the current mediaExt ('rts' or 'mp4'); wires onSample, onMetadata, and onError automatically |
Source Properties Available to Subclasses
| Property | Type | Description |
|---|---|---|
this.url | string | The resolved playback URL |
this.streamName | string | Stream name extracted from the endpoint |
this.metadata | Metadata | undefined | Current stream metadata (available after readMetadata is called) |
this.audioTime | number | Latest ingested audio timestamp (ms) |
this.videoTime | number | Latest ingested video timestamp (ms) |
this.currentTime | number | Max of audio, video, and data times (ms) |
this.mediaExt | string | Media container extension, e.g. 'rts' or 'mp4' |
this.reliable | boolean | Whether reliable mode is active |
this.closed | boolean | true after this.close() has been called |
WSSource as a Reference Implementation
WSSource in src/sources/WSSource.ts is a good real-world reference for a push-based transport. It demonstrates:
- Registering for multiple protocols:
@Source.registerClass('wss', 'ws') - Opening a
WebSocketReliableconnection inplay() - Parsing JSON metadata and binary frames on the same WebSocket
- Delegating binary frames to
newReader()for demuxing - Sending a
tracksmessage insetTracks()to request a server-side switch