logo
Live Streaming
On this page

Implementing Video Call with Angular (Web)


Feature Overview

This document introduces how to quickly use Angular to implement a simple Video Call.

Explanation of related concepts:

  • ZEGO Express SDK: A real-time audio/video SDK provided by ZEGO that offers developers convenient integration, high definition and smoothness, multi-platform interoperability, low latency, and high concurrency audio/video services.
  • Publish stream: The process of transmitting captured and packaged audio/video data streams to the ZEGO real-time audio/video cloud.
  • Play stream: The process of pulling existing audio/video data streams from the ZEGO real-time audio/video cloud.

Prerequisites

Before implementing basic Video Call functionality, ensure that:

Example Source Code Download

Please refer to Download Example Source Code to obtain the source code.

For relevant source code, please view files in the "/express-demo-web/src/Examples/Framework/Angular/angular" directory.

Usage Steps

Note

The Node version used in the current project is 14.17.3, and the Angular/cli version is 12.1.4.

Taking user A playing user B's stream as an example, the flow is as follows:

The API call sequence of the entire stream publishing and playing process is as follows:

Create Engine

(Optional) Create UI

Before creating the engine, it is recommended for developers to add the following UI elements to facilitate the implementation of basic Video Call functionality.

  • Local preview window
  • Remote video window
  • End button

Create Engine

Create a ZegoExpressEngine engine instance, pass the obtained AppID to the "appID" parameter, and pass the access server address to the "server" parameter.

Note
  • "server" is the access server address. For information on how to obtain it, please refer to Console - Project Information.
  • For SDK version 3.6.0 and above, server can be set to an empty string, null, undefined, or any arbitrary string, but cannot be left empty.
// Initialize instance
export class AppComponent {
    zg:any = null;

    createZegoExpressEngine() {
        this.zg = new ZegoExpressEngine(appID, server);
    }
}

(Optional) Listen to Event Callbacks

If you need to register callbacks, developers can implement certain methods in ZegoEvent (including ZegoRTCEvent and ZegoRTMEvent) according to actual needs. After creating the engine, you can set callbacks by calling the on interface.

this.zg.on('roomStateChanged', (roomID, reason, errorCode, extendData) => {
        if (reason == ZegoRoomStateChangedReason.Logining) {
            // Logging in
        } else if (reason == ZegoRoomStateChangedReason.Logined) {
            // Login successful
            //Only when the room status is login successful or reconnection successful can stream publishing (startPublishingStream) and stream playing (startPlayingStream) normally send and receive audio and video
            //Publish your own audio/video stream to the ZEGO audio/video cloud
        } else if (reason == ZegoRoomStateChangedReason.LoginFailed) {
            // Login failed
        } else if (reason == ZegoRoomStateChangedReason.Reconnecting) {
            // Reconnecting
        } else if (reason == ZegoRoomStateChangedReason.Reconnected) {
            // Reconnection successful
        } else if (reason == ZegoRoomStateChangedReason.ReconnectFailed) {
            // Reconnection failed
        } else if (reason == ZegoRoomStateChangedReason.Kickout) {
            // Kicked out of the room
        } else if (reason == ZegoRoomStateChangedReason.Logout) {
            // Logout successful
        } else if (reason == ZegoRoomStateChangedReason.LogoutFailed) {
            // Logout failed
        }
});

(Optional) Check Compatibility

Before implementing stream publishing and playing functionality, developers can call the checkSystemRequirements interface to check browser compatibility.

For browser versions supported by the SDK, please refer to "Prepare Environment" in Download Example Source Code.

const result = await this.zg.checkSystemRequirements();
// The returned result is the compatibility check result. When webRTC is true, it means webRTC is supported. For the meaning of other properties, please refer to the interface API documentation
console.log(result);
// {
//   webRTC: true,
//   customCapture: true,
//   camera: true,
//   microphone: true,
//   videoCodec: { H264: true, H265: false, VP8: true, VP9: true },
//   screenSharing: true,
//   errInfo: {}
// }

For the meaning of each parameter in the returned result, please refer to the parameter description under the ZegoCapabilityDetection interface.

Login Room

Generate Token

Logging into a room requires a Token for identity verification. For information on how to obtain it, please refer to Using Token Authentication. For quick debugging, you can use the console to generate a temporary Token.

Login Room

Call the loginRoom interface, pass in the room ID parameter "roomID", "token", and the user parameter "user", and log in to the room by passing in the "config" parameter according to the actual situation.

