Web - JavaScript/ReactJS

Overview

Follow this step by step tutorial to implement the Watch Together video chat sample application.
While the client-side application will take care of most of the functionality, in order to make this sample application work, you will need to get an access token from the Cluster Authentication Server (CAS).

Requirements

To complete this guide successfully the following prerequisites are required:

Authentication

An Access Token is needed in order to allow a client to connect to a Session.
Note: It is important that the client application does not request an Access Token directly from the frontend. By doing that you risk exposing the API_TOKEN and API_SECRET.
  • To learn how to acquire an Access Token please look at the Cluster Authentication Server (CAS) reference
  • To simplify the tutorial, in the section below you can see an example of getting an Access Token.

Acquiring an Access Token

cUrl(Bash)
curl -iL --request GET --url https://YOUR_CAS_URL/stream/token --header 'auth-api-key: API_KEY' --header 'auth-api-secret: API_SECRET'
The Access Token is a JWT token - more about jwt you can read - here.
A successful response will look like that:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...."
}
You can get your API_KEY and API_SECRET in your private area, here.
Note: Every Streaming Token corresponds to one specific Session only. To allow two different clients to connect to the same Session, the clients need to use the same Access Token.

Going to production

When moving from the Sandbox environment to production you will need to implement your own authentication server. This server will supply the various clients (Web, Android, and iOS) with a valid Access Token so that they can use the service.
For that you will need:
  • API_KEY, and API_SECRET - can be retrieved in your private area once you login
  • Your own working authentication server - Authentication overview

Create a New Project

JavaScript
  • Open WebStorm and create a new Empty Project
  • Create two files index.js and index.html in your project folder.
React
React JSX
npx create-react-app websdksample
cd websdksample
npm start
If you've previously installed create-react-app globally via npm install -g create-react-app, we recommend you uninstall the package using npm uninstall -g create-react-app to ensure that npx always uses the latest version.
Note: npx comes with npm 5.2+ and higher
  • Then open your project through code editor.

Adding Watch Together SDK library to the project

Follow the instructions to add the WebSDK into your project.
  • In the project’s root folder create .npmrc file
  • Put your Access Token inside //registry.npmjs.org/:_authToken=YOUR_ACCESS_TOKEN
  • Install WebSDK vianpm i @sscale/wtsdk
For more information on NPM installation look here.

Connecting to a Session

React JSX
JavaScript
const startConnecting = (streamingToken, pareticipantName) => {
WT.Session.connect(stremingToken, );
};
WT.SessionListeners.onStreamCreated((params) => {
setParticipants([...participantsRef.current, params])
});
WT.Session.connect(streamingToken, participantName)
WT.SessionListeners.onConnected(() => {
WT.SessionListeners.onStreamCreated((stream) => {
const { local, participantId, stream } = stream;
const video = document.createElement("video")
video.id = participantId;
video.autoplay = true;
video.muted = local ? true : false
video.srcObject = stream;
// append video to container
const container = document.querySelector("#example")
container.appendChild(video)
})

Sample application UI

To connect two or more users to the same Session follow the steps below:
  1. 1.
    Make sure you have acquired a valid Access Token (as explained in the Authentication section)
  2. 2.
    Share Streaming token between clients that need to join the same Session
  3. 3.
    Each client should invoke Session.connect(streamingToken, participantName)
JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WT Demo</title>
<!-- Connect Watch Together SDK -->
<script src="./WTSDK.js"></script>
</head>
<body>
<button onclick="connect()">Start</button>
<button onclick="disconnect()">Disconnect</button>
<button onclick="videoOn()">Video ON</button>
<button onclick="videoOff()">Video OFF</button>
<button onclick="voiceOn()">Voice ON</button>
<button onclick="voiceOff()">Voice Off</button>
<button onclick="screenSharing()">Screen Share</button>
<button onclick="stopScreenSharing()">Stop Screen Share</button>
<div id="video">
<!-- Container for video streams -->
</div>
<script src="./index.js"></script>
</body>
</html>
ReactJS
Participant video component
import React, {useEffect, useRef} from 'react';
const VideoContainer = ({
stream,
participant,
isLocal,
isMuted,
isVideoEnabled,
toggleAudio,
toggleVideo
}) => {
const video = useRef(null);
useEffect(() => {
if (stream && video) {
video.current.srcObject = stream;
video.current.onclick = () => false;
video.current.ondblclick = toggleFullscreen;
}
}, []);
const toggleFullscreen = e => {
if (!document.fullscreenElement) {
const fullScreenFunc = e.target.requestFullscreen ||
e.target.mozRequestFullScreen ||
e.target.webkitRequestFullscreen ||
e.target.msRequestFullscreen
if (fullScreenFunc) {
fullScreenFunc();
}
e.target.controls = false;
} else {
document.exitFullscreen();
e.target.controls = true;
}
};
return (
<div
id={`video-${participant}`}
className={`video ${isLocal ? 'local' : ''}`}>
<div className='participant' id={participant}>
{isLocal ? <>
<button
className={`toggleAudio ${isMuted ? 'muted' : 'unmuted'}`}
onClick={toggleAudio}
>
{
isMuted ?
<i
className='zmdi zmdi-volume-off size-normal'
style={{color: 'white'}}
/>
:
<i
className='zmdi zmdi-volume-up size-normal'
style={{color: 'white'}}
/>
}
</button>
<button
className={`toggleVideo ${isVideoEnabled ? 'videoOff' : 'videoOn'}`}
onClick={toggleVideo}
>
{
isVideoEnabled ?
<i
className='zmdi zmdi-videocam-off size-normal'
style={{color: 'white'}}
/>
:
<i
className='zmdi zmdi-videocam size-normal'
style={{color: 'white'}}
/>
}
</button>
</>
: ''
}
<video
id={`native-video-${participant}`}
ref={video}
autoPlay
muted={isLocal}
controls
disablePictureInPicture
playsInline
/>
</div>
</div>
);
};
export default VideoContainer;

Known Issues

  • IE, and old Edge (A new one, chromium-based was released on January 2020) are not supported
  • Screen sharing is not supported in Safari
  • Screen sharing is flickering on Firefox 72 version - browser issue

Supported browsers

  • Google Chrome browser (Screen sharing from 72+ version)
  • Firefox browser (latest release version) from v.66
  • Opera browser (latest release version) from 63+
  • Safari browser (latest release version)
  • Mobile Google Chrome browser
  • Mobile Firefox browser
  • Mobile Opera
  • Mobile Safari

Next steps

Support

Need technical support? contact us at [email protected].
Copy link
On this page
Overview
Requirements
Authentication
Acquiring an Access Token
Going to production
Create a New Project
Adding Watch Together SDK library to the project
Connecting to a Session
Sample application UI
Known Issues
Supported browsers
Next steps
Support