Documentation
ExpressVideoSDK Video Call
Documentation
Demo APP
SDK Center
API Center
FAQ
Code Market
Console
Sign Up
Log In
中文站 English
  • Documentation
  • Video Call
  • Develop your app
  • Implement a basic video call

Implement a basic video call

Last updated:2024-09-10 11:57

Introduction

This guide describes how to implement basic audio and video functions with the ZEGO Express SDK.

Basic concepts:

  • ZEGO Express SDK: The real-time audio and video SDK developed by ZEGOCLOUD to help you quickly build high-quality, low-latency, and smooth real-time audio and video communications into your apps across different platforms, with support for massive concurrency.

  • Stream publishing: The process of the client app capturing and transmitting audio and video streams to the ZEGOCLOUD Real-Time Audio and Video Cloud.

  • Stream playing: The process of the client app receiving and playing audio and video streams from the ZEGOCLOUD Real-Time Audio and Video Cloud.

  • Room: The service for organizing groups of users, allowing users in the same room to send and receive real-time audio, video, and messages to each other.

    1. Logging in to a room is required to perform stream publishing and playing.
    2. Users can only receive notifications about changes in the room they are in (such as new users joining the room, existing users leaving the room, new audio and video streams being published, etc.).

For more basic concepts, refer to the Glossary.

Prerequisites

Before you begin, make sure you complete the following steps:

  • Create a project in ZEGOCLOUD Console, and get the AppID and AppSign of your project.
  • The ZEGO Express SDK has been integrated into the project. For details, see How to view project information.

If the version of the ZEGO Express SDK you are using is under 2.17.0, to get the AppSign, contact the ZEGOCLOUD Technical Support. To upgrade the authentication mode from using the AppSign to Token, see Guide for upgrading the authentication mode from using the AppSign to Token.

Sample code

The following is sample code for a basic video call and can be used for reference during development.

Code for implementing a video call
//
//  ViewController.m
//  ZegoExpressExample
//
//  Copyright © 2022 Zego. All rights reserved.
//

#import "ViewController.h"
#import <ZegoExpressEngine/ZegoExpressEngine.h>

@interface ViewController ()<ZegoEventHandler>
// View for playing the audio and video streams of other users.
@property (strong, nonatomic) UIView *remoteUserView;
// Button for starting a video call.
@property (strong, nonatomic) UIButton *startVideoTalkButton;
// Button for stopping a video call.
@property (strong, nonatomic) UIButton *stopVideoTalkButton;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
}

- (void)setupUI {
    self.remoteUserView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 180, 250)];
    self.remoteUserView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:self.remoteUserView];

    self.startVideoTalkButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.view addSubview:self.startVideoTalkButton];
    self.startVideoTalkButton.frame = CGRectMake(100, self.view.bounds.size.height - 280, 150, 50);
    [self.startVideoTalkButton.titleLabel setFont:[UIFont systemFontOfSize:32]];
    [self.startVideoTalkButton setTitle:@"Start" forState:UIControlStateNormal];
    [self.startVideoTalkButton addTarget:self action:@selector(startVideoTalk:) forControlEvents:UIControlEventTouchUpInside];

    self.stopVideoTalkButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.view addSubview:self.stopVideoTalkButton];
    self.stopVideoTalkButton.frame = CGRectMake(100, self.view.bounds.size.height - 200, 150, 50);
    [self.stopVideoTalkButton.titleLabel setFont:[UIFont systemFontOfSize:32]];
    [self.stopVideoTalkButton setTitle:@"Stop" forState:UIControlStateNormal];
    [self.stopVideoTalkButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [self.stopVideoTalkButton addTarget:self action:@selector(stopVideoTalk:) forControlEvents:UIControlEventTouchUpInside];
}

- (void)startVideoTalk:(UIButton *)button {
    [self createEngine];
    [self loginRoom];
    [self startPublish];
}

- (void)stopVideoTalk:(UIButton *)button {
    [[ZegoExpressEngine sharedEngine] logoutRoom];
    [ZegoExpressEngine destroyEngine:^{

    }];
}

