互动连麦
互动功能即用户端与讲师端进行1对1或者1对多的在线视频连麦功能。VHCInteractive库提供此功能。
####注意:使用此类请先在plist文件中添加对于摄像头和麦克风的权限描述。
<!-- 相机 -->
<key>NSCameraUsageDescription</key>
<string>需要您的同意,APP才能访问相机</string>
<!-- 麦克风 -->
<key>NSMicrophoneUsageDescription</key>
<string>需要您的同意,APP才能访问麦克风</string>
1.VHCInteractiveRoom
简介
VHCInteractiveRoom类是微吼课堂互动直播间实体类,此类定义了进入互动、离开互动、推流等Api,实现用户在线互动功能。此类管理互动直播间的生命周期、上麦推流、互动消息等。
1.初始化
/**
@brief 构造方法
@warning cameraView 推流用的cameraView,即VHRenderView的实例对象,需用户自己手动创建。初始化时即绑定推流所用的cameraView,推流时只需调用- (void)startPublish方法即可。
*/
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithPushCameraView:(nonnull VHRenderView *)cameraView;
初始化时,需要传入推流使用的cameraView,即自己的摄像头实例,是VHRenderView类的实例。
2.进入直播间
/**
@brief 进入互动直播间
@discussion 结果会在- (void)roomdidEnteredWithRoomMetaDataerror:中回调,如果进入成功,可以开始推流上麦。
*/
- (void)enterLiveRoom;
互动前进入互动直播间,进入失败则不能互动,进入结果会有回调
3.上麦推流
/**
@brief 推流上麦
@discussion 调用此方法会有两个回调,先回调推流是否成功:- (void)room:didPublishWithCameraView:error:,然后回调上麦是否成功- (void)room:microUpWithError:
*/
- (BOOL)startPublish;
4.停止推流
/**
@brief 停止推流
@discussion 下麦的时候需要停止推流。
*/
- (void)stopPulish;
5.离开直播间
/**
@brief 离开互动直播间,即下麦
@discussion 停止推流后离开互动直播间需调用此方法。
*/
- (void)leaveLiveRoom;
6.操作自己的设备
/**
@brief 设置麦克风开关
@warning 推流后设置才可生效
@return VHCError 设置失败 错误码:VHCErrorType_NoAuthority无权操作; VHCErrorType_NotEnterClass:未进入课堂或已掉线;VHCErrorType_InVaild:设置无效,未推流前设置都是无效的。
*/
- (VHCError *)closeMicphone:(BOOL)isClose;
/**
@brief 设置摄像头开关
@warning 推流后设置才可生效
@return VHCError 设置失败 错误码:VHCErrorType_NoAuthority无权操作; VHCErrorType_NotEnterClass:未进入课堂或已掉线;VHCErrorType_InVaild:设置无效,未推流前设置都是无效的。
*/
- (VHCError *)closeVideo:(BOOL)isClose;
其中VHCInteractiveRoomDelegate是互动房间代理,此代理定义了进入互动房间结构回调、推流结果回调、上麦结果回调等与互动房间有关的回调方法。在回调中可以处理您关于互动的相关操作。
####VHCInteractiveRoomDelegate
///----------------------------
/// @name 互动直播间生命周期相关回调
///----------------------------
/**
@brief 进入互动直播间结果回调
@param data 互动直播间数据
@param error 错误
@discussion 当error为nil时候,表示已进入互动直播间;error不为空时,表示进入失败,失败原因描述:error.errorDescription。成功进入互动直播间成功就可以开始推流上麦了。
*/
- (void)room:(VHCInteractiveRoom *)room didEnteredWithRoomMetaData:(NSDictionary *)data error:(VHCError *)error;
/**
@brief 推流结果回调
@param cameraView 推流的cameraView
@param error 推流错误,当error不为空时表示推流失败
@discussion 推流成功之后,会收到上麦结果的回调。
*/
- (void)room:(VHCInteractiveRoom *)room didPublishWithCameraView:(VHRenderView *)cameraView error:(VHCError *)error;
/**
@brief 停止推流回调
@param cameraView 推流的cameraView
@discussion 自己调用- unpublish停止推流,会回调此方法;被讲师下麦,会停止推流,回调此方法;推流出错,停止推流,会回调此方法。
*/
- (void)room:(VHCInteractiveRoom *)room didUnpublish:(VHRenderView *)cameraView;
/**
@brief 某用户被讲师下麦回调
@param byUserId 操作者户参会id,一般的自己被讲师下麦,此id为讲师参会id
@param toUserId 被操作者户参会id,如果是自己的参会id,则表示自己被讲师下麦。
*/
- (void)room:(VHCInteractiveRoom *)room leaveRoomByUserId:(NSString *)byUserId toUser:(NSString *)toUserId;
/**
@brief 某用户上麦结果回调
@param joinId 上麦用户的参会id
@param error error为nil时上麦成功
@param info 其他信息
@discussion 当error为nil时,表示上麦成功。
*/
- (void)room:(VHCInteractiveRoom *)room microUpWithJoinId:(NSString *)joinId attributes:(NSDictionary *)info error:(VHCError *)error;
/**
@brief 某用户下麦回调
@param info 其他信息
@param joinId 下麦用户的参会id
*/
- (void)room:(VHCInteractiveRoom *)room microDownWithJoinId:(NSString *)joinId attributes:(NSDictionary *)info;
/**
@brief 用户与直播间的连接状态回调
@param connectedStatus 用户与直播间的连接状态 @see VHCInteractiveRoomConnectedStatus
@discussion 失去连接则表示该用户已经在主播端下麦,建议在此回调中处理下麦后的业务;当状态为VHCInteractiveRoomConnectedStatusConnected时,表示已成功上麦;当状态为VHCInteractiveRoomConnectedStatusDisConnected时,表示自己已下麦。
*/
- (void)room:(VHCInteractiveRoom *)room connectedStatusChanged:(VHCInteractiveRoomConnectedStatus)connectedStatus;
//
/////--------------------
///// @name 互动相关事件回调
/////--------------------
/**
@brief 新加入一路流(有成员进入互动房间,即有人上麦)
@discussion 流id:attendView.streamId;上麦用户参会id:attendView.userId。
*/
- (void)room:(VHCInteractiveRoom *)room didAddAttendView:(VHRenderView *)attendView;
/**
@brief 减少一路流(有成员离开房间,即有人下麦)
@discussion 流id:attendView.streamId;上麦用户参会id:attendView.userId。
*/
- (void)room:(VHCInteractiveRoom *)room didRemovedAttendView:(VHRenderView *)attendView;
/**
@brief 关闭画面回调
@param isClose YES:关闭,NO:打开
@discussion byUserId操作者参会id,toUserId被操作者参会id。
@warning 自己操作自己的设备byUserId和toUserId都是自己的参会id。
*/
- (void)room:(VHCInteractiveRoom *)room screenClosed:(BOOL)isClose byUser:(NSString *)byUserId toUser:(NSString *)toUserId;
/**
@brief 关闭麦克风回调,即静音操作回调
@param isClose YES:关闭,NO:打开
@discussion byUserId操作者参会id,toUserId被操作者参会id。
@warning 自己操作自己的设备byUserId和toUserId都是自己的参会id。当toUserId == nil时候,表示全体静音。全体禁音针对的群体是除讲师外的所有学员,因此将时端开启全体禁音时,讲师并不会被禁音,除非讲师自己禁音。
*/
- (void)room:(VHCInteractiveRoom *)room microphoneClosed:(BOOL)isClose byUser:(NSString *)byUserId toUser:(NSString *)toUserId;
###2.VHRenderView
VHRenderView类是推流摄像头view类,该类定义了摄像头视图的创建、推流等Api,通过此类进行互动推流。 此类提供了摄像头的创建、前后转换、静音、取消静音等Api,另外也提供了摄像头和麦克风的开关操作。
2.上麦互动
1.创建本地摄像头
- (VHRenderView *)cameraView {
if (!_cameraView) {
//语音上麦,只推语音流
NSDictionary *option = nil;
if (_type == MicroTypeOnlyVoice) {
option = @{VHVideoWidthKey:@"192",VHVideoHeightKey:@"144",VHVideoFpsKey:@(25),
VHMaxVideoBitrateKey:@(200),VHStreamOptionStreamType:@(5)}; }
_cameraView = [[VHRenderView alloc]
initCameraViewWithFrame:CGRectZero pushType:VHPushTypeSD options:option];
_cameraView.scalingMode = VHRenderViewScalingModeAspectFill;
}
return _cameraView;
}
####2.添加本地摄像头
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
///防止摄像头卡顿再此添加摄像头
self.cameraView.frame = self.view.bounds;
[self.view insertSubview:self.cameraView atIndex:0];
}
3.处理进入直播间回调
成功进入,则开始推流上麦
/**
@brief 进入互动直播间结果回调
@param data 互动直播间数据
@param error 错误
@discussion 当error为nil时候,表示已进入互动直播间;error不为空时,表示进入失败,失败原因描述:error.errorDescription。成功进入互动直播间成功就可以开始推流上麦了。
*/
- (void)room:(VHCInteractiveRoom *)room didEnteredWithRoomMetaData:(NSDictionary *)data error:(VHCError *)error
{
if (error) {
VHCLog(@"互动房间连接出错");
return;
}
VHCLog(@"互动房间连接成功,开始推流");
dispatch_async(dispatch_get_main_queue(), ^{
//上麦推流
[room publishWithCameraView:self.cameraView];
});
}
4.处理上麦结果
/**
@brief 某用户上麦结果回调
@param joinId 上麦用户的参会id
@param error error为nil时上麦成功
@discussion 当error为nil时,表示上麦成功。
*/
- (void)room:(VHCInteractiveRoom *)room microUpWithJoinId:(NSString *)joinId error:(VHCError *)error
{
if (error) {
if ([joinId isEqualToString:[User defaultUser].joinId]) {
VHCLog(@"上麦失败!");
[VHCTool showAlertWithMessage:@"上麦失败!"];
//上麦失败,退到看直播
[self closeButtonClick:nil];
}
return;
}
if ([joinId isEqualToString:[User defaultUser].joinId])
{
VHCLog(@"上麦成功!");
[VHCTool showAlertWithMessage:@"您已上麦"];
}
else {
[VHCTool showAlertWithMessage:[NSString stringWithFormat:@"用户%@上麦了",joinId]];
}
}
上麦结果回调会回调每个进入互动直播间的用户上麦消息,根据joinId区分不同的用户,收到上麦结果,error为空时,才算上麦成功,否则上麦失败。上麦失败建议退出互动直播间,重新进入。
其他具体见demo。
三、注意
VHRenderView和VHCInteractiveRoom类都提供了摄像头和麦克风的开关Api:
/*
* 关闭音频
*/
- (void) muteAudio;
/*
* 取消关闭音频
*/
- (void) unmuteAudio;
/*
* 关闭视频
*/
- (void) muteVideo;
/*
* 取消关闭视频
*/
- (void) unmuteVideo;
以上Api直接对自己的设备进行操作,关闭或者打开自己的摄像头。
/**
@brief 设置麦克风开关
@warning 推流后设置才可生效
@return VHCError 设置失败 错误码:VHCErrorType_NoAuthority无权操作; VHCErrorType_NotEnterClass:未进入课堂或已掉线;VHCErrorType_InVaild:设置无效,未推流前设置都是无效的。
*/
- (VHCError *)closeMicphone:(BOOL)isClose;
/**
@brief 设置摄像头开关
@warning 推流后设置才可生效
@return VHCError 设置失败 错误码:VHCErrorType_NoAuthority无权操作; VHCErrorType_NotEnterClass:未进入课堂或已掉线;VHCErrorType_InVaild:设置无效,未推流前设置都是无效的。
*/
- (VHCError *)closeVideo:(BOOL)isClose;
两者是有区别的,VHRenderView只是单纯的关闭或者打开自己的摄像头,但是不会通知主播端,VHCInteractiveRoom中的Api操作设备后会通知主播端。建议使用VHCInteractiveRoom中提供的Api。