Skip to main content
startCustomTrack(options) Prebuilt Custom Starts sharing a custom MediaStreamTrack with all other participants. Custom tracks are sent in addition to the standard audio, video, screenAudio, and screenVideo tracks — they do not replace them. Calling this with the same trackName replaces the existing custom track of that name. Must be called after join(). To stop sharing the track, use stopCustomTrack().
Custom tracks are not the right tool for screen sharing. For screen content, use startScreenShare() instead. See Screenshare streams vs. custom tracks for guidance on when to use each.

Parameters

track
MediaStreamTrack
required
The raw MediaStreamTrack to send.
trackName
string
An identifier for the custom track (max 50 characters). Must not conflict with reserved names: "audio", "video", "cam-audio", "cam-video", "screenVideo", "screenAudio", "screen-video", "screen-audio", "rmpAudio", "rmpVideo", "customVideoDefaults".If omitted, Daily generates a name in the format custom$TRACK_KIND$COUNT (e.g. "customAudio0", "customVideo1"). The resolved name is returned by the Promise.
mode
'music' | 'speech' | DailyMicAudioModeSettings
Audio processing mode for the track. Accepts the same values as micAudioMode.
ignoreAudioLevel
boolean
default:"false"
When true, this track is not factored into active speaker events.

Return value

Returns a Promise<string> that resolves to the track’s identifier — either the trackName you provided or the auto-generated one.

Errors

Throws in the following cases:
  • Not currently in a call.
  • trackName matches a reserved name.
  • trackName exceeds 50 characters.
  • track is not a MediaStreamTrack instance.

Examples

// Start a custom track, let Daily generate the name
const trackName = await call.startCustomTrack({ track: customTrack });
console.log('Track started as:', trackName); // e.g. "customVideo0"

// Start with an explicit name
const trackName = await call.startCustomTrack({
  track: customTrack,
  trackName: 'cameraFeed2',
});

Subscribing to custom tracks

To receive a remote participant’s custom tracks, subscribe to them via updateParticipant():
// Subscribe to all custom tracks from a participant
call.updateParticipant(sessionId, {
  setSubscribedTracks: { custom: true },
});

// Subscribe to a specific custom track
call.updateParticipant(sessionId, {
  setSubscribedTracks: { custom: { customVideo0: true } },
});

See also