Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/moqtail/moqtail/llms.txt

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

MOQtailClient

The MOQtailClient class represents a Media Over QUIC Transport (MOQT) client session. It provides high-level methods for subscribing to tracks, fetching historical data, announcing tracks for publication, and managing the session lifecycle.

Overview

Once initialized, the client provides methods for MOQT requests and publishing. If a protocol violation occurs, the client will terminate and must be re-initialized.

Initialization

MOQtailClient.new()

Establishes a new client session over WebTransport and performs the MOQT setup handshake.
static async new(args: MOQtailClientOptions): Promise<MOQtailClient>
args
MOQtailClientOptions
required
Configuration options for the client connection.
return
Promise<MOQtailClient>
A promise resolving to a ready client instance
Throws:
  • ProtocolViolationError - If the server sends an unexpected or invalid message during setup
  • Error - On WebTransport connection failure
const client = await MOQtailClient.new({
  url: 'https://relay.example.com/moq',
  supportedVersions: [0xff00000e] // Draft-14
});

Subscription Methods

subscribe()

Subscribes to a track and returns a stream of MoqtObjects matching the requested window and relay forwarding mode.
async subscribe(args: SubscribeOptions): Promise<SubscribeError | { requestId: bigint; stream: ReadableStream<MoqtObject> }>
args
SubscribeOptions
required
Subscription parameters
return
SubscribeError | { requestId: bigint; stream: ReadableStream<MoqtObject> }
Either a SubscribeError on refusal, or an object containing:
  • requestId - The subscription ID for use with unsubscribe() or subscribeUpdate()
  • stream - A ReadableStream<MoqtObject> for consuming objects
Throws:
  • MOQtailError - If the client is destroyed
  • ProtocolViolationError - If required fields are missing or inconsistent
  • InternalError - On transport/protocol failure (disconnect is triggered before rethrow)
const result = await client.subscribe({
  fullTrackName: FullTrackName.tryNew('video/main', 'h264'),
  filterType: FilterType.LatestObject,
  forward: true,
  groupOrder: GroupOrder.Original,
  priority: 0
});

if (!(result instanceof SubscribeError)) {
  for await (const obj of result.stream) {
    // Process MoqtObject
    console.log('Group:', obj.groupId, 'Object:', obj.objectId);
  }
}

unsubscribe()

Stops an active subscription identified by its request ID.
async unsubscribe(requestId: bigint | number): Promise<void>
requestId
bigint | number
required
The subscription request ID returned from subscribe()
Throws:
  • MOQtailError - If the client is destroyed
  • InternalError - On transport failure
await client.unsubscribe(subscriptionId);

subscribeUpdate()

Narrows or updates an active subscription window and/or relay forwarding behavior.
async subscribeUpdate(args: SubscribeUpdateOptions): Promise<void>
args
SubscribeUpdateOptions
required
Update parameters
Throws:
  • MOQtailError - If the client is destroyed
  • ProtocolViolationError - If the update would widen the window
  • InternalError - On transport failure
await client.subscribeUpdate({
  subscriptionRequestId: subId,
  startLocation: new Location(150n, 0n),
  endGroup: 180n,
  priority: 16,
  forward: true
});

switch()

Switches an active subscription to a different track while retaining the same subscription parameters.
async switch(args: SwitchOptions): Promise<SubscribeError | { requestId: bigint; stream: ReadableStream<MoqtObject> }>
args
SwitchOptions
required
Switch parameters
return
SubscribeError | { requestId: bigint; stream: ReadableStream<MoqtObject> }
Either a SubscribeError or an object with the new requestId and stream
const result = await client.switch({
  subscriptionRequestId: currentSubId,
  fullTrackName: newTrackName
});

Fetch Methods

fetch()

One-shot retrieval of a bounded object span, returning a stream of MoqtObjects.
async fetch(args: FetchOptions): Promise<FetchError | { requestId: bigint; stream: ReadableStream<MoqtObject> }>
args
FetchOptions
required
Fetch parameters
return
FetchError | { requestId: bigint; stream: ReadableStream<MoqtObject> }
Either a FetchError or an object with requestId and a finite stream
Throws:
  • MOQtailError - If client is destroyed
  • ProtocolViolationError - Priority out of [0-255] or invalid parameters
  • InternalError - On transport failure
const result = await client.fetch({
  priority: 64,
  groupOrder: GroupOrder.Original,
  typeAndProps: {
    type: FetchType.StandAlone,
    props: {
      fullTrackName,
      startLocation: new Location(0n, 0n),
      endLocation: new Location(10n, 0n)
    }
  }
});

if (!(result instanceof FetchError)) {
  for await (const obj of result.stream) {
    // Process historical objects
  }
}

Publishing Methods

publishNamespace()

Announces a namespace for publishing tracks.
async publishNamespace(namespace: Tuple | string, parameters?: VersionSpecificParameters): Promise<PublishNamespaceError | PublishNamespaceOk>
namespace
Tuple | string
required
Namespace tuple or slash-separated string path
parameters
VersionSpecificParameters
Optional extension parameters
return
PublishNamespaceError | PublishNamespaceOk
Either an error or success response
const result = await client.publishNamespace(['video', 'camera1']);

