Implementing Video Call
Feature Overview
This article will introduce how to quickly implement a simple real-time audio/video call.
Explanation of related concepts:
- ZEGO Express SDK: Real-time audio/video SDK provided by ZEGO, which can provide developers with convenient access, HD and smooth, multi-platform interoperability, low latency, and high concurrency audio/video services.
- Stream: Refers to a group of audio/video data that is continuously being sent, encapsulated in a specified encoding format. A user can publish multiple streams simultaneously (for example, one for camera data, one for screen sharing data) and can also play multiple streams simultaneously. Each stream is identified by a stream ID (streamID).
- Publish stream: The process of pushing packaged audio/video data streams to ZEGO real-time audio/video cloud.
- Play stream: The process of pulling and playing existing audio/video data streams from ZEGO real-time audio/video cloud.
- Room: Is the audio/video space service provided by ZEGO, used to organize user groups. Users in the same room can send and receive real-time audio/video and messages to each other.
- Users need to login to a room first before they can publish and play streams.
- Users can only receive relevant messages in their own room (user entry/exit, audio/video stream changes, etc.).
- Each room is identified by a unique roomID within an AppID. All users who login to the room using the same roomID belong to the same room.
Prerequisites
Before implementing basic real-time audio/video functions, please ensure:
- ZEGO Express SDK has been integrated in the project and basic real-time audio/video functions have been implemented. For details, please refer to Quick Start - Integration.
- A project has been created in the ZEGOCLOUD Console and valid AppID and AppSign have been applied for.
The SDK also supports Token authentication. If you need to upgrade the authentication method, please refer to How to upgrade from AppSign authentication to Token authentication.
Usage Steps
The basic process for users to make video calls through ZEGO Express SDK is as follows:
Users A and B join the room. User B previews and pushes audio/video streams to ZEGO cloud service (publish stream). After user A receives the notification of user B's published audio/video streams, user A plays user B's audio/video streams in the notification (play stream).
The API call sequence of the entire publish/play stream process is shown in the following figure:
Create Engine
1. Create UI (optional)
Before starting, it is recommended that developers add the following UI elements to facilitate the implementation of basic real-time audio/video functions.
- Local preview window
- Remote video window
- End button

