Hire the author: Sunny G

Introduction

In this blog, I will talk about how to make a real-time communication app using the agora package. It can be implemented using the npm Agora RTC package which is used to send and receive audio/video of the user. I will walk you through all the things step by step. For sharing audio/video we used the agora-rtc-sdk-ng package.

You can easily set up this package in your project. For video sharing, agora is best to fulfil your requirements. It provides full customization. As we know virtual event is a trendy market right now. Agora SDK is best to create a virtual event platform. Agora is also good at live engagement and interaction. They specialize in live video, audio, and broadcasting. Built using SD-RTN. They own the network and can provide the flexibility and support that no other provider gives.

What is the agora rtc package?

Agora NG Web-SDK is a full-featured SDK to implement streaming. It is an updated version of agora-rtc-sdk. ng package is completely different from the agora-rtc-sdk. If you migrate from RTC SDK to SDK ng, you need to put lots of effort to achieve this. The previous version of the Agora RTC SDK library is not preferable to use.

The main update in the new version is that they replaced the Stream object with the Local Track and Remote Track objects for controlling the media stream. Other features you can implement with this app are Image beautification, live streaming, screen sharing, and sharing audio/video tracks.

Learning Strategies and Tools

To create a basic application these are some prerequisites that you must need to keep in mind.

  • Angular 2+ knowledge
  • Typescript
  • Node.js commands
  • Agora RTC sdk ng package
  • agora RTC token
  • Create new project here console.agora.io. After that you will get appID which you can use to run the app.
  • visual studio code

Project Setup

Install Node and run the below commands after that

To install angular

>npm install -g @angular/cli 

To create a new application

>ng new agora-app 

To change directory

>cd agora-app

To run the application

>ng serve 

To install agora rtc dependencies

>npm i agora-rtc-sdk-ng 

File structure

To create a video call app The core things that we require are services and components.

API service includes:

As I mentioned above we need an agora RTC token to start a call. Here we are going to use the API with this API you can generate RTC tokens. So, This service is used to run the HTTP request to get the RTC token.

Stream service includes:

This service is used to add RTC utilities and store variables, create RTC clients etc. It is also used to import packages so that you can do the call initialization or other kinds of stuff. Here we are going to handle how we can play the video and audio of users. 

The basic component includes:

The component is to display the UI of joined users. Created two buttons Join and Leave. containers to show video of users.

Routing file includes:

Create routes so that multiple users can join the call. As we know to join a call we need a link so that users can join the call. So the route is a link that we need to create also.

Step by Step Procedure

Step 1: using agora RTC SDK utilities/services-

To start a call, you need to create an RTC client that provides functions to connect your system to Agora servers. With the Agora create client method it creates a local client object with your appID. After this creation you need to call the Agora join method then you have to create an instance of local tracks or a media stream. A media stream consists of an audio and video track. This package controls the stream by operating the tracks. It is built using webRTC.

With this, you need to create a local audio-video stream to send to the remote user. If we want to display the stream on our screen then pass the DOM element id where you want to show video in HTML template in the play method.

Here we have to maintain a remote user ids list so that we can track easily who has joined the channel. AgoraRTCClient object is the main utility or service that provides various functions to join a call, publish local audio and video tracks etc.

Local Track and Remote Track objects provide methods for controlling audio, video, basically playback control.

Step 2:creating client roles

In this library, two types of client roles are present- host, audience.

All users are host by default. When the user publishes a stream then events start work. It is important to declare a role if you are creating a hosting app. call the setClientRole method to set the user role as host before calling publish method.

If the user role is the audience then the user can only watch and not able to publish their tracks.

The package does not automatically set the user role as host before calling publish method. you need to set the client role host before calling this method.

Note: If the stream is published, they automatically become hosts, if it is unpublished, they automatically become an audience.

You can refer more to Agora RTC’s basic processes and objects in the below code. I will also give you all code in the end for your reference.

Step 3: Adding Functions and agora events

To utilize Agora functions, you have to use the async-await method to handle the Join and Leave button event.

When a remote user publishes media tracks, the SDK triggers user-published event, in which you can get an Agora RTC Remote User object. You need to listen for this event with client.on and call Agora RTC Client.subscribe in the callback to subscribe to this remote user.

To automatically subscribe to the remote user who publishes media tracks, and play the media tracks, we add the following code to listen for user-published.

When the remote user unpublished a media track or leaves the channel, the SDK triggers user-unpublished event.

Step 4: Creating rtc streaming angular service

rtcstream.service.ts

