# Javascript SDK

# Installation

# CDN

The JS SDK is available as a UMD or ESM module and can be included in you application via a <script> tag.

<!-- UMD -->
<script src="https://sdk.virtualcareservices.net/dist/umd/vcs-realtime-sdk.min.js"></script>

<!-- ESM -->
<script type="module" src="https://sdk.virtualcareservices.net/dist/mjs/vcs-realtime-sdk.min.mjs"></script>

# npm/yarn

Until the module is published on npm, it can be downloaded from https://sdk.virtualcareservices.net/dist/vcs-realtime-sdk.tgz (opens new window).

npm install https://sdk.virtualcareservices.net/dist/vcs-realtime-sdk.tgz

# Builds

The JS vcs-realtime-sdk has two build versions: ES and UMD. The UMD version can be used for CommonJS, AMD and browser globals.

ES modules:

import { joinRoom } from 'vcs-realtime-sdk';

Browser global:

When loading the UMD version via script, the realtime SDK is exposed as a RealtimeSdk global variable.

<script src="https://sdk.virtualcareservices.net/dist/umd/vcs-realtime-sdk.min.js"></script>
<script>
  RealtimeSdk.joinRoom(<TOKEN>).then(...)
</script>

# Examples

# Join room

import { joinRoom } from 'vcs-realtime-sdk';

const room = await joinRoom(<TOKEN>);
console.log(`Joined ${room.name} with ${room.remoteParticipants.length} participants`);

# Join room with audio only

const room = await joinRoom(<TOKEN>, {
  audio: true,
  video: false,
  name: 'Bob'
});

# Join room with HD video

const room = await joinRoom(<TOKEN>, { hdVideo: true });

# Join room with mediaStream

// Create your own mediaStream via navigator.mediaDevices.getUserMedia or
// or canvas.captureStream for example.
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const room = await joinRoom(<TOKEN>, { mediaStream: stream });

# Don't ask for camera/mic until other participant(s) joined

const room = await joinRoom(<TOKEN>, { delayLocalStream: true });

# Display local mediaStream

const room = await joinRoom(<TOKEN>);

// Attach local mediaStream yourself in which case you
// are responsible to listen for `localStream` event and 
// update video element's srcObject.
document.querySelector('#localVideo').srcObject = room.localParticipant.mediaStream;

// ...or let the SDK handle mediaStream changes by providng a wrapper div
const div = document.createElement('div');
room.localParticipant.attach(div, { width: '200px' });
document.body.appendChild(div);

# Display remote mediaStreams

const room = await joinRoom(<TOKEN>);

// Show participant already in the room
room.remoteParticipants.forEach(render);

// Show new participant joining
room.on('participantJoined', render);

function render(participant) {
  const div = document.createElement('div');
  participant.attach(div);
  document.body.appendChild(div);
}

# Mute/unmute

room.toggleMute();
const muted = room.isMuted();

# Toggle video

await room.toggleVideo();
const hasVideo = room.hasVideo();

# Toggle Audio

toggleAudio will add or remove an audio MediaStreamTrack to the local MediaStream. This is different from toggleMute which simply enables/disables the existing audio track.

const hasAudio = await room.toggleAudio();

# Replace the local media stream

Create your own mediaStream via navigator.mediaDevices.getUserMedia or or canvas.captureStream for example.

const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const room = await room.replaceVideoStream(stream);

# Switch camera on mobile

await room.switchCamera();
console.log(`Camera facing ${room.cameraFacingMode})`;

# Remove participant that left

If participant was attached using the attach API, then the SDK will remove the participant video. But if you created the video element manually, you are responsible to listen for participantLeft and remove the video element.

room.on('participantLeft', participant => {
  document.querySelector(<selector of video el>).remove();
});

# Leave a room

const room = await joinRoom(<TOKEN>);
room.leave();

# Use participant info

You can pass a name and other arbitrary data as options to joinRoom. This info is exchanged with all participants.

const room = await joinRoom(<TOKEN>, {
  name: 'Bob',
  participantInfo: {
    age: 32,
    town: 'Wilen'
  }
});

# Presenting incoming calls

By setting the autoanswer option to false, participants are presented an incoming call that can be accepted or declined. This will require the participant to be registered before receiving a call. The application will be responsible to signal this to the receiving party.

//TODO

# Set preferred device

import { Device } from 'vcs-realtime-sdk';
const devices = Device.getDevices();
console.log('Available microphones: ', devices.audioInputList);
console.log('Preferred microphone: ', devices.audioInput);
Device.setPreferredDevice(devices.audioInputList[0].deviceId, 'audioinput');

# Logging

Pass a custom logger to the SDK such as the browser's console object, or as shown below a third party logger (opens new window).

import * as log from 'loglevel';
import { setLogger } from 'vcs-realtime-sdk';

log.setLevel('debug');
// Important to set the custom SDK logger after setting the log level.
// The SDK now logs all debug, info, warn and error statements.
setLogger(log);

// Log statement of own app
log.warn('[myapp] warning!');

# Data Channel

Exchange messages (JSON objects) between participants based on WebRTC Data Channels. Messages can be sent to a single participant or broadcasted to all participants.

const room = await joinRoom(<TOKEN>);

// Send message to newly joined participant
room.on('participantJoined', async p => {
  await room.sendMessageToParticipant({ text: `Welcome to room ${room.name}` }, p.address);
});

// Listen to messages from other participants
room.on('messageReceived', (participant, data) => {
  alert(`Participant ${participant.address} sent message: ${data}`);
});