2. Include header files
Include ZegoExpressEngine header files in the project.
#include "ZegoExpressSDK.h"
using namespace ZEGO::EXPRESS;3. Create engine
Call the createEngine interface and pass the applied AppID and AppSign to the parameters "appID" and "appSign".
Select an appropriate scenario according to the actual audio/video business of the App. Please refer to the Scenario-based Audio/Video Configuration document and pass the selected scenario enumeration to the parameter "scenario".
The SDK also supports Token authentication. If you have higher security requirements for the project, it is recommended to upgrade the authentication method. Please refer to How to upgrade from AppSign authentication to Token authentication.
enableCamera(false) to turn off the camera to avoid starting video capture and publishing stream, which will generate additional video traffic.ZegoEngineProfile profile;
// AppID and AppSign are assigned to each App by ZEGO; for security reasons, it is recommended to store AppSign in the App's business backend and obtain it from the backend when needed
profile.appID = appID;
profile.appSign = appSign;
// Specify using live streaming scenario (please fill in the scenario suitable for your business according to the actual situation)
profile.scenario = ZegoScenario::ZEGO_SCENARIO_BROADCAST;
// Create engine instance
auto engine = ZegoExpressSDK::createEngine(profile, nullptr);4. Set callback
You can listen to and handle concerned event callbacks by instantiating a class that implements the IZegoEventHandler interface and implementing required callback methods. Then pass the instantiated object as the eventHandler parameter to createEngine or pass it to setEventHandler to register the callback.
It is recommended to register the callback when creating the engine or immediately after creating the engine to avoid delaying registration and missing event notifications.
Login Room
1. Login
After creating a ZegoUser user object by passing in the user ID parameters "userID" and "userName", call loginRoom and pass in the room ID parameter "roomID" and user parameter "user" to login to the room. If the room does not exist, calling this interface will create and login to this room.
- Within the same AppID, ensure that "roomID" is globally unique.
- Within the same AppID, ensure that "userID" is globally unique. It is recommended that developers set it to a meaningful value and associate "userID" with their own business account system.
- "userID" cannot be empty, otherwise the login to the room will fail.
// Create user object
ZegoUser user("user1", "user1");
// Only by passing in ZegoRoomConfig with the "isUserStatusNotify" parameter set to "true" can you receive the onRoomUserUpdate callback.
ZegoRoomConfig roomConfig;
// If you use appsign for authentication, you do not need to fill in the token parameter; if you need to use a more secure authentication method: token authentication.
// roomConfig.token = "xxxx";
roomConfig.isUserStatusNotify = true;
// Login room
engine->loginRoom(roomID, user, roomConfig, [=](){
// (Optional callback) Login room result, if you only care about the login result, just pay attention to this callback
});2. Listen to event callbacks after logging in to the room
According to actual needs, listen to the event notifications you care about after logging in to the room, such as room status updates, user status updates, stream status updates, etc.
-
onRoomStateChanged: Room status update callback. After logging in to the room, when the room connection status changes (such as room disconnection, login authentication failure, etc.), the SDK will notify through this callback.
-
onRoomUserUpdate: User status update callback. After logging in to the room, when users are added to or deleted from the room, the SDK will notify through this callback.
Only when calling the loginRoom interface to login to the room and passing in ZegoRoomConfig configuration, and the "isUserStatusNotify" parameter is set to "true", can users receive the onRoomUserUpdate callback.
-
onRoomStreamUpdate: Stream status update callback. After logging in to the room, when users in the room newly publish or delete audio/video streams, the SDK will notify through this callback.
- Only when calling the loginRoom interface to login to the room and passing in ZegoRoomConfig configuration, and the "isUserStatusNotify" parameter is set to "true", can users receive the onRoomUserUpdate callback.
- 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 (addition) to pull remote published audio/video streams.
- Please note, do not call any SDK interfaces in the SDK callback thread. You need to manually switch to another thread, otherwise a deadlock will occur.
// Room status update callback
void onRoomStateChanged(const std::string &roomID, ZegoRoomStateChangedReason reason, int errorCode, const std::string &extendedData) {
if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGINING)
{
// Logging in
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGINED)
{
// Login successful
// Please note, do not call any SDK interfaces in the SDK callback thread, you need to manually switch to another thread, otherwise a deadlock will occur
// Only when the room status is login successful or reconnection successful can publishing stream (startPublishingStream) and playing stream (startPlayingStream) normally send and receive audio/video
// Publish your audio/video stream to ZEGO audio/video cloud
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGIN_FAILED)
{
// Login failed
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_RECONNECTING)
{
// Reconnecting
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_RECONNECTED)
{
// Reconnection successful
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_RECONNECT_FAILED)
{
// Reconnection failed
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_KICK_OUT)
{
// Kicked out of the room
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGOUT)
{
// Logout successful
}
else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGOUT_FAILED)
{
// Logout failed
}
}
// User status update callback
void onRoomUserUpdate(const std::string& roomID, ZegoUpdateType updateType, const std::vector<ZegoUser>& userList) override {
// Implement event callback as needed
}
// Stream status update callback
void onRoomStreamUpdate(const std::string& roomID, ZegoUpdateType updateType, const std::vector<ZegoStream>& streamList, const std::string& extendedData) override {
// Implement event callback as needed
}Publish Stream
1. Start publishing stream
Call startPublishingStream and pass in the stream ID parameter "streamID" to send the local audio/video stream to remote users.
- Within the same AppID, ensure that "streamID" is globally unique. If within the same AppID, different users each publish a stream with the same "streamID", the user who publishes later will fail to publish.
- Before starting to publish stream, it is recommended that developers configure the publishing parameters first. If not configured, the SDK will use default configuration. The SDK supports rich publishing parameter configuration, mainly including: video frame rate, bitrate, resolution, audio bitrate, etc.
// Start publishing stream
engine->startPublishingStream("streamID");2. Listen to event callbacks after publishing stream
According to actual application needs, listen to the event notifications you care about after publishing stream, such as publishing status updates, etc.
onPublisherStateUpdate: Publishing status update callback. After successfully calling the publishing interface, when the publishing status changes (such as network interruption causing publishing abnormalities, etc.), the SDK will notify through this callback while retrying publishing.
// Publishing status update callback
virtual void onPublisherStateUpdate(const std::string& streamID, ZegoPublisherState state, int errorCode, const std::string& extendedData) {
// Implement event callback as needed
}Play Stream
1. Start playing stream
Call the startPlayingStream interface and pull the remote published audio/video stream according to the passed in stream ID parameter "streamID".
- The "streamID" published by remote users can be obtained from the onRoomStreamUpdate callback in IZegoEventHandler.
- The Linux SDK downloaded from the official website does not include internal video rendering functionality. Developers need to implement custom video rendering through the enableCustomVideoRender interface when playing streams. If you need to support internal rendering functionality, please contact ZEGO Technical Support.
// Start playing stream
engine->startPlayingStream("streamID", nullptr);2. Listen to event callbacks after playing stream
According to actual application needs, listen to the event notifications you care about after playing stream, such as playing status updates, etc.
onPlayerStateUpdate: Playing status update callback. After successfully calling the playing interface, when the playing status changes (such as network interruption causing publishing abnormalities, etc.), the SDK will notify through this callback while retrying playing.
// Playing status change callback
virtual void onPlayerStateUpdate(const std::string& streamID, ZegoPlayerState state, int errorCode, const std::string& extendedData) {
// Implement event callback as needed
}Test publishing and playing functions online
Run the project on a real device. After successful operation, you can see the local video screen.
For convenience, 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 audio/video call starts successfully, you can hear remote audio and see remote video screen.
Stop Publishing/Playing Stream
1. Stop publishing stream
Call stopPublishingStream to stop sending local audio/video streams to remote users.
// Stop publishing stream
engine->stopPublishingStream();2. Stop playing stream
Call stopPlayingStream to stop pulling remote published audio/video streams.
If developers receive a notification of "decrease" in audio/video streams through the onRoomStreamUpdate callback, please call the stopPlayingStream interface to stop playing streams in time to avoid pulling empty streams and generating additional costs; or, developers can choose an appropriate time according to their own business needs and actively call the stopPlayingStream interface to stop playing streams.
// Stop playing stream
engine->stopPlayingStream("streamID");Leave Room
Call the logoutRoom interface to leave the room.
// Leave room
engine->logoutRoom("roomID");Destroy Engine
Call the destroyEngine interface to destroy the engine, which is used to release resources used by the SDK.
-
If you need to listen to the callback to ensure that device hardware resources are released, you can pass in "callback" when destroying the engine. This callback is only used for sending notifications, and developers cannot release engine-related resources in the callback.
-
If you don't need to listen to the callback, you can pass in "nullptr".
// Destroy engine instance
ZegoExpressSDK::destroyEngine(engine, nullptr);