import AgoraRTC, { IAgoraRTCClient, LiveStreamingTranscodingConfig, ICameraVideoTrack, IMicrophoneAudioTrack, ScreenVideoTrackInitConfig, VideoEncoderConfiguration, AREAS, IRemoteAudioTrack, ClientRole } from "agora-rtc-sdk-ng"
import { BehaviorSubject } from 'rxjs';
import { ApiService } from './api.service';
rtc: IRtc = {
// For the local client.
client: null,
// For the local audio and video tracks.
localAudioTrack: null,
localVideoTrack: null,
};
options = {
appId: "", // set your appid here
channel: "test", // Set the channel name.
// token: '', // Pass a token if your project enables the App Certificate.
// uid: null
};
remoteUsers: IUser[] = []; // To add remote users in list
updateUserInfo = new BehaviorSubject<any>(null); // to update remote users name
constructor(public api: ApiService) { }
createRTCClient() {
this.rtc.client = AgoraRTC.createClient({ mode: "rtc", codec: "h264" });
}
// To join a call with tracks (video or audio)
async localUser(token, uuid) {
const uid = await this.rtc.client.join(this.options.appId, this.options.channel,
token, uuid);
// Create an audio track from the audio sampled by a microphone.
this.rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
// Create a video track from the video captured by a camera.
this.rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack({
encoderConfig: "120p",
});
// Publish the local audio and video tracks to the channel.
this.rtc.localVideoTrack.play("local-player");
// channel for other users to subscribe to it.
await this.rtc.client.publish([this.rtc.localAudioTrack, this.rtc.localVideoTrack]);
}
agoraServerEvents(rtc) {
rtc.client.on("user-published", async (user, mediaType) => {
console.log(user, mediaType, 'user-published');
await rtc.client.subscribe(user, mediaType);
if (mediaType === "video") {
const remoteVideoTrack = user.videoTrack;
remoteVideoTrack.play('remote-playerlist' + user.uid);
}
if (mediaType === "audio") {
const remoteAudioTrack = user.audioTrack;
remoteAudioTrack.play();
}
});
rtc.client.on("user-unpublished", user => {
console.log(user, 'user-unpublished');
});
rtc.client.on("user-joined", (user) => {
let id = user.uid;
this.remoteUsers.push({ 'uid': +id });
this.updateUserInfo.next(id);
console.log("user-joined", user, this.remoteUsers, 'event1');
});
}
// To leave channel-
async leaveCall() {
// Destroy the local audio and video tracks.
this.rtc.localAudioTrack.close();
this.rtc.localVideoTrack.close();
// Traverse all remote users.
this.rtc.client.remoteUsers.forEach(user => {
// Destroy the dynamically created DIV container.
const playerContainer = document.getElementById('remote-playerlist' + user.uid.toString());
playerContainer && playerContainer.remove();
});
// Leave the channel.
await this.rtc.client.leave();
}
// rtc token
async generateTokenAndUid(uid) {
let url = 'https://test-agora.herokuapp.com/access_token?&#39;;
const opts = { params: new HttpParams({ fromString: "channel=test&uid=" + uid }) };
const data = await this.api.getRequest(url, opts.params).toPromise();
return { 'uid': uid, token: data['token'] }
}
generateUid() {
const length = 5;
const randomNo = (Math.floor(Math.pow(10, length 1) + Math.random() * 9 * Math.pow(10, length 1)));
return randomNo;
}
}
export interface IUser {
uid: number;
name?: string;
}
export interface IRtc {
client: IAgoraRTCClient,
localAudioTrack: IMicrophoneAudioTrack,
localVideoTrack: ICameraVideoTrack
}

Step 5: Creating component to start a call-

app.component.html

<div class="container-fluid banner">
<p class="banner-text">Video Call</p>
</div>
<div class="container">
<form id="join-form" name="join-form" class="mt-4">
<div class="row join-info-group">
<div class="col-sm">
<p class="join-info-text">Join call</p>
</div>
</div>
<!– UI Controls –>
<div class="button-group mt-3">
<button id="join" type="submit" class="btn btn-live btn-sm" (click)="startCall()">Join</button>
<button id="mic-btn" type="button" class="btn btn-live btn-sm" [disabled]="this.hideBtns">
<i id="mic-icon" class="fas fa-microphone"></i>
</button>
<button id="leave" type="button" class="btn btn-live btn-sm" [disabled]="this.hideBtns" (click)="logout()">Leave</button>
</div>
</form>
<!– Streams –>
<div class="row video-group">
<div class="col">
<p id="local-player-name" class="player-name"></p>
<div id="local-player" class="player"></div>
</div>
<div class="w-100">Remote Users</div>
<div class="col" *ngFor="let i of stream.remoteUsers">
<div id="{{ 'remote-playerlist' + i.uid}}" class="ui centered medium image" style=" width: 200px;
height: 200px;">{{i.name}}</div>
</div>
</div>
</div>

Step 6: Integrating service to the component to start a call

app.component.ts

hideBtns = true;
async startCall() {
const uid = this.stream.generateUid();
const rtcDetails = await this.stream.generateTokenAndUid(uid);
this.stream.createRTCClient();
this.stream.agoraServerEvents(this.stream.rtc);
await this.stream.localUser(rtcDetails.token, uid);
this.hideBtns = false;
}
async logout() {
await this.stream.leaveCall();
}

Now we have successfully created a simple video calling. you can feel free to change the styles and add more features like Image enhancement, etc.

Future Directions

With this package, you can create below functionalities:

  • video call Applications (conferencing tool, Group video calling)
  • voice call Applications.
  • live interactive voice/video streaming app – You can broadcast a live video in your app. In this single person stream, the video and other people can see it.
  • live podcasting app

Reflective Analysis

The end result is below. Here the feature we are have added is On the start call button click the User can join the call with his audio/video. Simple to use app:

How to Test this Video App

Run the app using ng serve command.

After this, you can open these links in two tabs.

http://localhost:4200/user/1

http://localhost:4200/user/2

Click on the join now button to connect the call

Glossary

Here’s an video app glossary:

  • RTC: real time communication on web
  • SD-RTN: Software Defined Real-time Network, is a real-time transmission network built by Agora.
  • appID: project id that you create on Agora console
  • stream: kind of data stream of video and audio tracks

Conclusion

It is simple to create a basic video app with these Agora packages. You can integrate this with any client-side framework. Here i have integrated the packages using the angular framework.

More Resources

GitHub repository for the source code – check the master branch in this repo.

For more info you can check:

reference link:

I also invite you to join the Agora.io Developer Slack community:

For more interesting blogs check: LD blog

Hire the author: Sunny G