- (void)createEngine {
    ZegoEngineProfile *profile = [[ZegoEngineProfile alloc] init];
    // Register with the official website and obtain the data in the format similar to 1234567890.
    profile.appID = <#appID#>;
    // Register with the official website and obtain a string of 64 characters in the format similar to @"0123456789012345678901234567890123456789012345678901234567890123".
    profile.appSign = @"<#appSign#>"; 
    // General scenario. Select a scenario based on your service requirements.
    profile.scenario = ZegoScenarioDefault;
    // Create an engine and set `eventHandler` to `self`. If callback registration is not needed, `eventHandler` can be set to `nil`, and you can call the `-setEventHandler:` method to set the callback later on.
    [ZegoExpressEngine createEngineWithProfile:profile eventHandler:self];
}

- (void)loginRoom {
    // The value of `roomID` is generated locally and must be globally unique. Users must log in to the same room to call each other.
    NSString *roomID = @"room1";

    // Create a user object. The `ZegoUser` constructor `userWithUserID` will set `userName` to the value of `userID`. The `userID` and `userName` parameters cannot be set to `nil`. Otherwise, logging in to a room will fail.
    // The value of `userID` is generated locally and must be globally unique.
    ZegoUser *user = [ZegoUser userWithUserID:@"user1"];

    // The `onRoomUserUpdate` callback can be received only when `ZegoRoomConfig` in which the `isUserStatusNotify` parameter is set to `true` is passed.
    ZegoRoomConfig *roomConfig = [[ZegoRoomConfig alloc] init];
    // If you use the AppSign for authentication, you do not need to set the `token` parameter. If you want to use the Token for authentication, which is securer, see [Guide for upgrading the authentication mode from using the AppSign to Token](https://docs.zegocloud.com/faq/token_upgrade).

    // roomConfig.token = @"<#token#>";

    roomConfig.isUserStatusNotify = YES;
    // Log in to a room.
    [[ZegoExpressEngine sharedEngine] loginRoom:roomID user:user config:roomConfig callback:^(int errorCode, NSDictionary * _Nullable extendedData) {
        // (Optional callback) Room login result. This callback is sufficient if you only need to check the login result.
        if (errorCode == 0) {
            NSLog(@"Room login successful.");
        } else {
            // Login failed. For details, see [Error codes\|_blank](/404).
            NSLog(@"Room login failed.");
        }
    }];
}

- (void)startPublish {
    // Set the local preview view and start the preview. The default view mode of the SDK is used and the entire view is filled through proportional scaling.
    [[ZegoExpressEngine sharedEngine] startPreview:[ZegoCanvas canvasWithView:self.view]];

    // After calling the `loginRoom` method, call this method to publish streams.
    // Ensure that the value of `streamID` is globally unique under the same AppID. If different streams are published with the same `streamID`, the ones that are published after the first one will fail.
    [[ZegoExpressEngine sharedEngine] startPublishingStream:@"stream1"];
}

// After the `loginRoom` method is called, you can use the `onRoomStateChanged` callback to listen for the room connection status in real time.
// For details, see https://docs.zegocloud.com/article/13398.
-(void)onRoomStateChanged:(ZegoRoomStateChangedReason)reason errorCode:(int)errorCode extendedData:(NSDictionary *)extendedData roomID:(NSString *)roomID {
    if(reason == ZegoRoomStateChangedReasonLogining) {
        // Logging in to a room. When `loginRoom` is called to log in to a room or `switchRoom` is called to switch to another room, the room enters this status, indicating that it is requesting a connection to the server. On the app UI, the status of logging in to the room is displayed.
    } else if(reason == ZegoRoomStateChangedReasonLogined) {
        // Logging in to a room succeeds. When a user successfully logs in to a room or switches the room, the room enters this status. In this case, the user can receive notifications of addition or deletion of other users and their streams in the room.
        // Only after a user successfully logs in to a room or switches the room, `startPublishingStream` and `startPlayingStream` can be called to publish and play streams properly.
    } else if(reason == ZegoRoomStateChangedReasonLoginFailed) {
        // Logging in to a room fails. When a user fails to log in to a room or switch the room due to a reason such as incorrect AppID or Token, the room enters this status.
    } else if(reason == ZegoRoomStateChangedReasonReconnecting) {
        // The room connection is temporarily interrupted. The SDK will retry internally if the interruption is caused by poor network quality.
    } else if(reason == ZegoRoomStateChangedReasonReconnected) {
        // Reconnecting a room succeeds. The SDK will retry internally if the interruption is caused by poor network quality. If the reconnection is successful, the room enters this status.
    } else if(reason == ZegoRoomStateChangedReasonReconnectFailed) {
        // Reconnecting a room fails. The SDK will retry internally if the interruption is caused by poor network quality. If the reconnection fails, the room enters this status.
    } else if(reason == ZegoRoomStateChangedReasonKickOut) {
        // The server forces a user to log out of a room. If a user who has logged in to room A tries to log in to room B, the server forces the user to log out of room A and room A enters this status.
    } else if(reason == ZegoRoomStateChangedReasonLogout) {
        // Logging out of a room succeeds. This is the default status of a room before login. If a user successfully logs out of a room by calling `logoutRoom` or `switchRoom`, the room enters this status.
    } else if(reason == ZegoRoomStateChangedReasonLogoutFailed) {
        // Logging out of a room fails. If a user fails to log out of a room by calling `logoutRoom` or `switchRoom`, the room enters this status.
    }
}

