Getting started
The application consists of 4 basic entities:
Client - This object provides access to conference channels, peers, their media tracks and yourself media tracks
Peer - Conference participant in a channel
PeerTrack - Conference participant’s media track
Track - Your media track
Table of contents
Installation
Usage
Connection
Client observer events
Peers
Peer observer events
Getting remote peers media tracks
Getting own media tracks
Publishing media to a channel
Disconnecting
Basic example
Installation
Use the package manager npm or yarn to install livedigital-client.
Yarn
yarn add @livedigital/client
NPM
npm install @livedigital/client
Usage
In the beginning import the SDK module:
import Client from '@livedigital/client';
And create an instance of the livedigital Web SDK Client with ClientParams:
const client = new Client(ClientParams);
Connection
Connection request to the signaling servers uses JWT token based authentication.
Use your personal jwtSecret
as the secret key for JWT token generation, appId
and channelId
as token payload parameters when connectiong to a channel.
The example below shows how to generate token using jsonwebtoken
library.
import jwt from 'jsonwebtoken';
const appId = 'yourAppId';
const channelId = 'yourChannelId';
const jwtSecret = 'yourPrivateJwtSecret';
const role = 'host';
const uid = 'yourUserId'; // your internal user ID
// token generation
const token = jwt.sign({ channelId }, jwtSecret, { issuer: appId, subject: uid, audience: role });
appId
,channelId
andjwtSecret
you can find in Management API.role
is a Role of a peeruid
is your internal user ID. It can be used to map livedigital peers to your application’s users. uid is available in Peer from Client as well as from Management-API
IMPORTANT NOTE: Keep your jwtSecret parameter secret. The best way is to generate a token on the backend side.
To join a channel, call client.join(joinChannelParams)
method with JoinChannelParams:
await client.join({
token,
appData: {
// any your custom data
},
// The following parameters must match ones that were used for token generation
channelId,
role,
});
appData
is your custom application data. There may be data such as your member’s name, track mirroring options and other data about your application. This data will be available to all conference participants in peer.appData
Client observer events
The next step is to subscribe to client events on client.observer.
For example:
client.observer.on('peer-joined', (peer) => {
// Save the received peer instance in your application
});
client.observer.on('peer-left', (peer) => {
// Delete the received peer instance in your application
});
client.observer.on('channel-rejoin-required', () => {
// The connection to the server was lost and is now restored.
// You can call client.leave() and client.join() to reconnect to a channel
});
client.observer.on('channel-rejoin-required', () => {
// The connection to the server was lost and is now restored.
// You can call client.leave() and client.join() to reconnect to a channel
});
client.observer.on('devices-list-updated', (devices) => {
// Calls if available devices list in your browser has changed
});
client.observer.on('transport-connection-timeout', (direction, reason) => {
// Calls if your RTCDtlsTransport connection was not established
});
client.observer.on('channel-event', (event) => {
// Do everything you want with your own custom messages
});
You can read more about sending custom messages in the Management-API docs.
Peers
Then you can receive list of peers in channel with client.loadPeers() with specific Roles and save it instances in your application. Peer is a conference participant.
await client.loadPeers('host');
const peers = client.peers;
Peer observer events
And subscribe to peer events on peer.observer for each peer similar to subscribing to client events
peer.observer.on('media-published', (publisher) => {
// Peer published media, you can call peer.subscribe(publisher.producerId)
});
peer.observer.on('media-unpublished', (publisher) => {
// Peer stopped publishing media, this publisher can be deleted
});
peer.observer.on('connection-quality-changed', (connectionQuality) => {
// You can display the connection quality of this peer in your app
});
peer.observer.on('track-start', (track) => {
// You have successfully subscribed to the publication of this peer and now track is available to you
});
peer.observer.on('track-end', (track) => {
// Peer stopped publishing the track, this track can be deleted
});
peer.observer.on('track-paused', (track) => {
// Track was paused
});
peer.observer.on('track-resumed', (track) => {
// Track was reumed
});
Getting remote peers media tracks
If you just received a “media-published” event, uploaded a peer list from client.peers, or received a “peer-joined” event, the next step is to get the list of Publishers of this peer, or use the Publisher that you received from the Peer observer and subscribe on this publisher.
await peer.subscribe(publisher.producerId);
After that, you will receive a “track-start” event from the peer observer containing PeerTrack. You can get acquainted with the properties and methods of tracks in the corresponding section of the documentation.
Depending on the track kind, you can render it with a MediaStreamTrack on a video or audio html element.
You can control the quality of PeerTrack, see more at PeerTrack.requestVideoPreferredLayers
Getting own media tracks
First you need to get a list of available media devices on your device
await client.detectDevices();
const mediaDevices = [...client.availableVideoDevices, ...client.availableAudioDevices];
For each MediaDevice you can get a Track and publish it. If you do not specify deviceId when creating a track, then the track will be created for the default device for each track kind.
const cameraTrack = await client.createCameraVideoTrack(options);
You can see more about options for create Tracks in CreateTrackOptions
Client has a creation method for each track kind.
createCameraVideoTrack
createMicrophoneAudioTrack
createScreenMediaTracks
Publishing media to a channel
await cameraTrack.publish();
After that, all peers in the channel will receive the “media-published” event, and your peer will immediately receive “track-started” - no need to subscribe to your own Publisher, for save resources.
Disconnecting
await client.leave();
Basic example
This example shows how to create a “conference viewer” application
import Client from '@livedigital/client';
const startConference = async () => {
const client = new Client();
client.observer.on('peer-joined', async (peer) => {
subscribePeerEvents(peer);
await subscribePeerPublishers(peer);
});
await client.join({
appId: '62138aae16def841275b2745',
channelId: '62138aba16def841275b2752',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
role: 'audience',
});
await client.loadPeers('host');
const { peers } = client;
peers.forEach((peer) => subscribePeerEvents(peer));
await Promise.all(peers.map((peer) => subscribePeerPublishers(peer)));
}
const subscribePeerEvents = (peer) => {
peer.observer.on('media-published', async (publisher) => {
await peer.subscribe(publisher.producerId);
});
peer.observer.on('track-start', (track) => {
// You have successfully subscribed to the publication of this peer and now track is available to you
// render track on video or audio element
});
}
const subscribePeerPublishers = async (peer) => {
await Promise.all(peer.publishedMedia.map((publisher) => peer.subscribe(publisher.producer.id)));
}
(async () => {
await startConference();
})()