5_2-手机开播场景-连麦推流
1 Feature Overview
The streaming and mic link module is a fundamental feature in the mobile live streaming scenario. It supports camera on/off, front/rear camera switching, and microphone on/off functions. Streaming also supports resolution settings and camera mirroring. Streaming can be used for instructors to conduct classes, while mic linking supports both audio and video mic linking with free choice, and supports multi-user mic linking to enrich classroom content.
Streaming process: Initialize the streaming engine -> Set streaming configuration parameters -> Start streaming.
Mic linking process: Instructor initiates mic link -> Student raises hand to apply for mic link -> Instructor allows student to mic link -> Student officially joins the mic link.
2 Implementation Introduction
2.1 PLVStreamerPresenter
This class is a streaming manager encapsulated for streaming and mic linking in the mobile live streaming scenario. It supports CDN streaming, course management, RTC mic linking, and mic link user management.
2.1.1 Initialization Method
In the demo project PLVLSStreamerViewController, the manager needs to be initialized:
self.streamerPresenter = [[PLVStreamerPresenter alloc] init];
self.streamerPresenter.delegate = self;
self.streamerPresenter.previewType = PLVStreamerPresenterPreviewType_UserArray;
At the same time, PLVLSStreamerViewController must conform to the protocol PLVStreamerPresenterDelegate and implement its delegate methods. For more details, refer to the demonstration of PLVLSStreamerViewController in the demo project.
2.1.2 Setting Default Configuration
Based on specific business scenarios, default configurations for microphone, camera, stream properties, mixing layout mode, and other attributes can be set:
// 设置 麦克风、摄像头默认配置
// 仅在[prepareLocalPreviewCompletion:]方法调用前设置有效
self.streamerPresenter.micDefaultOpen = YES;// YES:麦克风默认开启 NO:麦克风默认关闭;默认值 NO
self.streamerPresenter.cameraDefaultOpen = YES;// YES:摄像头默认开启 NO:摄像头默认关闭;默认值 NO
self.streamerPresenter.cameraDefaultFront = YES;// YES:摄像头默认前置 NO:摄像头默认后置;默认值 后置
// 设置 流属性配置
[self.streamerPresenter setupStreamScale:PLVBLinkMicStreamScale16_9];
[self.streamerPresenter setupStreamQuality:PLVBLinkMicStreamQuality720P];
// 设置 混流配置
[self.streamerPresenter setupMixLayoutType:PLVRTCStreamerMixLayoutType_MainSpeaker];
2.1.3 Preview of Streaming Screen
Taking the demonstration of PLVLSStreamerViewController in the demo project as an example, join the RTC channel after the socket login success callback:
#pragma mark - PLVSocketManager Protocol
- (void)socketMananger_didLoginSuccess:(NSString *)ackString { // 登录成功
// 登录成功
[self.streamerPresenter joinRTCChannel];
}
At this point, the room status changes. In the delegate method shown below, set the container view for the local video preview:
#pragma mark - PLVStreamerPresenterDelegate
/// ‘房间加入状态’ 发生改变
- (void)plvStreamerPresenter:(PLVStreamerPresenter *)presenter currentRtcRoomJoinStatus:(PLVStreamerPresenterRoomJoinStatus)currentRtcRoomJoinStatus inRTCRoomChanged:(BOOL)inRTCRoomChanged inRTCRoom:(BOOL)inRTCRoom{
if (inRTCRoomChanged) {
if (inRTCRoom) {
[self preapareStartClass];
}
}
}
- (void)preapareStartClass {
__weak typeof(self) weakSelf = self;
[self.streamerPresenter prepareLocalPreviewCompletion:^(BOOL granted, BOOL prepareSuccess) {
if (prepareSuccess) {
[weakSelf.streamerPresenter setupLocalPreviewWithCanvaView:nil];
}
if (!granted) {
NSString *msg = [NSString stringWithFormat:@"需要获取您的音视频权限,请前往设置"];
[PLVAuthorizationManager showAlertWithTitle:@"提示" message:msg viewController:weakSelf];
}
}];
}
2.1.4 Start Class Method
The startClass method of PLVStreamerPresenter is used to start the class. Internally, it calls the startPushStream method. The startPushStream method is only responsible for streaming, while the startClass method starts streaming and sends a request to change the channel status to "Start Class". It is recommended to use the startClass method in business scenarios.
In the demo project, PLVLSStreamerViewController demonstrates starting the class when the countdown ends:
__weak typeof(self) weakSelf = self;
_coutBackView.countDownCompletedBlock = ^{
[weakSelf.streamerPresenter startClass];
};
2.1.5 End Class Method
The finishClass method of PLVStreamerPresenter is used to end the class. Internally, it calls the stopPushStream method. The startPushStream method only stops streaming, while the finishClass method stops streaming and sends a request to change the channel status to "End Class". It is recommended to use the finishClass method in business scenarios:
[self.streamerPresenter finishClass];
2.1.6 Allow User to Go on Mic
The allowRemoteUserJoinLinkMic method of PLVStreamerPresenter is used to allow a user to go on mic:
/// 允许 某位远端用户 上麦
///
/// @param waitUser 远端用户等待连麦模型
/// @param emitCompleteBlock ‘允许 某位远端用户 上麦’的请求发送结果Block
- (void)allowRemoteUserJoinLinkMic:(PLVLinkMicWaitUser *)waitUser emitCompleteBlock:(nullable void (^)(BOOL emitSuccess))emitCompleteBlock;
In the internal method of addLinkMicWaitUserWithDict of PLVStreamerPresenter, the user is allowed to go on mic.
When the array of online users in the RTC room changes, the reloadLinkMicUserWindows method of PLVLSLinkMicAreaView is called to refresh the mic link user's screen:
/// ’RTC房间在线用户数组‘ 发生改变
- (void)plvStreamerPresenter:(PLVStreamerPresenter *)presenter linkMicOnlineUserListRefresh:(NSArray <PLVLinkMicOnlineUser *>*)onlineUserArray{
[self.linkMicAreaView reloadLinkMicUserWindows];
}
2.1.7 Disconnect User from Mic
The closeAllLinkMicUser method of PLVStreamerPresenter is used to disconnect all mic link users:
[self.streamerPresenter closeAllLinkMicUser];
The closeRemoteUserLinkMic method of PLVStreamerPresenter is used to disconnect a specific remote user from the mic link. It is used internally in PLVStreamerPresenter. The closeAllLinkMicUser method uses the closeRemoteUserLinkMic method to implement disconnecting all mic link users.
For more implementation details, refer to PLVLSStreamerViewController in the demo project.
2.2 PLVLSLinkMicAreaView
PLVLSLinkMicAreaView is used to carry the data provided by the PLVStreamerPresenter streaming manager.
In the demo project, PLVLSStreamerViewController demonstrates how to add the PLVLSLinkMicAreaView control:
self.linkMicAreaView = [[PLVLSLinkMicAreaView alloc] init];
self.linkMicAreaView.delegate = self;
[self.view addSubview:self.linkMicAreaView];
At the same time, PLVLSStreamerViewController must conform to the protocol PLVLSLinkMicAreaViewDelegate and implement the following delegate methods:
@protocol PLVLSLinkMicAreaViewDelegate <NSObject>
/// 连麦窗口列表视图 需要获取当前用户数组
///
/// @param linkMicAreaView 连麦窗口列表视图
- (NSArray *)plvLSLinkMicWindowsViewGetCurrentUserModelArray:(PLVLSLinkMicAreaView *)linkMicAreaView;
/// 连麦窗口列表视图 需要查询某个条件用户的下标值
///
/// @param linkMicAreaView 连麦窗口列表视图
/// @param filtrateBlockBlock 筛选条件Block
- (NSInteger)plvLSLinkMicWindowsView:(PLVLSLinkMicAreaView *)linkMicAreaView findUserModelIndexWithFiltrateBlock:(BOOL(^)(PLVLinkMicOnlineUser * enumerateUser))filtrateBlockBlock;
/// 连麦窗口列表视图 需要根据下标值获取对应用户
///
/// @param linkMicAreaView 连麦窗口列表视图
/// @param targetIndex 目标下标值
- (PLVLinkMicOnlineUser *)plvLSLinkMicWindowsView:(PLVLSLinkMicAreaView *)linkMicAreaView getUserModelFromOnlineUserArrayWithIndex:(NSInteger)targetIndex;
@end
And in the -viewWillLayoutSubviews method, layout PLVLSLinkMicAreaView:
self.linkMicAreaView.frame = CGRectMake(CGRectGetMaxX(self.documentAreaView.frame) + linkMicAreaViewLeftPadding, CGRectGetMaxY(self.statusAreaView.frame), linkMicAreaViewWidth, ducomentViewHeight);
The specific implementation of the above content can be found in PLVLSStreamerViewController in the demo project.