// When another user in the same room publishes or stops publishing streams, you will receive a notification of stream increase or decrease of the user.
- (void)onRoomStreamUpdate:(ZegoUpdateType)updateType streamList:(NSArray<ZegoStream *> *)streamList extendedData:(NSDictionary *)extendedData roomID:(NSString *)roomID {
    // When `updateType` is set to `ZegoUpdateTypeAdd`, an audio and video stream is added, and you can call the `startPlayingStream` method to play the stream.
    if (updateType == ZegoUpdateTypeAdd) {
        // Start to play streams. Set the view for rendering the remote streams. The default view mode of the SDK is used and the entire view is filled through proportional scaling.
        // In the following code, the value of `remoteUserView` is the same as that of `View` of the UI. For conciseness of the sample code, only the first stream in the list of newly added audio and video streams is played here. In a real service, it is recommended that you traverse the stream list to play each stream.
        NSString *streamID = streamList[0].streamID;
        [[ZegoExpressEngine sharedEngine] startPlayingStream:streamID canvas:[ZegoCanvas canvasWithView:self.remoteUserView]];
    }
}

// You will receive this callback when another user logs in to or out of the room. If the value of `ZegoUpdateType` in the callback is `ZegoUpdateTypeAdd`, a user has logged in to the room. If the value of `ZegoUpdateType` in the callback is `ZegoUpdateTypeDelete`, a user has logged out of the room.
// This callback can be received only when `ZegoRoomConfig` in which the `isUserStatusNotify` parameter is set to `YES` is passed in the `loginRoom` method.
// The `onRoomUserUpdate` callback may be invalid for rooms with more than 500 users. If such rooms need to be supported in your service, contact ZEGOCLOUD technical support.
- (void)onRoomUserUpdate:(ZegoUpdateType)updateType userList:(NSArray<ZegoUser *> *)userList roomID:(NSString *)roomID {
    if (updateType == ZegoUpdateTypeAdd) {
        for (ZegoUser *user in userList) {
            NSLog(@"User %@ logged in to room %@.", user.userName, roomID);
        }
    } else if (updateType == ZegoUpdateTypeDelete) {
        for (ZegoUser *user in userList) {
            NSLog(@"User %@ logged out of room %@.", user.userName, roomID);
        }
    }
}

// Status notification of audio and video stream publishing.
// This callback is received when the status of audio and video stream publishing of a user changes. If an exception occurs during stream publishing due to a network interruption, the SDK retries to publish the streams and triggers this status change notification.
- (void)onPublisherStateUpdate:(ZegoPublisherState)state errorCode:(int)errorCode extendedData:(NSDictionary *)extendedData streamID:(NSString *)streamID {
    if (errorCode != 0) {
        NSLog(@"Stream publishing exception. errorCode: %d", errorCode);
    } else {
        switch (state) {
            case ZegoPublisherStatePublishing:
                NSLog(@"Publishing streams.");
                break;
            case ZegoPublisherStatePublishRequesting:
                NSLog(@"Requesting stream publishing.");
                break;
            case ZegoPublisherStateNoPublish:
                NSLog(@"Streams not published.");
                break;
        }
    }
}

// Status notifications of audio and video stream playing.
// This callback is received when the status of audio and video stream playing of a user changes. If an exception occurs during stream playing due to a network interruption, the SDK automatically retries to play the streams.
- (void)onPlayerStateUpdate:(ZegoPlayerState)state errorCode:(int)errorCode extendedData:(NSDictionary *)extendedData streamID:(NSString *)streamID {
    if (errorCode != 0) {
        NSLog(@"Stream playing exception. streamID: %@, errorCode: %d", streamID, errorCode);
    } else {
        switch (state) {
            case ZegoPlayerStatePlaying:
                NSLog(@"Playing streams.");
                break;
            case ZegoPlayerStatePlayRequesting:
                NSLog(@"Requesting stream playing.");
                break;
            case ZegoPlayerStateNoPlay:
                NSLog(@"Streams not played.");
                break;
        }
    }
}

// You can use the `onNetworkQuality` callback to listen for the upstream and downstream network quality of users (including yourself) in a room. This callback will be received every two seconds. For details about network quality levels, see `ZegoStreamQualityLevel`.
- (void)onNetworkQuality:(NSString *)userID upstreamQuality:(ZegoStreamQualityLevel)upstreamQuality downstreamQuality:(ZegoStreamQualityLevel)downstreamQuality {
    if (userID == nil) {
        // Network quality of the local user.
//        NSLog(@"My upstream network quality is %lu.", (unsigned long)upstreamQuality);
//        NSLog(@"My downstream network quality is %lu.", (unsigned long)downstreamQuality);
    } else {
        // Network quality of other users in a room.
//        NSLog(@"The upstream network quality of user %@ is %lu.", userID, (unsigned long)upstreamQuality);
//        NSLog(@"The downstream network quality of user %@ is %lu.", userID, (unsigned long)downstreamQuality);
    }

    /*
     ZegoStreamQualityLevelExcellent: The network quality is excellent.
     ZegoStreamQualityLevelGood: The network quality is good.
     ZegoStreamQualityLevelMedium: The network quality is medium.
     ZegoStreamQualityLevelBad: The network quality is bad.
     ZegoStreamQualityLevelDie: The network is abnormal.
     ZegoStreamQualityLevelUnknown: The network quality is unknown.
     */
}


@end

Implementation process

The following diagram shows the basic process of User A playing a stream published by User B:

/Pics/in_app_chat/17395_2.png

Initialize the SDK

Create the UI

Create a UI for video calls for your project based on your scenario requirements. We recommend you add the following UI elements to your project:

  • A view for local preview
  • A view for remote video
  • A Stop button
layout

Import the header file

import im.zego.zegoexpress.ZegoExpressEngine;
import im.zego.zegoexpress.callback.IZegoDestroyCompletionCallback;
import im.zego.zegoexpress.callback.IZegoEventHandler;
import im.zego.zegoexpress.constants.ZegoPlayerState;
import im.zego.zegoexpress.constants.ZegoPublisherState;
import im.zego.zegoexpress.constants.ZegoRoomStateChangedReason;
import im.zego.zegoexpress.constants.ZegoScenario;
import im.zego.zegoexpress.constants.ZegoStreamQualityLevel;
import im.zego.zegoexpress.constants.ZegoUpdateType;
import im.zego.zegoexpress.entity.ZegoCanvas;
import im.zego.zegoexpress.entity.ZegoEngineProfile;
import im.zego.zegoexpress.entity.ZegoRoomConfig;
import im.zego.zegoexpress.entity.ZegoStream;
import im.zego.zegoexpress.entity.ZegoUser;
ZegoExpressEngine engine;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Request necessary camera and audio recording permissions before the call
    requestPermission();

    // Start call button
    findViewById(R.id.startButton).setOnClickListener(new View.OnClickListener() {
        // Click to start the call
        @Override
        public void onClick(View view) {
            // Create an instance of the Express SDK
            createEngine();
            // Set up event handlers
            setEventHandler();
            // Log in to the room
            loginRoom();
            // Start preview and publishing
            startPublish();
        }
    });

    // Stop call button
    findViewById(R.id.stopButton).setOnClickListener(new View.OnClickListener() {
        // Click to stop the call
        @Override
        public void onClick(View view) {
            engine.logoutRoom();
            ZegoExpressEngine.destroyEngine(new IZegoDestroyCompletionCallback() {
                @Override
                public void onDestroyCompletion() {
                    // Successfully destroyed
                }
            });

        }
    });
}

// Request camera and audio recording permissions
private void requestPermission() {
    String[] permissionNeeded = {
            "android.permission.CAMERA",
            "android.permission.RECORD_AUDIO"};
    if (ContextCompat.checkSelfPermission(getApplicationContext(), "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ||
            ContextCompat.checkSelfPermission(getApplicationContext(), "android.permission.RECORD_AUDIO") != PackageManager.PERMISSION_GRANTED) {
        // 101 is the requestCode, it can be any number greater than 0, and will be passed to the permission request result callback onRequestPermissionsResult
        requestPermissions(permissionNeeded, 101);
    }
}

Create a ZegoExpressEngine instance

Call the createEngine method and set the appID and appSign parameters to the applied AppID and AppSign, respectively.

Use the scenario parameter to pass a room scenario matching the audio and video service of your app. For details, see Config your video based on scenes.

Register a callback. You can set eventHandler to an implemented object (for example, self) that conforms to the IZegoEventHandler protocol.

The SDK also supports Token-based authentication. If you want to upgrade the authentication mode, see Guide for upgrading the authentication mode from using the AppSign to Token.

// Create a ZegoExpress instance and listen for common events
void createEngine() {
    ZegoEngineProfile profile = new ZegoEngineProfile();
    profile.appID = appID;  // Please obtain from the official website, format: 1234567890L
    profile.appSign = appSign; // Please obtain from the official website, format: @"0123456789012345678901234567890123456789012345678901234567890123" (64 characters in total)
    profile.scenario = ZegoScenario.BROADCAST;  // Specify the use of the live broadcast scenario (Please fill in the appropriate scenario according to your actual situation)
    profile.application = getApplication();
    engine = ZegoExpressEngine.createEngine(profile, null);
}

Log in to a room

Call the loginRoom method to log in to a room. If the room does not exist, calling this method will create and log in to the room. The values of the roomID and user parameters are generated locally, but the following conditions must be met:

  • The value of roomID must be globally unique under the same AppID.
  • The value of userID must be globally unique under the same AppID. You are advised to associate userID with the account system of your service.
// Login to the room
void loginRoom() {
    // The constructor of ZegoUser, public ZegoUser(String userID), sets "userName" to be the same as the parameter "userID". Both "userID" and "userName" cannot be "null", otherwise it will cause login failure.
    ZegoUser user = new ZegoUser("user2");

    ZegoRoomConfig roomConfig = new ZegoRoomConfig();
    // If you use appsign for authentication, the token parameter does not need to be filled in; if you need to use a more secure authentication method: token authentication, please refer to [How to Upgrade from AppSign Authentication to Token Authentication](https://doc-en.zego.im/en/faq/token_upgrade?product=ExpressVideo&platform=all)
    // roomConfig.token = ;
    // Only ZegoRoomConfig with the parameter "isUserStatusNotify" set to "true" can receive the onRoomUserUpdate callback.
    roomConfig.isUserStatusNotify = true;

    // The roomID is generated locally and needs to be globally unique. Different users need to log in to the same room to communicate.
    String roomID = "room1";

    // Login to the room
    engine.loginRoom(roomID, user, roomConfig, (int error, JSONObject extendedData)->{
        // Login result, if you only care about the login result, pay attention to this callback
        if (error == 0) {
            // Login successful
            Toast.makeText(this, "Login successful", Toast.LENGTH_LONG).show();
        } else {
            // Login failed, please refer to the errorCode description: https://doc-en.zego.im/en/article/4378
            Toast.makeText(this, "Login failed, please refer to the errorCode description: https://doc-en.zego.im/en/article/4378", Toast.LENGTH_LONG).show();
        }
    });
}

Listen for the login status (room connection status)

After the loginRoom method is called, you can use the onRoomStateChanged callback to listen for the room connection status in real time.

Start the local video preview and publish streams to ZEGOCLOUD audio and video cloud

Start the local video preview

To view the local videos, call the startPreview method to set the preview view and start the local preview.

Publish streams to ZEGOCLOUD audio and video cloud

After the loginRoom method is called, you can call the startPublishingStream method and pass streamID to publish the audio and video streams to ZEGOCLOUD audio and video cloud. You can use the onPublisherStateUpdate callback to listen for the publishing status.

The value of streamID is generated locally, but the following condition must be met:

The value of streamID must be globally unique under the same AppID. If different streams are published with the same streamID, the ones that are published after the first one will fail.

// Preview and start streaming
void startPublish() {
    // Set the local preview view and start previewing, using the SDK's default mode, which scales and fills the entire view
    ZegoCanvas previewCanvas = new ZegoCanvas(findViewById(R.id.preview));
    engine.startPreview(previewCanvas);

    // Start streaming
    // Call loginRoom before calling this method to start streaming
    // Within the same AppID, developers need to ensure that the "streamID" is globally unique. If different users push a stream with the same "streamID", the user who pushes the stream later will fail to start streaming.
    engine.startPublishingStream("stream2");
}

@@@Warning_How_to_switch_devices@@@

Play streams

During a video call, audio and video streams of other users need to be played.

When another user in the same room publishes audio and video streams to ZEGOCLOUD audio and video cloud, you will receive a notification of new audio and video streams through the onRoomStreamUpdate callback and can obtain streamID of a certain stream through ZegoStream.

You can call startPlayingStream in the callback and pass the value of streamID to play the audio and video stream of the user. You can use the onPlayerStateUpdate callback to listen for the playing status.

// Set event handler
void setEventHandler() {
    engine.setEventHandler(new IZegoEventHandler() {
        @Override
        // We will receive notifications of audio and video stream changes from other users in the room here
        public void onRoomStreamUpdate(String roomID, ZegoUpdateType updateType, ArrayList<ZegoStream> streamList, JSONObject extendedData) {
            super.onRoomStreamUpdate(roomID, updateType, streamList, extendedData);
            // When updateType is ZegoUpdateType.ADD, it means that there is a new audio and video stream added. We can call the startPlayingStream interface to pull and play the audio and video stream
            if (updateType == ZegoUpdateType.ADD) {
                // Start pulling the stream, set the remote stream rendering view, and use the SDK's default mode to scale and fill the entire view
                ZegoStream stream = streamList.get(0);
                String playStreamID = stream.streamID;
                // The remoteUserView here is the TextureView on the UI. In order to make the example code more concise, we only pull the first stream in the list of newly added audio and video streams. In actual business scenarios, it is recommended for developers to loop through the streamList and pull each audio and video stream
                ZegoCanvas playCanvas = new ZegoCanvas(findViewById(R.id.remoteUserView));
                engine.startPlayingStream(playStreamID, playCanvas);
            }
        }
    });
}

Common functions

Common notification callbacks

@@@Express_Java_Common_Callback@@@

Stop audio and video call

Stop pushing and pulling audio and video streams

1. Stop pushing stream and stop preview

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

// Stop pushing stream
engine.stopPublishingStream();

If local preview is enabled, call the stopPreview interface to stop previewing.

// Stop local preview
engine.stopPreview();

Stop pulling stream

Call the stopPlayingStream interface to stop pulling the audio and video streams pushed by remote users.

If the developer receives a notification of "decrease" in audio and video streams through the onRoomStreamUpdate callback, please promptly call the stopPlayingStream interface to stop pulling the stream to avoid pulling an empty stream and incurring additional costs. Alternatively, developers can choose an appropriate time to proactively call the stopPlayingStream interface to stop pulling the stream based on their business needs.

// Stop pulling stream
engine.stopPlayingStream("stream1");

Logout room

Call the logoutRoom interface to logout the room.

// Logout room
engine.logoutRoom();

Destroy engine

If the user no longer needs the audio and video functions, call the destroyEngine interface to destroy the engine and release resources such as microphone, camera, memory, and CPU.

  • If you need to listen for callbacks to ensure that the device hardware resources are released, you can pass in "callback" when destroying the engine. This callback is only used to send notifications, and developers cannot release resources related to the engine in the callback.

  • If you don't need to listen for callbacks, you can pass in "null".

ZegoExpressEngine.destroyEngine(null);

Debugging video call function

We recommend you run your project on a real device. If your app runs successfully, you should hear the sound and see the video captured locally from your device.

To test out the real-time audio and video features, visit the ZEGO Express Web Demo, and enter the same AppID, Server and RoomID to join the same room. If it runs successfully, you should be able to view the video from both the local side and the remote side, and hear the sound from both sides as well.

In audio-only scenarios, no video will be captured and displayed.

Video call API invocation sequence

/Pics/Video_call/17933.png

FAQ

1. Can I kill the process directly after calling logoutRoom to logout the room?

If you kill the process directly after calling logoutRoom , there is a certain probability that the logoutRoom signal will not be sent. In this case, the ZEGO server can only wait for the heartbeat timeout to consider that the user has exited the room. To ensure that the logoutRoom signal is sent, it is recommended to call destroyEngine and kill the process after receiving the callback.

Related documents

  • Error codes
  • How can I obtain the SDK logs and stack traces?
  • Does ZEGO SDK support a fast reconnection for temporary disconnection?
  • How can I listen for the event callbacks related to room users' login/logout in live streaming?
  • Why can't I turn on the camera?
Page Directory
  • Free trial
  • 提交工单
    咨询集成、功能及报价等问题
    电话咨询
    400 1006 604
    Get Consulting
    Scan Wechat QR code