logo
On this page

Implementing Voice Call


Introduction

This document introduces how to quickly implement a simple real-time audio and video call.

Explanation of related concepts:

  • ZEGO Express SDK: A real-time audio and video SDK provided by ZEGO, offering developers convenient access, high definition and fluency, multi-platform interoperability, low latency, and high concurrency audio and video services.
  • Stream: A set of audio and video data packets encapsulated in a specified encoding format and continuously being sent. A user can publish multiple streams simultaneously (for example, one for camera data and 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 and video data streams to ZEGOCLOUD.
  • Play stream: The process of pulling and playing existing audio and video data streams from ZEGOCLOUD.
  • Room: An audio and 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.
    1. Users need to log in to a room first before they can publish or play streams.
    2. Users can only receive related messages in the room they are in (user entry/exit, audio and video stream changes, etc.).
    3. Each room is identified by a unique roomID within an AppID. All users who log in to the room using the same roomID belong to the same room.

Prerequisites

Before implementing basic audio call functionality, please ensure:

  • The ZEGO Express SDK has been integrated in your project to implement basic real-time audio and video functions. For details, please refer to Quick Start - Integrate.
  • A project has been created in the ZEGOCLOUD Console, and a valid AppID and AppSign have been obtained.
Warning

The SDK also supports Token authentication. If you have higher security requirements for your project, it is recommended to upgrade the authentication method. For details, please refer to How to upgrade Express from AppSign authentication to Token authentication?.

Usage Steps

Taking User A playing User B's stream as an example, the process is as follows:

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

Create Engine

1. Import Header File

Introduce the ZegoExpressEngine header file in the project.

#include "ZegoExpressSDK.h"
using namespace ZEGO::EXPRESS;

2. Create Engine

Call the createEngine interface, and pass the obtained AppID to the parameter "appID".

Select an appropriate scenario based on your App's actual audio and video business. Please refer to the Scenario-based Audio and Video Configuration document, and pass the selected scenario enumeration to the parameter "scenario".

ZegoEngineProfile profile;
// AppID and AppSign are assigned by ZEGO to each App; for security reasons, it is recommended to store the AppSign in the App's business backend and obtain it from the backend when needed
profile.appID = appID; // Please obtain it through official website registration, format is 123456789
profile.appSign = appSign; // Please obtain it through official website registration, format is "0123456789012345678901234567890123", 64 characters
profile.scenario = ZegoScenario::ZEGO_SCENARIO_BROADCAST;
// Create engine instance
auto engine = ZegoExpressSDK::createEngine(profile, nullptr);

3. Disable Camera

Warning

Express Linux SDK does not provide an audio-only package with the video module removed. Therefore, the Linux "Real-time Voice" SDK is actually the "Real-time Audio and Video" SDK.

To implement an audio-only scenario, please call enableCamera after creating the engine to disable the camera, to avoid starting the engine's video module. After the camera is disabled, camera permissions will no longer be required, and video streams will not be published.

engine->enableCamera(false); // Disable camera

For more information, please refer to the document Differences between Real-time Audio and Video SDK and Real-time Voice SDK.

If you have high requirements for the Express Linux SDK package size, you can contact Technical Support for custom package reduction. For SDK package size data, please refer to the Overview document.

4. Set Event Handlers

You can instantiate a class that implements the IZegoEventHandler method or pass it to the setEventHandler method to register callbacks.

Warning

It is recommended to register callbacks immediately after creating the engine or immediately after creating the engine to avoid missing event notifications.

Log In to Room

1. Log In

Create a ZegoUser user object by passing in the user ID parameter "userID" and "userName", then call the loginRoom, and pass in the room ID parameter "roomID" and user parameter "user", to log in to the room. If the room does not exist, calling this interface will create and log in to this room.

  • Within the same AppID, ensure that the "roomID" information is globally unique.
  • Within the same AppID, ensure that the "userID" is globally unique. It is recommended that developers set it to a meaningful value and can associate the "userID" with their own business account system.
  • The "userID" cannot be empty, otherwise it will cause room login failure.
// Create user object
ZegoUser user("user1", "user1");
// Only by passing in a ZegoRoomConfig with the "isUserStatusNotify" parameter value set to "true" can you receive the onRoomUserUpdate callback.
ZegoRoomConfig roomConfig;
// If you use the appsign method for authentication, the token parameter does not need to be filled; if you need to use a more secure authentication method: token authentication.
// roomConfig.token = "xxxx";
roomConfig.isUserStatusNotify = true;
// Log in to room
engine->loginRoom(roomID, user, roomConfig, [=](){
    // (Optional callback) Log in to room result, if you only focus on the login result, pay attention to this callback
});

2. Listen for Event Callbacks After Logging In to Room

According to actual needs, listen for 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, 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 removed from the room, the SDK will notify through this callback.

    Only when calling the loginRoom interface to log in to the room with the ZegoRoomConfig configuration, and the "isUserStatusNotify" parameter value is "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 remove audio and video streams, the SDK will notify through this callback.

Warning
  • Only when calling the loginRoom interface to log in to the room with the ZegoRoomConfig configuration, and the "isUserStatusNotify" parameter value is "true", can users receive the onRoomUserUpdate callback.

  • Normally, if a user wants to play audio published by other users, they can call the startPlayingStream interface in the stream status update (addition) callback to pull the remote published audio and 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)
    {
        // Log in 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 (startPublishingStream) or playing (startPlayingStream) normally send and receive audio and video
        // Publish the local audio and video stream to the ZEGO audio and video cloud
    }
    else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGIN_FAILED)
    {
        // Log in failed
    }
    else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_RECONNECTING)
    {
        // Reconnecting
    }
    else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_RECONNECTED)
    {
        // Reconnection 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.
    }
    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)
    {
        // Log out successful
    }
    else if(reason == ZEGO_ROOM_STATE_CHANGED_REASON_LOGOUT_FAILED)
    {
        // Log out failed
    }
};

