This guide describes how to implement the core features of an interactive live streaming client using the ZEGO Express-Video SDK.
The following flowchart shows the basic processing flow of an interactive live streaming client.
The following diagram shows the API call sequence of a live streaming scenario where the viewer initiates the request to interact with the host live.
When you build your app, you will need to implement the Room Service component in the following diagram yourself. It is a back-end service mainly responsible for managing all the live rooms in your application. It maintains room-related information, such as the room list and room creator information, and serves such information to your app clients.
)
To help you better understand the above processing logic of our VideoLive demo, we will explain the core snippets of our demo source code in the following sections. You can also read the full demo source code for further study.
Before any other SDK operations, you need to create and initialize a ZegoExpressEngine instance. Since it requires quite a lot of SDK internal processing, it is recommended to perform this step when the client app starts up.
ZegoEngineProfile *profile = [ZegoEngineProfile new];
// The AppID value you get from the ZEGO Admin console.
profile.appID = appID;
// The AppSign value (64 characters) you get from the ZEGO Admin Console.
profile.appSign = appSign;
// Use the general scenario.
profile.scenario = ZegoScenarioGeneral;
// Create a ZegoExpressEngine instance and set eventHandler to [self]. If eventHandler is set to [nil], no callback will be received. You can set up the event handler later by calling the [-setEventHandler:] method.
[ZegoExpressEngine createEngineWithProfile:profile eventHandler:self];
For more details on how to initialize the engine, please refer to ZEGO Express-Video SDK QuickStart - Implementation.
The host and the viewers need to log into a room before they can start or join a live streaming session.
After a user initiates to log into a room, the ZEGO Express-Video SDK will fire an event through the callback onRoomStateUpdate to notify whether the login is successful. Upon successful login, the user can start publishing or playing streams by calling the corresponding APIs.
The host can join an existing room or create a new room to start a live streaming session. During the login process, if the room specified does not exist, it will be created automatically. So, there is no need to manually create a room first.
Viewers can get a room list from the back-end Room Service and select an existing room to join.
// Specify the Room ID.
NSString *roomID = <#(nonnull NSString *)#>;
// Create a user.
ZegoUser *user = [ZegoUser userWithUserID:conf.userID userName:conf.userName];
// The user's specific room settings.
ZegoRoomConfig *roomConfig = [[ZegoRoomConfig alloc] init];
// Whether to receive event notifications when other users join or leave the room.
roomConfig.isUserStatusNotify = YES;
// Log into the room.
[[ZegoExpressEngine sharedEngine] loginRoom:roomID user:user config:roomConfig];
For more details on how to log in to a room, please refer to ZEGO Express-Video SDK QuickStart - Implementation - 2.2.
The ZEGO Express-Video SDK allows a client to publish streams to ZEGO's media servers or a CDN for stream delivery.
Compared with CDN, ZEGO's media servers provide a better interactive live streaming experience with much lower streaming latency. A stream published to ZEGO's streaming media servers can be played by the stream ID, while a stream published to a CDN can be played via the corresponding playback URL. If you choose to publish streams to CDN, you can perform the setup before starting to publish streams.
Our VideoLive demo app publishes streams to ZEGO's media server.
// Set the view for rendering local video preview.
UIView *renderView = <#UIView#>;
// Set the view mode.
ZegoViewMode *renderMode = <#ZegoViewMode#>;
// Specify the Stream ID.
NSString *streamID = <#NSString#>;
ZegoCanvas *preview = [ZegoCanvas canvasWithView:renderView];
preview.viewMode = renderMode;
// Start the local video preview.
[[ZegoExpressEngine sharedEngine] startPreview:preview];
// Start publishing the stream.
[[ZegoExpressEngine sharedEngine] startPublishingStream:canvas.streamID];
For more details on how to start local video preview and start publishing streams, please refer to ZEGO Express-Video SDK QuickStart - Implementation - 2.3.
To view the stream published by the host, the viewer needs to get the stream ID from the callback onRoomStreamUpdate and play the stream by the stream ID.
// Set the view for rendering a remote stream.
UIView *playView = <#UIView#>;
// Set the view mode.
ZegoViewMode *playMode = <#ZegoViewMode#>;
// Specify the Stream ID.
NSString *streamID = <#NSString#>;
ZegoCanvas *preview = [ZegoCanvas canvasWithView:preview];
preview.viewMode = playMode;
// Start playing the stream.
[[ZegoExpressEngine sharedEngine] startPlayingStream:streamID canvas:preview];
For more details on how to play remote streams with SDK, please refer to ZEGO Express-Video SDK QuickStart - Implementation - 2.4.
You can perform the following steps to start a live interaction between the host and the viewer (in this example, the viewer initiates the request to interact) :
/// Send a request message for live interaction.
// User info of the host (the message recipient).
ZegoUser *anchor = [[ZegoUser alloc] initWithUserID:<#(nonnull NSString *)#> userName:<#(nonnull NSString *)#>];
// Specify the Room ID of the current room.
NSString *roomID = <#NSString#>;
// Define the message content of the request for live interaction.
NSString *command = <#NSString#>;
// Send the request message (messages should be verified on both sides).
[[ZegoExpressEngine sharedEngine] sendCustomCommand:command toUserList:@[anchor] roomID:roomID callback:^(int errorCode) {
if (errorCode != 0) {
// Failed to send the request message. Implement the retry logic here.
}
}];
/// Receive the request message for live interaction.
- (void)onIMRecvCustomCommand:(NSString *)command fromUser:(ZegoUser *)fromUser roomID:(NSString *)roomID {
// Check if it is a request for live interaction.
if ([command isEqualToString:<#(nonnull NSString *)#>]) {
// User info of the viewer (the message recipient).
ZegoUser *user = [[ZegoUser alloc] initWithUserID:<#(nonnull NSString *)#> userName:<#(nonnull NSString *)#>];
// Define the Accept or Reject response message content.
NSString *isAgreeCommand = <#NSString#>;
// Specify the Room ID of the current room.
NSString *roomID = <#NSString#>;
// Send the Accept or Reject response message.
[[ZegoExpressEngine sharedEngine] sendCustomCommand:isAgreeCommand toUserList:@[user] roomID:roomID callback:^(int errorCode) {
if (errorCode != 0) {
// Failed to send the response message. Implement the retry logic here.
}
}];
}
}
Either the host or the viewer can end the live interaction.
// Case 1: the host ends the live interaction.
// The host sends a message to the viewer for ending the interaction.
[[ZegoExpressEngine sharedEngine] sendCustomCommand:<#(nonnull NSString *)#> toUserList:<#(nullable NSArray<ZegoUser *> *)#> roomID:<#(nonnull NSString *)#> callback:<#^(int errorCode)callback#>];
// Upon receiving the message from the host to end the interaction, the viewer stops publishing the stream. Once the viewer's stream stops, the event (stream deleted from the room) will be fired through the callback `onRoomStreamUpdate`. Upon receiving the stream deleted event, the host can stop playing the viewer's stream and remove the corresponding view from the UI.
// Case 2: the viewer ends the live interaction.
// The viewer stops publishing the stream, stops local video preview, and remove the view for local preview accordingly.
[[ZegoExpressEngine sharedEngine] stopPublishingStream:<#(ZegoPublishChannel)#>];
// Once the viewer's stream stops, the event (stream deleted from the room) will be fired through the callback `onRoomStreamUpdate`. Upon receiving the stream deleted event, the host can stop playing the viewer's stream and remove the corresponding view from the UI.
| Method | Description |
|---|---|
| createEngine | Creates a singleton instance of ZegoExpressEngine. |
| setEventHandler | Sets event callback handler for the SDK. |
| loginRoom | Logs in to a room. |
| startPreview | Starts local video preview |
| startPublishingStream | Starts publishing a stream. |
| startPlayingStream | Starts playing a stream. |
| sendBroadcastMessage | Sends a Broadcast Message. |
| sendCustomCommand | Sends a Custom Command to the specified users. |
| stopPublishingStream | Stops publishing a stream. |
| stopPreview | Stops the local video preview. |
| stopPlayingStream | Stops playing a stream. |
| logoutRoom | Logs out of a room. |
| destroyEngine | Destroys the created ZegoExpressEngine instance. |
The ZEGO Express-Video SDK allows you to implement beauty features using third-party SDKs. Check out the guide ZEGO Express-Video SDK - Custom Video Pre-processing for more details on this topic.
With the ZEGO Express-Video SDK, you can also stream out background music along with the main media stream. Check out the guide ZEGO Express-Video SDK - Media Player for more details on this topic.
Through stream mixing, you can combine multiple media streams into a single one on the cloud. When the host and viewers have live interactions during a live streaming session, all the streams of the participating users can be mixed into a single stream, so that other viewers only need to play the mixed stream to view all the videos of users engaged in interaction. Check out the guide ZEGO Express-Video SDK - Stream Mixing for more details on this topic.
For more details on how to publish/play streams to/from CDN, please refer to:
