← All demos
Dynamic media
Start with a data-only connection using announce(), then add, swap, and remove camera, microphone, and screen tracks while the viewer stays connected.
- Start the publisher. It announces a data-only stream with no media.
- Click Connect in the Viewer panel after the publisher has started, or open the share link on another device and connect there.
- Add a camera, microphone, or screen and watch each track appear on the viewer.
- Pause or remove tracks, or send a message over the data channel.
Tracks are added after announce() with
addTrack(), swapped with replaceTrack(), and removed with removeTrack(). Adding and removing renegotiates with each connected viewer; replacing does not.Publisher
Not startedConnection
Add media
Manage tracks
Local preview
Local tracks
ConnectionNot connected
MediaNone
Data channelClosed
Viewer
Not connectedConnection
Remote
Received tracks
ConnectionNot connected
MediaNone
Data channelClosed
Key SDK calls in this demo
// Publisher: start data-only, add media later
const pub = new VDONinjaSDK();
await pub.connect();
await pub.joinRoom({ room });
await pub.announce({ streamID }); // no media yet
const local = new MediaStream([camTrack]);
await pub.addTrack(camTrack, local); // renegotiates with each viewer
await pub.replaceTrack(camTrack, screenTrack); // swap, no renegotiation
await pub.removeTrack(screenTrack); // stops the track and renegotiates
// Viewer
viewer.addEventListener('track', (e) => remoteStream.addTrack(e.detail.track));
await viewer.connect();
await viewer.joinRoom({ room });
await viewer.view(streamID, { audio: true, video: true });