// User status update callback
void onRoomUserUpdate(const std::string& roomID, ZegoUpdateType updateType, const std::vector<ZegoUser>& userList) override {
    // Implement event callback according to needs
};

// Stream status update callback
void onRoomStreamUpdate(const std::string& roomID, ZegoUpdateType updateType, const std::vector<ZegoStream>& streamInfoList, const std::string& extendedData) override {
    // Implement event callback according to needs
};

Publish Stream

1. Start Publishing Stream

Call the startPublishingStream interface, and pass in the stream ID parameter "streamID", to send the local audio and video stream to remote users.

Warning

Within the same AppID, ensure that the "streamID" is globally unique. If within the same AppID, different users each publish a stream with the same "streamID", it will cause the user who publishes later to fail to publish the stream.

In addition, it is recommended for developers to configure publishing parameters before starting publishing. If not configured, the SDK will use the default configuration. The SDK supports rich publishing parameter configuration, mainly including: video frame rate, bitrate, resolution, audio bitrate, etc.

// Start publishing stream
engine->startPublishingStream("stream1");

2. Listen for Event Callbacks After Publishing Stream

According to actual application needs, listen for event notifications you care about after publishing the stream, such as publishing status updates, publishing quality, etc.

  • onPublisherStateUpdate: 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 to publish.
  • onPublisherQualityUpdate: Publishing quality callback. After the publishing interface is called successfully, it periodically calls back with audio and video stream quality data (such as resolution, frame rate, bitrate, etc.).

Event callbacks are all ZegoExpressEngine delegates. Developers can directly assign their implemented callback handling functions to the corresponding delegates of ZegoExpressEngine, and then receive callbacks and process them.

// Publishing status update callback
void onPublisherStateUpdate(const std::string& streamID, ZegoPublisherState state, int errorCode, const std::string& extendedData) {
    printf("onPublisherStateUpdate: streamID=%s", streamID.c_str());
        // ...
}
Note

If you need to understand Express's microphone/audio/speaker related interfaces, please refer to FAQ - How to implement switching camera/video screen/microphone/audio/speaker?.

Play Stream

1. Start Playing Stream

Call the startPlayingStream interface, based on the passed stream ID parameter "streamID", to pull the remote published audio and video stream.

The "streamID" published by remote users can be obtained from the onRoomStreamUpdate callback of the ZegoEventHandler.

// Start playing stream
engine->startPlayingStream("123", nullptr);

2. Listen for Event Callbacks After Playing Stream

According to actual application needs, listen for event notifications you care about after playing the stream, such as playing status updates, playing quality, etc.

  • onPlayerStateUpdate: 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 to play.
  • onPlayerQualityUpdate: Playing quality callback. After playing is successful, it calls back every 3 seconds with the quality data of the pulled audio and video stream (such as resolution, frame rate, bitrate, RTT, packet loss rate, etc.), allowing real-time monitoring of the health status of the pulled stream.

Event callbacks are all ZegoExpressEngine delegates. Developers can directly assign their implemented callback handling functions to the corresponding delegates of ZegoExpressEngine, and then receive callbacks and process them.

// Playing status update callback
virtual void onPlayerStateUpdate(const std::string& streamID, ZegoPlayerState state, int errorCode, const std::string& extendedData) {
    printf("onPlayerStateUpdate: streamID=%s", streamID.c_str());
        // ...
}

Experience Real-time Audio and Video Functions

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 the corresponding Token, and you can join the same room to communicate with real devices. When the audio and video call starts successfully, you can hear the remote audio and see the remote video screen.

Stop Publishing and Playing Streams

1. Stop Publishing Stream

Call the stopPublishingStream interface to stop sending the local audio and video stream to remote users.

// Stop publishing stream
engine->stopPublishingStream();

2. Stop Playing Stream

Call the stopPlayingStream interface to stop pulling the remote published audio and video stream.

Warning

If the developer receives a "decrease" notification for audio and video streams through the onRoomStreamUpdate callback, please call the stopPlayingStream interface in time to stop playing streams, to avoid pulling empty streams and generating additional costs; or, developers can choose the appropriate timing according to their business needs and proactively call the stopPlayingStream interface to stop playing streams.

// Stop playing stream
engine->stopPlayingStream("123");

Log Out of Room

Call the logoutRoom interface to log out of the room.

// Log out of room
engine->logoutRoom("123666");

Destroy Engine

Call the destroyEngine interface to destroy the engine, used to release the resources used by the SDK.

// Destroy engine instance
ZegoExpressSDK::destroyEngine(engine);

Previous

Integrating SDK

Next

Scenario-based Audio and Video Configuration

On this page

Back to top