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.
For more basic concepts, refer to the Glossary.
Before you begin, make sure you complete the following steps:
If the version of the ZEGO Express SDK you are using is under 2.17.0, to get the AppSign, contact ZEGOCLOUD Technical Support. To upgrade the authentication mode from using the AppSign to Token, see Upgrade guide.
The following diagram shows the basic process of User A playing a stream published by User B.
The following diagram shows the API call sequence of the stream publishing and playing process:
The following sections explain each step of this process in more detail.
ZegoExpressEngine
instance1. Optional: Create the UI
Before creating a ZegoExpressEngine
instance, we recommend you add the following UI elements to implement basic real-time audio and video features:
2. Create a ZegoExpressEngine
instance
To create a singleton instance of the ZegoExpressEngine
class, call the createEngine
method with the AppID of your project.
// Define a ZegoExpressEngine object
ZegoExpressEngine engine;
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = appID; // AppID format:1234567890
profile.scenario = ZegoScenario.General; // General scenario
// Create a ZegoExpressEngine instance
engine = ZegoExpressEngine.CreateEngine(profile);
1. Log in
Before logging in to a room, you will need to generate a token first; Otherwise, the login will fail.
To generate a token, refer to the Use Tokens for authentication.
To log in to a room, call the loginRoom
method. If the roomID does not exist, a new room will be created and you will log in automatically when you call the loginRoom
method.
// create a user
ZegoUser user = new ZegoUser();
user.userId="xxx";
user.userName="xxxx";
// set the token
ZegoRoomConfig roomConfig = new ZegoRoomConfig();
// If you need to use a more secure authentication method, Token authentication, please refer to [Guide for upgrading the authentication mode from using the AppSign to Token](https://docs.zegocloud.com/faq/token_upgrade?product=ExpressVideo&platform=all).
// On the WebGL platform, the "token" cannot be empty.
roomConfig.token = "xxxx";
// Log in to a room
engine.LoginRoom("123666", user, roomConfig);
2. Listen for and handle the event callbacks for updates on users and streams in the room
To listen for and handle various events that may happen after logging in to a room, you can implement the corresponding event callback methods of the event handler as needed. The following are some common event callbacks related to room users and streams:
onRoomStateUpdate
: Callback for updates on current user's room connection status. When the current user's room connection status changes (for example, when the current user is disconnected from the room or login authentication fails), the SDK sends out the event notification through this callback.
onRoomUserUpdate
: Callback for updates on the status of other users in the room. When other users join or leave the room, the SDK sends out the event notification through this callback.
onRoomStreamUpdate
: Callback for updates on the status of the streams in the room. When new streams are published to the room or existing streams in the room stop, the SDK sends out the event notification through this callback.
Event callbacks are delegates of the ZegoExpressEngine
class. To listen for and handle a specific event callback, assign the callback handling method you implement to the corresponding callback delegate of the ZegoExpressEngine
instance.
onRoomUserUpdate
callback, you must set the isUserStatusNotify
property of the room configuration parameter ZegoRoomConfig
to true
when you call the loginRoom
method to log in to a room.onRoomStreamUpdate
callback, and when there is a stream added, call the startPlayingStream
method to start receiving and playing the newly added stream.// Callback for updates on the current user's room connection status.
public void OnRoomStateUpdate(string roomId, ZegoRoomState state, int errorCode, string extendedData) {
// Implement the callback handling logic as needed.
}
// Callback for updates on the status of other users in the room.
private void OnRoomUserUpdate(string roomId, ZegoUpdateType updateType, List<ZegoUser> userList, uint userCount) {
// Implement the callback handling logic as needed.
}
// Callback for updates on the status of the streams in the room.
private void OnRoomStreamUpdate(string roomId, ZegoUpdateType updateType, List<ZegoStream> streamInfoList, uint streamInfoCount) {
// Implement the callback handling logic as needed.
}
// Assign the callback handling methods you implement to the delegates of the engine.
engine.onRoomStateUpdate = OnRoomStateUpdate;
engine.onRoomUserUpdate = OnRoomUserUpdate;
engine.onRoomStreamUpdate = OnRoomStreamUpdate;
1. Start publishing a stream
To start publishing a local audio or video streams to remote users, call the startPublishingStream
method with the corresponding Stream ID passed to the streamID
parameter.
streamID
must be globally unique within the scope of the AppID. If different streams are published with the same streamID
, the ones that are published after the first one will fail.
// Start publishing a stream.
[[ZegoExpressEngine sharedEngine] startPublishingStream:@"stream1"];
2. Optional: Start the local video preview
To start the local video preview, call the startPreview
method with the view for rendering the local video passed to the canvas
parameter.
There are four screen orientations for Android devices and iOS devices: Portrait
, PortraitUpsideDown
, LandscapeLeft
, and LandscapeRight
. To make sure the local preview and remote playback are always displayed in the right orientation, you need to add related code in your project, for more details, see Quick starts - Integration - 4 Set screen orientation.
In Unity, you can render the local video preview using RawImage
or Plane Renderer
.
Method 1: Using aRawImage
Select Canvas > UI > Raw Image to create a RawImage
.
Add the following code to render the local video using the RawImage
.
RawImageVideoSurface localVideoSurface = null;
GameObject mainLocalVideoPlane = null;
mainLocalVideoPlane = GameObject.Find("MainPreViewRawImage");
if (mainLocalVideoPlane != null && localVideoSurface == null)
{
// Add a RawImageVideoSurface component, and the renderer is RawImage.
localVideoSurface = mainLocalVideoPlane.AddComponent<RawImageVideoSurface>();
// Set the RawImageVideoSurface as the view for local video preview.
localVideoSurface.SetCaptureVideoInfo();
// Set the engine as the video source.
localVideoSurface.SetVideoSource(engine);
}
// Start local video preview
engine.StartPreview();
Method 2: Using Plane Renderer
Select Canvas > 3D Object > Plane to create a Plane
(with a Renderer
).
Add the following code to render the local video using the Renderer
of the Plane
.
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Plane);// Create a Plane in runtime.
if (go == null)
{
return;
}
go.name = "preview-render";
// Ensure the video can be displayed on the screen.
go.transform.Rotate(90.0f, -180.0f, 0.0f);
go.transform.position = new Vector3(0.0f, 0.0f, 0.0f);
go.transform.localScale = new Vector3(0.36f, 1f, 0.64f);
// Add a RendererVideoSurface component, and the renderer is the Plane's renderer.
RendererVideoSurface renderer = go.AddComponent<RendererVideoSurface>();
// Set the RendererVideoSurface component as the view for local video preview.
renderer.SetCaptureVideoInfo();
// Set the engine as the video source.
renderer.SetVideoSource(engine);
// Start local video preview
engine.StartPreview();
3. Listen for and handle the event callbacks related to stream publishing
To listen for and handle various events that may happen after stream publishing starts, you can implement the corresponding event callback methods of the event handler as needed. The following is a common event callback related to stream publishing:
onPublisherStateUpdate
: Callback for updates on stream publishing status. After stream publishing starts, if the status changes, (for example, when the stream publishing is interrupted due to network issues and the SDK retries to start publishing the stream again), the SDK sends out the event notification through this callback.
onPublisherQualityUpdate
: Callback for reporting stream publishing quality. After stream publishing starts, the SDK sends out the streaming quality data (resolution, frame rate, bit rate, etc.) regularly through this callback.
Event callbacks are delegates of the ZegoExpressEngine
class. To listen for and handle a specific event callback, assign the callback handling method you implement to the corresponding callback delegate of the ZegoExpressEngine
instance.
// Callback for updates on stream publishing status.
public void OnPublisherStateUpdate(string streamId, ZegoPublisherState state, int errorCode, string extendedData)
{
// Implement the callback handling logic as needed.
}
// Callback for updates on stream publishing quality.
private void OnPublisherQualityUpdate(string streamId, ZegoPublishStreamQuality quality)
{
// Implement the callback handling logic as needed.
}
// Assign the callback handling methods you implement to the delegates of the engine.
engine.onPublisherStateUpdate = OnPublisherStateUpdate;
engine.onPublisherQualityUpdate = OnPublisherQualityUpdate;
engine.StartPublishingStream("stream1");
1. Start playing a stream
To start playing a remote audio or video stream, call the startPlayingStream
method with the corresponding stream ID passed to the streamID
parameter and the view for rendering the video passed to the canvas
parameter.
You can listen for the onRoomStreamUpdate
callback to obtain the stream IDs of the streams published by remote users.
There are four screen orientations for Android devices and iOS devices: Portrait
, PortraitUpsideDown
, LandscapeLeft
, and LandscapeRight
. To make sure the local preview and remote playback are always displayed in the right orientation, you need to add related code in your project, for more details, see [Qucik starts-Integration-4 Set screen orientation.
In Unity, you can render the remote video stream preview using RawImage
or Plane Renderer
.
Method 1: Using RawImage
Select Canvas > UI > Raw Image to create a RawImage
(with a Renderer
).
Add the following code to render the remote video stream using the RawImage.
private const float Offset = 100;
GameObject go = new GameObject();
if (go == null)
{
return;
}
go.name = "play-rawimage";
// Create a RawImage in runtime
go.AddComponent<RawImage>();
GameObject canvas = GameObject.Find("Canvas");
if (canvas != null)
{
go.transform.parent = canvas.transform;
}
float xPos = UnityEngine.Random.Range(Offset - Screen.width / 2f, Screen.width / 2f - Offset);
float yPos = UnityEngine.Random.Range(Offset, Screen.height / 2f - Offset);
go.transform.localPosition = new Vector3(xPos, yPos, 0f);
go.transform.localScale = new Vector3(3f, 4f, 1f);
// Add a RawImageVideoSurface component, and the renderer is RawImage.
RawImageVideoSurface videoSurface = go.AddComponent<RawImageVideoSurface>();
// Set the Stream ID of the stream you want to render.
videoSurface.SetPlayVideoInfo("123");
// Set the engine as the video source.
videoSurface.SetVideoSource(engine);
// Start playing the stream.
engine.StartPlayingStream("123");
Method 2: Using Plane Renderer
Select Canvas > 3D Object > Plane to create a Plane
(with a Renderer
).
Add the following code to render the remote stream using the Renderer
of the Plane
.
remoteVideoPlane = GameObject.Find("PlayRender");
if (remoteVideoPlane != null)
{
if (remoteVideoSurface == null)
{
// Add a RendererVideoSurface component, and the renderer is the Plane's renderer.
remoteVideoSurface = remoteVideoPlane.AddComponent<RendererVideoSurface>();
// Ensure the video can be displayed on the screen.
remoteVideoSurface.transform.Rotate(90.0f, -180.0f, 0.0f);
remoteVideoSurface.transform.position = new Vector3(0.0f, 0.0f, 0.0f);
remoteVideoSurface.transform.localScale = new Vector3(0.36f, 1f, 0.64f);
}
if (remoteVideoSurface != null)
{
// Set the Stream ID of the stream you want to render.
remoteVideoSurface.SetPlayVideoInfo("123");
// Set the engine as the video source.
remoteVideoSurface.SetVideoSource(engine);
}
}
// Start playing the stream.
engine.StartPlayingStream(“123”);
2. Listen for and handle the event callbacks related to stream playing
To listen for and handle various events that may happen after stream playing starts, you can implement the corresponding event callback methods of the event handler as needed. The following is a common event callback related to stream playing:
onPlayerStateUpdate
: Callback for updates on stream playing status. After stream playing starts, if the status changes (for example, when the stream playing is interrupted due to network issues and the SDK retries to start playing the stream again), the SDK sends out the event notification through this callback.
onPlayerQualityUpdate
: Callback for reporting stream playing quality. After stream playing starts, the SDK sends out the streaming quality data (frame rate, bit rate, RTT, packet loss rate, etc.) through this callback every 3 seconds.
onPlayerMediaEvent
: Callback for reporting streaming media events. After stream playing starts, when events occur (for example, the audio or video stutters or recovers from a stutter) the SDK sends out the event notification through this callback.
Event callbacks are delegates of the ZegoExpressEngine
class. To listen for and handle a specific event callback, assign the callback handling method you implement to the corresponding callback delegate of the ZegoExpressEngine
instance.
// Callback for updates on stream playing status.
public void OnPlayerStateUpdate(string streamId, ZegoPlayerState state, int errorCode, string extendedData)
{
// Implement the callback handling logic as needed.
}
// Callback for reporting stream playing quality.
private void OnPlayerQualityUpdate(string streamId, ZegoPlayStreamQuality quality)
{
// Implement the callback handling logic as needed.
}
// Callback for reporting streaming media events. Please note that this callback is not supported on the WebGL platform.
private void OnPlayerMediaEvent(string streamId, ZegoPlayerMediaEvent mediaEvent)
{
// Implement the callback handling logic as needed.
}
// Assign the callback handling methods you implement to the delegates of the engine.
engine.onPlayerStateUpdate = OnPlayerStateUpdate;
// Please note that the onPlayerMediaEvent event callback is not supported on the WebGL platform.
engine.onPlayerMediaEvent = OnPlayerMediaEvent;
engine.onPlayerQualityUpdate = OnPlayerQualityUpdate;
engine.StartPlayingStream("123");
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.
1. Stop publishing a remote stream
To stop publishing a local audio or video stream to remote users, call the stopPublishingStream
method.
// Stop publishing a stream
engine.StopPublishingStream();
2. Stop local video preview
If local video preview is started, call the stopPreview
method to stop it as needed.
// Stop local video preview
engine.StopPreview();
3. Stop playing a stream
To stop playing a remote audio and video stream, call the stopPlayingStream
method with the corresponding stream ID passed to the streamID
parameter.
// stop playing a stream
engine.StopPlayingStream("123");
To log out of a room, call the logoutRoom
method with the corresponding room ID passed to the roomID
parameter.
// log out of a room
engine.LogoutRoom("123666");
ZegoExpressEngine
instanceTo destroy the ZegoExpressEngine
instance and release the resources it occupies, call the destroyEngine
method.
// Destroy the engine instance
ZegoExpressEngine.DestroyEngine();