if (!(result instanceof PublishNamespaceError)) {
  console.log('Namespace announced successfully');
}

publishNamespaceDone()

Signals that a previously announced namespace is no longer being published.
async publishNamespaceDone(namespace: Tuple | string): Promise<void>
namespace
Tuple | string
required
Namespace to mark as done
await client.publishNamespaceDone(['video', 'camera1']);

addOrUpdateTrack()

Registers or updates a track definition for local publishing.
addOrUpdateTrack(track: Track): void
track
Track
required
Track definition containing name, sources, and metadata. See Track documentation.
Throws:
  • MOQtailError - If the client has been destroyed
client.addOrUpdateTrack({
  fullTrackName: FullTrackName.tryNew('video/main', 'h264'),
  forwardingPreference: ObjectForwardingPreference.Subgroup,
  trackSource: { live: liveStream },
  publisherPriority: 0
});

removeTrack()

Removes a previously registered track from the client’s local catalog.
removeTrack(track: Track): void
track
Track
required
Track to remove
Throws:
  • MOQtailError - If the client has been destroyed
client.removeTrack(track);

Datagram Methods

startDatagrams()

Starts receiving datagrams from the WebTransport connection.
async startDatagrams(): Promise<void>
Throws:
  • MOQtailError - If client is destroyed or datagrams already started
await client.startDatagrams();

stopDatagrams()

Stops receiving datagrams and releases resources. Idempotent.
async stopDatagrams(): Promise<void>
await client.stopDatagrams();

subscribeToTrackDatagrams()

Subscribes to receive datagrams for a specific track.
subscribeToTrackDatagrams(trackAlias: bigint, handler: (obj: MoqtObject) => void): () => void
trackAlias
bigint
required
Track alias to subscribe to
handler
(obj: MoqtObject) => void
required
Function called for each received MoqtObject on this track
return
() => void
Unsubscribe function to remove the handler
const unsubscribe = client.subscribeToTrackDatagrams(trackAlias, (obj) => {
  console.log('Received datagram:', obj.payload);
});

// Later:
unsubscribe();

sendDatagram()

Sends a single MoqtObject as a datagram.
async sendDatagram(trackAlias: bigint, object: MoqtObject): Promise<void>
trackAlias
bigint
required
Track alias for this object
object
MoqtObject
required
MoqtObject to send
Throws:
  • MOQtailError - If datagram writer not initialized
  • InternalError - If object has neither payload nor status
await client.sendDatagram(trackAlias, moqtObject);

createDatagramSender()

Creates a datagram sender for a specific track.
createDatagram Sender(trackAlias: bigint): SendDatagramStream
trackAlias
bigint
required
Track alias for outgoing datagrams
return
SendDatagramStream
A SendDatagramStream for writing MoqtObjects as datagrams
Throws:
  • MOQtailError - If datagram writer not initialized
const sender = client.createDatagramSender(trackAlias);
await sender.write(moqtObject);

Session Management

disconnect()

Gracefully terminates the client session and releases WebTransport resources.
async disconnect(reason?: unknown): Promise<void>
reason
unknown
Optional application-level reason (string or error) passed to onSessionTerminated callback
await client.disconnect('user logout');

Properties

serverSetup

Gets the current server setup configuration.
get serverSetup(): ServerSetup
return
ServerSetup
The ServerSetup instance negotiated during connection
const setup = client.serverSetup;
console.log('Negotiated version:', setup.selectedVersion);

isDatagramsEnabled

Returns true if datagram support is currently active.
get isDatagramsEnabled(): boolean
if (client.isDatagramsEnabled) {
  console.log('Datagrams are active');
}

receivedDatagramObjects

Stream of all received MoqtObjects from datagrams across all tracks.
readonly receivedDatagramObjects: ReadableStream<MoqtObject>
Only one reader should be active. For multiple subscribers, use subscribeToTrackDatagrams() instead.
const reader = client.receivedDatagramObjects.getReader();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  // Process datagram object
}

Event Callbacks

These callbacks can be set after client initialization:

onNamespacePublished

Fired when a PUBLISH_NAMESPACE control message is received.
client.onNamespacePublished = (msg: PublishNamespace) => {
  console.log('Namespace announced:', msg.namespace);
};

onNamespaceDone

Fired when a PUBLISH_NAMESPACE_DONE control message is received.
client.onNamespaceDone = (msg: PublishNamespaceDone) => {
  console.log('Namespace done:', msg.namespace);
};

onGoaway

Fired on GOAWAY reception signaling graceful session wind-down.
client.onGoaway = (msg: GoAway) => {
  console.warn('Server sent GOAWAY:', msg.newSessionUri);
};

onPeerPublish

Fired when an inbound PUBLISH control message is received.
client.onPeerPublish = (msg: Publish, stream: ReadableStream<MoqtObject>) => {
  console.log('Peer publishing:', msg.fullTrackName);
};

onError

General-purpose error callback for exceptions not thrown synchronously.
client.onError = (error: unknown) => {
  console.error('Client error:', error);
};

See Also