| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787 |
- //
- // ClassroomViewController.m
- // MusicGradeExam
- //
- // Created by Kyle on 2020/7/10.
- // Copyright © 2020 DayaMusic. All rights reserved.
- //
- #import "ClassroomViewController.h"
- #import "ClassTitleView.h"
- #import "ClassroomMainContainer.h"
- #import "ClassVideoListView.h"
- #import "KSNormalAlertView.h"
- #import "RTCService.h"
- #import "Classroom.h"
- #import "ClassroomService.h"
- #import <MBProgressHUD/MBProgressHUD.h>
- #import "AppDelegate.h"
- #import "UIDevice+TFDevice.h"
- #import "KSRemoteUserManager.h"
- #import "LocalRenderManager.h"
- #import "NSDate+Transform.h"
- #import "UIViewController+zhStatusBarStyle.h"
- #import "KSTipsView.h"
- #import "RoomLoginHelper.h"
- #define TitleViewHeight (64)
- typedef NS_ENUM(NSInteger, KICKTYPE) {
- KICKTYPE_NONE,
- KICKTYPE_FINISH = 1,
- KICKTYPE_RECORD = 2,
- KICKTYPE_RESIGN = 3,
- };
- @interface ClassroomViewController ()<ClassTitleViewDelegate, RongRTCRoomDelegate, ClassroomDelegate, UIGestureRecognizerDelegate, RongRTCActivityMonitorDelegate, RTCServiceDelegate, ClassVideoListViewDelegate>
- @property (nonatomic, strong) ClassTitleView *titleView;
- @property (nonatomic, strong) ClassroomMainContainer *containerView;
- @property (nonatomic, strong) ClassVideoListView *videoListView;
- @property (nonatomic, strong) MBProgressHUD *hud;
- @property (nonatomic, strong) NSMutableArray<NSNumber*>* packetLossStore;
- @property (nonatomic, strong) UILabel *networkLabel;
- @property (nonatomic, assign) BOOL cancleAlert;
- @property (nonatomic, assign) BOOL hasShowAlert;
- @property (nonatomic, assign) BOOL isSwitchLine; // 是否线路切换
- @property (nonatomic, strong) KSTipsView *tipsView;
- @property (nonatomic, assign) KICKTYPE kickType; // 退出状态
- @end
- @implementation ClassroomViewController
- #pragma mark - Life cycle
- - (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
- self.zh_statusBarHidden = YES;
- // 切换到横屏
- AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
- delegate.allowAutoRotate = YES;
- [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight];
- [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
- [RongRTCEngine sharedEngine].monitorDelegate = self;
- }
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- // 竖屏
- AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
- delegate.allowAutoRotate = NO;
- [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait];
- [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
- self.zh_statusBarHidden = NO;
- }
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
-
- self.view.backgroundColor = [UIColor colorWithHexString:@"141414" alpha:1];
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(leaveRoomAction) name:@"classroomLogout" object:nil];
- // 切换到横屏
- AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
- delegate.allowAutoRotate = YES;
- [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight];
- [self addSubviews];
- [self bindDelegates];
- [self publishStream];
- [self renderMainContainerView];
- [[RTCService sharedInstance] useSpeaker:YES];
- UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
- [self.view addGestureRecognizer:tapGes];
- tapGes.delegate = self;
- [self showRoleHud];
- self.kickType = KICKTYPE_NONE;
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundQuitRoomAction) name:@"backgroundQuit" object:nil];
- }
- - (void)backgroundQuitRoomAction {
- self.isSwitchLine = NO;
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- self.cancleAlert = YES;
- }
- #pragma mark ----- 账号异地登陆
- - (void)leaveRoomAction {
- [self.tipsView showTipsMessage:@"该账号在其他地方登录" inView:self.view];
- self.isSwitchLine = NO;
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- self.cancleAlert = YES;
- [[NSNotificationCenter defaultCenter] postNotificationName:@"backLoginView" object:nil];
- }
- // 提示信息
- - (void)showMessage:(NSString *)message {
- MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
- [self.view bringSubviewToFront:hud];
- hud.removeFromSuperViewOnHide =YES;
- hud.mode = MBProgressHUDModeText;
- hud.label.text = message;
- hud.minSize = CGSizeMake(132.f, 60.0f);
- hud.label.textColor = [UIColor whiteColor];
- hud.bezelView.backgroundColor = [UIColor colorWithHexString:@"#000000" alpha:0.8];
- [hud hideAnimated:YES afterDelay:2];
- }
- - (void)tapGesture: (UITapGestureRecognizer *)tapGesture {
- self.titleView.isDisplay = YES;
- }
- -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
- if ([touch.view isDescendantOfView:self.videoListView]) {
- return NO;
- }
- if ([touch.view isDescendantOfView:self.containerView]) {
- [self tapGesture:(UITapGestureRecognizer *)gestureRecognizer];
- }
- return YES;
- }
- - (void)showRoleHud {
- Role role = [ClassroomService sharedService].currentRoom.currentMember.role;
- if(role == RoleAudience) {
- [self.tipsView showTipsMessage:@"你当前身份是旁听人,其他人看/听不见你" inView:self.view];
-
- [self performSelector:@selector(showOnlyYouHUD) withObject:nil afterDelay:5.0f];
- }else{
- [self showOnlyYouHUD];
- }
- }
- - (void)showOnlyYouHUD {
- if ([ClassroomService sharedService].currentRoom.memberList.count == 1) {
- [self.tipsView showTipsMessage:@"当前课堂只有你一人,你可以等待或离开" inView:self.view];
- }
- }
- #pragma mark --- ClassTitleViewDelegate
- - (void)classTitleView:(UIButton *)button didTapAtTag:(ClassTitleViewActionTag)tag {
- switch (tag) {
- case ClassTitleViewActionTagMicrophone:
- {
- if (button.selected == NO) {
- [KSNormalAlertView ks_showAlertWithTitle:@"确认关闭麦克风吗?" leftTitle:@"取消" rightTitle:@"确认" cancel:^{
- } confirm:^{
- button.selected = YES;
- [[ClassroomService sharedService] enableDevice:NO withType:DeviceTypeMicrophone];
- }];
- }
- else {
- button.selected = NO;
- [[ClassroomService sharedService] enableDevice:YES withType:DeviceTypeMicrophone];
- }
- }
- break;
- case ClassTitleViewActionTagCamera:
- {
- if (button.selected == NO) {
- [KSNormalAlertView ks_showAlertWithTitle:@"确认关闭摄像头吗?" leftTitle:@"取消" rightTitle:@"确认" cancel:^{
- } confirm:^{
- button.selected = YES;
- [[ClassroomService sharedService] enableDevice:NO withType:DeviceTypeCamera];
- }];
- }
- else {
- button.selected = NO;
- [[ClassroomService sharedService] enableDevice:YES withType:DeviceTypeCamera];
- }
- }
- break;
- case ClassTitleViewActionTagSwitchLine: // 切换线路
- {
- [KSNormalAlertView ks_showAlertWithTitle:@"确认切换线路吗?" leftTitle:@"取消" rightTitle:@"确认" cancel:^{
- } confirm:^{
- [self restartRoom];
- }];
- }
- break;
- case ClassTitleViewActionTagSwitchCamera:
- {
- [[RTCService sharedInstance] switchCamera];
- }
- break;
- case ClassTitleViewActionTagHangup:
- {
- [KSNormalAlertView ks_showAlertWithTitle:@"确认退出课堂吗?" leftTitle:@"取消" rightTitle:@"确认" cancel:^{
- } confirm:^{
- SealClassLog(@"ActionTagHangup");
- self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- [self.hud hideAnimated:YES];
- }];
- }];
- }
- break;
- default:
- break;
- }
- }
- // 判断是否需要退出房间
- - (void)refreshClassStatus {
- /*
- NSString *userType = UserDefault(UserTypeKey);
- if (![userType isEqualToString:@"1"] && self.isQuitRoom == NO) {
- NSString *formatString = @"yyyy-MM-dd HH:mm:ss";
- NSDate *endDate = [NSDate dateFromString:self.classEndTime format:formatString];
- NSTimeInterval endDuration = [[NSDate date] timeIntervalSinceDate:endDate];
- if (endDuration >= self.quitRoomTime * 60) {
- self.isQuitRoom = YES;
- // 退出房间
- [self showMessage:@"课程已结束"];
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- // 课程结束退出房间
- SealClassLog(@"ClassEnd!");
- self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
- [[LoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- [self.hud hideAnimated:YES];
- }];
- });
- }
- }
- */
- }
- #pragma mark ------ 退出RTC房间并重新加入
- - (void)restartRoom {
- self.isSwitchLine = YES;
- self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- }
- - (void)reJoinRTCRoom {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- NSString *roomId = [RoomLoginHelper sharedInstance].roomId;
- NSString *userName = [RoomLoginHelper sharedInstance].userName;
- [[ClassroomService sharedService] joinClassroom:roomId userName:userName isAudience:NO success:^(Classroom * _Nonnull classroom) {
- self.isSwitchLine = NO;
- [self restartRTCConnection];
- } error:^(ErrorCode errorCode, NSString * _Nonnull message) {
- [self.tipsView showTipsMessage:@"切换线路失败!" inView:self.view];
- [self.hud hideAnimated:YES];
- self.isSwitchLine = NO;
- }];
- });
- }
- - (void)restartRTCConnection {
-
- [[RTCService sharedInstance] joinRongRTCRoom:[ClassroomService sharedService].currentRoom.roomId success:^(RongRTCRoom * _Nonnull room) {
- [self.hud hideAnimated:YES];
- [self.tipsView showTipsMessage:@"切换线路成功" inView:self.view];
- // 重置UI 重新发布音视频流
- [LocalRenderManager shareInstance].hadRenderMainView = NO;
- [self publishStream];
- [self bindDelegates];
- [self.titleView refreshTitleView];
- [self.hud hideAnimated:YES];
- [RongRTCEngine sharedEngine].monitorDelegate = self;
- [[RTCService sharedInstance] useSpeaker:YES];
- [self renderMainContainerView];
- [self.videoListView reloadVideoList];
-
- } error:^(RongRTCCode code) {
- [self.hud hideAnimated:YES];
- [self.tipsView showTipsMessage:@"切换线路失败!" inView:self.view];
- }];
- }
- #pragma mark - ClassroomDelegate
- - (void)roomDidLeave {
- NSLog(@"roomDidLeave");
- if (_isSwitchLine) {
- if ([RTCService sharedInstance].rtcRoom) {
- [[KSRemoteUserManager shareInstance] removeAllUser];
- [[RTCService sharedInstance] leaveRongRTCRoom:[ClassroomService sharedService].currentRoom.roomId success:^{
- [self reJoinRTCRoom];
- } error:^(RongRTCCode code) {
- [self.hud hideAnimated:YES];
- [self.tipsView showTipsMessage:@"切换线路失败!" inView:self.view];
- self.isSwitchLine = NO;
- }];
- }
- }
- else if (_kickType != KICKTYPE_NONE) { // 退出房间,但是不dismiss
- [[KSRemoteUserManager shareInstance] removeAllUser];
- if ([RTCService sharedInstance].rtcRoom) {
- [[RTCService sharedInstance] leaveRongRTCRoom:[ClassroomService sharedService].currentRoom.roomId success:^{
- } error:^(RongRTCCode code) {
- }];
- }
- [self showKickAlert];
- }
- else {
- [[KSRemoteUserManager shareInstance] removeAllUser];
- if ([RTCService sharedInstance].rtcRoom) {
- [[RTCService sharedInstance] leaveRongRTCRoom:[ClassroomService sharedService].currentRoom.roomId success:^{
- } error:^(RongRTCCode code) {
- }];
- }
- [self dismissClassroom];
- }
- }
- - (void)showKickAlert {
- if (_kickType == KICKTYPE_FINISH) {
- [KSNormalAlertView ks_showAlertWithTitle:@"您已完成考试,请耐心等待考试结果。" confirmTitle:@"退出考场" confirm:^{
- [self dismissClassroom];
- }];
- }
- else if (_kickType == KICKTYPE_RECORD) {
- // 弹窗提示去录播
- [KSNormalAlertView ks_showAlertWithTitle:@"当前状态无法正常完成在线直播考试\n主考官建议您录播上传考试视频。" leftTitle:@"取消" rightTitle:@"去录播" cancel:^{
- // 离开教室
- [self dismissClassroom];
- } confirm:^{
- // 去录播
- [self dismissClassroom];
- [[NSNotificationCenter defaultCenter] postNotificationName:RecordExamNotification object:nil];
- }];
- }
- else if (_kickType == KICKTYPE_RESIGN) {
- [KSNormalAlertView ks_showAlertWithTitle:@"当前状态无法正常完成考试,请检查设备及网络状态正常后再次签到考试。" confirmTitle:@"确定" confirm:^{
- // 离开教室
- [self dismissClassroom];
- }];
- }
- }
- - (void)dismissClassroom {
- [self.hud hideAnimated:YES];
- [ClassroomService sharedService].currentRoom = nil;
- [self dismissViewControllerAnimated:NO completion:^{
- [self.titleView stopDurationTimer];
- }];
- }
- - (void)memberDidJoin:(RoomMember *)member {
- NSLog(@"memberDidJoin %@",member);
- if(member.role == RoleMainTeacher || member.role == RoleAssistantTeacher) {
- [self.videoListView reloadVideoList];
- }
- if (member.role == RoleMainTeacher || member.role == RoleAssistantTeacher) {
- [self.tipsView showTipsMessage:[NSString stringWithFormat:@"老师%@已经进入教室", member.name] inView:self.view];
- }
- }
- - (void)memberDidLeave:(RoomMember *)member {
- NSLog(@"memberDidLeave %@",member);
- // 此处移除
- [[KSRemoteUserManager shareInstance] removeUser:member.userId];
-
- if(member.role == RoleMainTeacher || member.role == RoleAssistantTeacher) {
- [self.videoListView reloadVideoList];
- }
- }
- - (void)memberDidKick:(RoomMember *)member {
- NSLog(@"memberDidKick %@",member);
- RoomMember *curMember = [ClassroomService sharedService].currentRoom.currentMember;
- [[ClassroomService sharedService].currentRoom removeMemeber:member];
- if ([curMember.userId isEqualToString:member.userId]) {
- self.kickType = KICKTYPE_FINISH;
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- return;
- }
-
-
- [[KSRemoteUserManager shareInstance] removeUser:member.userId];
- Role curRole = [ClassroomService sharedService].currentRoom.currentMember.role;
- if (curRole == RoleMainTeacher || curRole == RoleAssistantTeacher) {
- [self.tipsView showTipsMessage:[NSString stringWithFormat:@"你已将%@移出课堂", member.name] inView:self.view];
- }
- [self.videoListView reloadVideoList];
- if (self.containerView.member.role == member.role) {
- [self.containerView cancelRenderView];
- }
- }
- - (void)memberRecordAction:(RoomMember *)member {
- NSLog(@"memberRecordAction %@", member);
- RoomMember *curMember = [ClassroomService sharedService].currentRoom.currentMember;
- if ([curMember.userId isEqualToString:member.userId]) {
- self.kickType = KICKTYPE_RECORD;
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- }
- }
- // 不播放声音列表
- - (void)memberIgnoreAction:(RoomMember *)member {
- NSLog(@"memberRecordAction %@", member);
- NSString *shieldUserId = member.shieldUserId;
- NSArray *memberArray = [shieldUserId componentsSeparatedByString:@","];
- [[RTCService sharedInstance] unPlayRemoteUserAudioStream:memberArray];
- }
- - (void)memberNoFinishAction:(RoomMember *)member {
- NSLog(@"memberRecordAction %@", member);
- RoomMember *curMember = [ClassroomService sharedService].currentRoom.currentMember;
- if ([curMember.userId isEqualToString:member.userId]) {
- self.kickType = KICKTYPE_RESIGN;
- [[RoomLoginHelper sharedInstance] logout:^{
- } error:^(RongRTCCode code) {
- }];
- }
- }
- - (void)errorDidOccur:(ErrorCode)code {
- NSLog(@"errorDidOccur %@",@(code));
- [self.hud hideAnimated:YES];
- if (code != ErrorCodeSuccess) {
- if (code == ErrorCodeOverMaxUserCount) {
- [self.tipsView showTipsMessage:@"超过人数限制" inView:self.view];
- }else {
- [self.tipsView showTipsMessage:@"操作失败,请稍后再试" inView:self.view];
- }
- }
- }
- - (void)deviceDidEnable:(BOOL)enable type:(DeviceType)type forUser:(RoomMember *)member operator:(nonnull NSString *)operatorId {
- NSLog(@"deviceDidEnable devicetype:%@ enable:%@ memeber:%@",@(type),@(enable),member);
- RoomMember *curMember = [ClassroomService sharedService].currentRoom.currentMember;
- NSString *hudMessage = @"";
- //只有老师和自己才有提示
- if ((curMember.role == RoleMainTeacher || curMember.role == RoleAssistantTeacher) && ![curMember.userId isEqualToString:operatorId]) {
- if (type == DeviceTypeCamera) {
- hudMessage = !enable ? [NSString stringWithFormat:NSLocalizedStringFromTable(@"SetCameraClose", @"SealClass", nil),member.name] : [NSString stringWithFormat:NSLocalizedStringFromTable(@"SetCameraOpen", @"SealClass", nil),member.name];
- } else if (type == DeviceTypeMicrophone) {
- hudMessage = !enable ? [NSString stringWithFormat:NSLocalizedStringFromTable(@"SetMicorophoneClose", @"SealClass", nil),member.name] : [NSString stringWithFormat:NSLocalizedStringFromTable(@"SetMicorophoneOpen", @"SealClass", nil),member.name];
- }
- else if (type == DeviceTypeMusicMode) {
- hudMessage = !enable ? [NSString stringWithFormat:@"%@的音乐模式已关闭",member.name] : [NSString stringWithFormat:@"%@的音乐模式已开启",member.name];
- }
- [self.tipsView showTipsMessage:hudMessage inView:self.view];
- } else {
- if ([curMember.userId isEqualToString:member.userId]) {
- if (type == DeviceTypeCamera) { // 摄像头
- // 非自己操作才需要做提示
- if(![curMember.userId isEqualToString:operatorId]){
- hudMessage = !enable ? @"老师已关闭你的摄像头" : NSLocalizedStringFromTable(@"CameraOpend", @"SealClass", nil);
- [self.tipsView showTipsMessage:hudMessage inView:self.view];
- }
-
- [[RTCService sharedInstance] setCameraDisable:!enable];
- } else if (type == DeviceTypeMicrophone) { // 麦克风
- // 非自己操作才需要做提示
- if(![curMember.userId isEqualToString:operatorId]){
- hudMessage = !enable ? @"老师已关闭你的麦克风" : NSLocalizedStringFromTable(@"MicorophoneOpend", @"SealClass", nil);
- [self.tipsView showTipsMessage:hudMessage inView:self.view];
- }
-
- [[RTCService sharedInstance] setMicrophoneDisable:!enable];
-
- }
- else if (type == DeviceTypeMusicMode) {
- // 非自己操作才需要做提示
- if(![curMember.userId isEqualToString:operatorId]) {
- }
-
- [self changeModeAction:enable];
- }
- else if (type == DeviceTypeHandup) {
- }
- }
- }
- if (type == DeviceTypeCamera && [curMember.userId isEqualToString:member.userId]) {
- // 延迟调用,防止刷新出现灰屏
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self renderMainContainerView];
- });
- }
- [self.titleView refreshTitleView];
- }
- //助教请求用户打开设备,助教关闭用户设备没有回调。
- - (void)deviceDidInviteEnable:(DeviceType)type ticket:(NSString *)ticket {
- NSLog(@"deviceDidInviteEnable devicetype:%@ ticket:%@ ",@(type),ticket);
- if (type == DeviceTypeCamera) {
- [KSNormalAlertView ks_showAlertWithTitle:@"老师邀请你打开摄像头" leftTitle:@"拒绝" rightTitle:@"同意" cancel:^{
- [[ClassroomService sharedService] rejectEnableDevice:ticket];
- } confirm:^{
- [[ClassroomService sharedService] approveEnableDevice:ticket];
- }];
- }else if (type == DeviceTypeMicrophone) {
- [KSNormalAlertView ks_showAlertWithTitle:@"老师邀请你打开麦克风" leftTitle:@"拒绝" rightTitle:@"同意" cancel:^{
- [[ClassroomService sharedService] rejectEnableDevice:ticket];
- } confirm:^{
- [[ClassroomService sharedService] approveEnableDevice:ticket];
- }];
- }
- else {
- [[ClassroomService sharedService] approveEnableDevice:ticket];
- }
- }
- //只有助教能收到这个回调,可以不在这里处理文字,因为设备的回调还会走
- - (void)deviceInviteEnableDidApprove:(RoomMember *)member type:(DeviceType)type {
- NSLog(@"deviceInviteEnableDidApprove devicetype:%@ member:%@ ",@(type),member);
- }
- //拒绝只有助教能收到这个回调,且只走这个回调
- - (void)deviceInviteEnableDidReject:(RoomMember *)member type:(DeviceType)type {
- NSLog(@"deviceInviteEnableDidReject devicetype:%@ member:%@ ",@(type),member);
- [self.tipsView showTipsMessage:[NSString stringWithFormat:@"%@拒绝了你的邀请",member.name] inView:self.view];
- }
- #pragma mark - private method
- - (void)bindDelegates {
- self.titleView.delegate = self;
- [[RTCService sharedInstance] setRTCRoomDelegate:self];
- [RTCService sharedInstance].delegate = self;
- [ClassroomService sharedService].classroomDelegate = self;
- }
- - (void)addSubviews {
- [self.view addSubview:self.containerView];
- [self.view addSubview:self.titleView];
- [self.view addSubview:self.videoListView];
- [self.view bringSubviewToFront:self.titleView];
- }
- - (CGRect)mainContainerViewFrame {
- CGFloat x = iPhoneXSafeTopMargin;
- CGFloat y = 0;
- CGFloat width = UIScreenWidth - x - iPhoneXSafeBottomMargin;
- CGFloat height = UIScreenHeight - y;
- return CGRectMake(x, y, width, height);
- }
- - (void)publishStream {
- if ([ClassroomService sharedService].currentRoom.currentMember.role != RoleAudience) {
- [[RTCService sharedInstance] publishLocalUserDefaultAVStream];
- }
- }
- - (void)renderMainContainerView {
- // 主屏显示学生
- [self.containerView containerViewRenderView:[ClassroomService sharedService].currentRoom.currentMember];
- }
- - (void)whiteboardDidDisplay:(NSString *)boardId {
- NSLog(@"whiteboardDidDisplay %@ ",boardId);
- [self renderMainContainerView];
- }
- - (void)sharedScreenDidDisplay:(NSString *)userId {
- NSLog(@"sharedScreenDidDisplay %@ ",userId);
- [self renderMainContainerView];
- }
- - (void)studentDidDisplay:(NSString *)studentId {
- NSLog(@"studentDidDisplay %@", studentId);
- [self renderMainContainerView];
-
- }
- - (void)teacherDidDisplay {
- NSLog(@"teacherDidDisplay %@ ",[ClassroomService sharedService].currentRoom.teacher);
- [self renderMainContainerView];
- }
- - (void)noneDidDisplay {
- NSLog(@"noneDidDisplay");
- [self renderMainContainerView];
- }
- #pragma mark --- RTCServiceDelegate 自己发布流成功回调
- - (void)successPublishLocalStream {
-
- }
- #pragma mark - RongRTCRoomDelegate
- - (void)didPublishStreams:(NSArray <RongRTCAVInputStream *>*)streams {
-
- // 当用户非正常退出的时候,如果再次进入需要重新订阅流
- RongRTCAVInputStream *firstStream = [streams lastObject];
- if ([[KSRemoteUserManager shareInstance] isContentUser:firstStream.userId]) {
- [[KSRemoteUserManager shareInstance] removeUser:firstStream.userId];
- }
-
- for (RongRTCAVInputStream *stream in streams) {
- if (stream.streamType == RTCMediaTypeVideo) {
- [self.videoListView updateUserVideo:stream.userId];
- }
- }
- }
- - (void)didConnectToStream:(RongRTCAVInputStream *)stream {
- if (stream.streamId && stream.streamId.length > 0) {
- NSLog(@"didConnectToStream userId:%@ streamID:%@",stream.userId,stream.streamId);
- }
- }
- - (void)didReportFirstKeyframe:(RongRTCAVInputStream *)stream {
- if (stream.streamId && stream.streamId.length > 0) {
- }
- }
- #pragma mark ----- ClassVideoListViewDelegate
- - (void)videoListView:(ClassVideoListView *)view didTap:(RoomMember *)member {
-
- }
- #pragma mark - Getters & setters
- - (KSTipsView *)tipsView {
- if (!_tipsView) {
- _tipsView = [[KSTipsView alloc] initWithFrame:CGRectZero];
- }
- return _tipsView;
- }
- - (ClassTitleView *)titleView {
- if (!_titleView) {
- _titleView = [[ClassTitleView alloc] initWithFrame:CGRectMake(iPhoneXSafeTopMargin, 0, kScreenWidth - iPhoneXSafeTopMargin - iPhoneXSafeBottomMargin, TitleViewHeight)];
- }
- return _titleView;
- }
- - (ClassVideoListView *)videoListView {
- if(!_videoListView) {
- CGFloat width = 0.0f;
- CGFloat height = 0.0f;
- height = kScreenHeight - 10;
- width = height / 3.0f * 4;
- if (width > kScreenWidth - 160) {
- width = kScreenWidth - 160;
- }
- _videoListView = [[ClassVideoListView alloc] initWithFrame:CGRectMake(width + iPhoneXSafeTopMargin + 5, 10, kScreenWidth - (width + 10 + iPhoneXSafeTopMargin) - iPhoneXSafeBottomMargin, height)];
- _videoListView.delegate = self;
- }
- return _videoListView;
- }
- - (ClassroomMainContainer *)containerView {
- if (!_containerView) {
- _containerView = [[ClassroomMainContainer alloc] initWithFrame:[self mainContainerViewFrame]];
- }
- return _containerView;
- }
- #pragma mark ---- 网络监测
- - (void)didReportStatForm:(RongRTCStatisticalForm *)form {
- const CGFloat lossRateBase = 0.15;
- if (self.packetLossStore.count + form.sendStats.count > 10) {
- NSInteger diff = (self.packetLossStore.count + form.sendStats.count) - 10;
- [self.packetLossStore removeObjectsInRange:NSMakeRange(0,diff)];
- }
-
- for (RongRTCStreamStat* stat in form.sendStats) {
- [self.packetLossStore addObject:@(stat.packetLoss)];
- }
-
- float totalSum = 0;
- for (NSNumber* lossRate in self.packetLossStore) {
- totalSum += [lossRate floatValue];
- }
-
- if (totalSum > 0 && self.packetLossStore.count) {
- float avgLoss = totalSum / self.packetLossStore.count;
- [self showNetworkingStatus:avgLoss];
- if (avgLoss > lossRateBase) { // 网络质量不佳
-
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.view addSubview:self.networkLabel];
- [self.view bringSubviewToFront:self.networkLabel];
- self.networkLabel.hidden = NO;
- self.networkLabel.text = @"当前通话连接质量不佳";
- });
- }
- else { // 正常
- dispatch_async(dispatch_get_main_queue(), ^{
- self.networkLabel.hidden = YES;
- self.networkLabel.text = @"";
- [self.networkLabel removeFromSuperview];
- });
- }
- }
- }
- - (void)showNetworkingStatus:(float)packageLose {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (packageLose < 0.05) {
- self.titleView.netStatus = NetWorkingStatus_Good;
- }
- else if (packageLose <= 0.1) {
- self.titleView.netStatus = NetWorkingStatus_Well;
- }
- else if (packageLose <= 0.15) {
- self.titleView.netStatus = NetWorkingStatus_Bad;
- }
- else {
- self.titleView.netStatus = NetWorkingStatus_Poor;
- }
- });
- }
- - (NSMutableArray<NSNumber*>*)packetLossStore {
- if (!_packetLossStore) {
- _packetLossStore = [[NSMutableArray alloc] initWithCapacity:10];
- }
- return _packetLossStore;
- }
- - (UILabel *)networkLabel {
- if (!_networkLabel) {
- _networkLabel = [[UILabel alloc] initWithFrame:CGRectMake((kScreenWidth - 200) / 2.0f, (kScreenHeight - 60) / 2.0f, 200, 60)];
- _networkLabel.backgroundColor = HexRGBAlpha(0x000000, 0.8f);
- _networkLabel.textColor = HexRGB(0xffffff);
- _networkLabel.textAlignment = NSTextAlignmentCenter;
- _networkLabel.font = [UIFont systemFontOfSize:14.0f];
- _networkLabel.layer.cornerRadius = 5.0f;
- }
- return _networkLabel;
- }
- #pragma mark ---- 修改声音模式
- - (void)changeModeAction:(BOOL)enable {
- if (enable) {
- [[RongRTCAudioCapturer sharedInstance] changeMusicPlayMode:RongRTCAudioScenarioMusicSingleNotePlay];
- }
- else {
- [[RongRTCAudioCapturer sharedInstance] changeMusicPlayMode:RongRTCAudioScenarioMusicNomalPlay];
- }
- }
- /*
- #pragma mark - Navigation
- // In a storyboard-based application, you will often want to do a little preparation before navigation
- - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
- // Get the new view controller using [segue destinationViewController].
- // Pass the selected object to the new view controller.
- }
- */
- @end
-
|