Warning
  • Before logging into a room, please register all callbacks that need to be monitored after logging into the room. After successfully logging into the room, you can receive relevant callbacks.
  • The values of the "roomID", "userID", and "userName" parameters are all customizable.
  • Both "roomID" and "userID" must be unique. It is recommended for developers to set "userID" to a meaningful value and associate it with the business account system.
// Login to the room, returns true if successful
// Setting userUpdate to true will enable monitoring of the roomUserUpdate callback. By default, this monitoring is not enabled
const result = await this.zg.loginRoom(roomID, token, {userID, userName}, {userUpdate: true});

Listen to Event Callbacks After Login Room

According to actual application needs, listen to event notifications of interest before logging into the room, such as room status updates, user status updates, stream status updates, etc.

  • roomStateChanged: Room status update callback. After logging into the room, when the room connection status changes (such as room disconnection, login authentication failure, etc.), the SDK will notify through this callback.

  • roomUserUpdate: User status update callback. After logging into the room, when users are added to or removed from the room, the SDK will notify through this callback.

    Users can receive the roomUserUpdate callback only when calling the loginRoom interface to log into the room with the ZegoRoomConfig configuration passed in and the "userUpdate" parameter set to "true".

  • roomStreamUpdate: Stream status update callback. After logging into the room, when users add or delete audio/video streams in the room, the SDK will notify through this callback.

Warning

Normally, if a user wants to play videos published by other users, they can call the startPlayingStream interface in the callback of stream status update (ADD) to play remote published audio/video streams.

// Room status update callback
this.zg.on('roomStateChanged', (roomID, reason, errorCode, extendData) => {
        if (reason == ZegoRoomStateChangedReason.Logining) {
            // Logging in
        } else if (reason == ZegoRoomStateChangedReason.Logined) {
            // Login successful
            //Only when the room status is login successful or reconnection successful can stream publishing (startPublishingStream) and stream playing (startPlayingStream) normally send and receive audio and video
            //Publish your own audio/video stream to the ZEGO audio/video cloud
        } else if (reason == ZegoRoomStateChangedReason.LoginFailed) {
            // Login failed
        } else if (reason == ZegoRoomStateChangedReason.Reconnecting) {
            // Reconnecting
        } else if (reason == ZegoRoomStateChangedReason.Reconnected) {
            // Reconnection successful
        } else if (reason == ZegoRoomStateChangedReason.ReconnectFailed) {
            // Reconnection failed
        } else if (reason == ZegoRoomStateChangedReason.Kickout) {
            // Kicked out of the room
        } else if (reason == ZegoRoomStateChangedReason.Logout) {
            // Logout successful
        } else if (reason == ZegoRoomStateChangedReason.LogoutFailed) {
            // Logout failed
        }
});

// User status update callback
this.zg.on('roomUserUpdate', (roomID, updateType, userList) => {
    console.warn(
        `roomUserUpdate: room ${roomID}, user ${updateType === 'ADD' ? 'added' : 'left'} `,
        JSON.stringify(userList),
    );
});

// Stream status update callback
// For specific implementation of the callback method, please refer to the "Video Call" example source code file /src/Examples/QuickStart/VideoTalk/index.js
this.zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {
    if (updateType == 'ADD') {
        // Stream added, start playing stream
    } else if (updateType == 'DELETE') {
        // Stream deleted, stop playing stream
    }
});

Publish Stream

Create Stream

  1. Before starting to publish a stream, you need to create a local audio/video stream. Call the createZegoStream interface, which by default captures camera footage and microphone sound.
Warning

After calling the createZegoStream interface, you need to wait for the ZEGO server to return the media stream object before performing subsequent operations.

HTML creates a container <div> for the media stream player component.

<div id="local-video" style="width: 320px;height: 240px;"></div>

Play the media stream after creating the stream.

// After calling the createZegoStream interface, you need to wait for the ZEGO server to return the media stream object before performing subsequent operations
this.localStream = await this.zg.createZegoStream({
    camera: {
        video: {
          input: videoDeviceID
        },
        audio: {
          input: audioDeviceID
        },
    }
});
  1. (Optional) Set audio/video capture parameters

You can set audio/video related capture parameters through the following properties in the createZegoStream interface as needed. For details, please refer to Custom Video Capture:

  • camera: Configuration for camera and microphone capture streams.

  • screen: Configuration for screen capture streams.

  • custom: Configuration for third-party stream capture.

