Setting up a video call

This tutorial will walk you through the steps of setting up a basic client using the Between API. By following this guide, you'll learn how to create a video call application and manage the call states.

Sample App

If you want to play arround with Between first, you can download sample app by clicking the button below:

DOWNLOAD SAMPLE APP

Navigate to src > Voip > index.js and replace this line with your API key:

const apiKey = 'API_KEY';

Now, make sure you are in the react-between-sample folder, and run the following command:

yarn && yarn start

It should start Between on http://localhost:3000/ and to invite others to your call, you can use ngrok

Prerequisites

If you have signed up for Between, you should have received an email that lets you login to the Between dashboard. If you have not yet signed up for Between, click here to create an account. You can get your API key after signing up.

A lot of the concepts in this page will be self-explanatory, but for beginners we recommend they head on over to the Basic Concepts page to learn the Between API.

Step 1: Import and initialize the Conference

The Conference object is crucial for establishing a video call. It is initialized with three parameters:

Note: If you have no customUserData, you cannot omit the third argument. You must make it null

import { Conference } from 'between-api'

let apiKey = ""; // Replace this with your API key
let customCallId = ""; // Optional: Replace this with your custom call ID
let customUserData = {}; // Replace this with your custom user data

let conf = new Conference(apiKey, customCallId, customUserData)
conf.id // custom or auto generated callId

// we set the current user's location type
conf.setLocationType("offsite")   

Step 2: Handling device permissions

Before starting a video call, we need to request permission to access the user's microphone and camera. Between simplifies this process by providing a built-in method called getPermissionState. This method unifies permission handling across all browsers and returns a DevicePermissionState object.

If the user denies permission, it's a good idea to handle this situation by displaying an alert. To learn more about how devices are used in Between, visit the Adjusting Audio/Video section.

// this will ask the user for media permissions
let status = await conf.getPermissionState()

// if the user denies permission, handle that
if (status.state === "denied" || status.state === "failed") {
    alert(status.error.rawStr)
    return
}

Step 3: Setting up session listeners

Between uses simple listeners to keep information up-to-date throughout the lifetime of the call. For this example, we'll cover three main listeners: localParticipant, peerJoined, and peerLeft.

The localParticipant listener is used to get a local video stream of the publishing user.

The peerJoined listener is called when a new user joins the call.

The peerLeft listener is called when any user leaves the call.

// we will setup all the relevant events to listen for

let local;
let remoteParticpants = {}

// setup the localParticipant listener
conf.on("localParticipant", (lp: LocalParticipant) => {
    // returns a LocalParticipant object
    // we will use this to publish audio/video
    // also to change devices throughout the conference 
    local = lp
    
    local.on("videoCreated", (video: HTMLVideoElement) => {
        // we get a local video stream of the publishing user
        // add the video element to the DOM
        document.getElementById('localVideo').append(video);
    })
})

conf.on("peerJoined", (peer: Peer) => {
    // returns a Peer object 
    
    // called whenever someone has entered the call
    // we will use this to get information about other
    // Peers in the call

    // NOTE: peer.id is customUserData that we initiated with

    peer.on('videoCreated', (video: HTMLVideoElement) => {
        // the remote user has published a video
        // add the video element to the DOM
        document.getElementById('remoteStreams').append(video)
    })

    // add this to our local array to use later
    // for volume, getting spatial data, etc..
    remoteParticpants[peer.id] = peer

})

conf.on("peerLeft", (id: string) => {
    // the peer has left the call

    delete remoteParticpants[id]
    document.getElementById(id).remove()
})

Step 4: Handling termination and starting the call

We can start the call with the startCall method. As for termination, Between dispatches the sessionTerminated listener for when the conference ends through either user input or unexpectedly, visit the Conference reference section to learn more about handling errors.

// Finally we will start the call
try {
  await conf.startCall()
} catch (error) {
  console.log('error', error)
}

// Set up the sessionTerminated listener
conf.on("sessionTerminated", () => {
    // The call has ended
    // Clear the local and remote participants
    local = null
    remoteParticpants = {}
})

Troubleshooting

Errors are a part of every project lifecycle. If your Peers are having issues starting or joining calls, we provide detailed call logs to help you diagnose. These logs include information such as:

If you are not able to resolve the issue on your own, please contact your Between consultant. You should be able to do so in the Between Dashboard

Next Steps

Your participants will want to do more than just start and join a call. They'll want to plug in their headphones, mute someone else, and more. Click here to learn how to do this.