Start Publishing Stream

Call the startPublishingStream interface, pass in the stream ID parameter "streamID" and the stream object "localStream" obtained from creating the stream, and send the local audio/video stream to remote users.

Warning
  • The value of the "streamID" parameter is customizable and must be globally unique within the entire AppID.
  • If you need to publish multiple streams, call the startPublishingStream interface multiple times, ensuring that the "streamID" of each stream is different.
// localStream is the MediaStream object obtained by creating the stream
this.zg.startPublishingStream(streamID, localStream)

Listen to Event Callbacks After Publishing Stream

According to actual application needs, listen to event notifications of interest after publishing streams, such as publishing status updates, publishing quality, etc.

  • publisherStateUpdate: Publishing status update callback. After the publishing interface is called successfully, when the publishing status changes (such as network interruption causing publishing exceptions, etc.), the SDK will notify through this callback while retrying publishing.
  • publishQualityUpdate: Publishing quality callback. After the publishing interface is called successfully, audio/video stream quality data (such as resolution, frame rate, bitrate, etc.) is periodically called back.
// Register the publisherStateUpdate publishing status update event callback.
this.zg.on('publisherStateUpdate',({streamID, state}) => {
    // streamID is the stream ID of the published stream, state is the publishing status. You can perform some logical processing based on these statuses.
})
// Register the publishQualityUpdate publishing quality update event callback.
this.zg.on('publishQualityUpdate', (streamID, stats) => {
    // The stats object can obtain stream quality related information such as resolution, frame rate, bitrate, etc. for data display.
})

Play Stream

Start Playing Stream

Call the startPlayingStream interface, and based on the passed stream ID parameter "streamID", play the audio/video footage that has been published to the ZEGO server by remote users.

Note

The "streamID" published by remote users can be obtained from the roomStreamUpdate callback.

HTML creates a container <div> for the media stream player component.

<div id="remote-video" style="width: 320px;height: 240px;"></div>

After playing the remote stream, render it to the tag.

this.remoteStream = await this.zg.startPlayingStream(streamID,options);

// Create a media stream player component
const remoteView = this.zg.createRemoteStreamView(this.remoteStream);
remoteView.play("remote-video", {enableAutoplayDialog:true});
Warning

"streamID" must be globally unique within the entire AppID.

Listen to Event Callbacks After Playing Stream

According to actual application needs, listen to event notifications of interest after playing streams, such as playing status changes, playing quality, etc.

  • playerStateUpdate: Playing status update callback. After the playing interface is called successfully, when the playing status changes (such as network interruption causing publishing exceptions, etc.), the SDK will notify through this callback while retrying publishing.
  • playQualityUpdate: Playing quality callback. After the playing interface is called successfully, audio/video stream quality data (such as resolution, frame rate, bitrate, etc.) is periodically called back.
// Register the playerStateUpdate playing status update event callback.
this.zg.on('playerStateUpdate',({streamID, state}) => {
    // streamID is the stream ID of the played stream, state is the playing status. You can perform some logical processing based on these statuses.
})
// Register the playQualityUpdate playing quality update event callback.
this.zg.on('playQualityUpdate', (streamID, stats) => {
    // The stats object can obtain stream quality related information such as resolution, frame rate, bitrate, etc. for data display.
})

Experience Video Call

Run the project on a real device. After running successfully, you can see the local video footage.

To facilitate the experience, ZEGO provides a Web platform for debugging. On this page, enter the same AppID and RoomID, enter different UserIDs and corresponding Token, and you can join the same room to communicate with real devices. When the Video Call starts successfully, you can hear remote audio and see remote video footage.

Stop Publishing and Playing Streams

Stop Publishing Stream

Call the stopPublishingStream interface to stop sending local audio/video streams to remote users.

this.zg.stopPublishingStream(streamID)

Destroy Stream

Call the destroyStream interface to destroy the created stream data. After destroying the stream, developers need to destroy the video themselves (stop capturing).

// localStream is the MediaStream object obtained by calling the createZegoStream interface
this.zg.destroyStream(localStream)

Stop Playing Stream

Call the stopPlayingStream interface to stop playing remote published audio/video streams.

this.zg.stopPlayingStream(streamID)

Logout Room

Call the logoutRoom interface to log out of the room.

this.zg.logoutRoom(roomID)

Previous

Implementing Video Call with Vue (Web)

Next

Implementing Video Call with React (Web)