ClassroomService.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. //
  2. // ClassroomService.m
  3. // SealClass
  4. //
  5. // Created by LiFei on 2019/2/27.
  6. // Copyright © 2019 RongCloud. All rights reserved.
  7. //
  8. #import "ClassroomService.h"
  9. #import "MemberChangeMessage.h"
  10. #import "WhiteboardMessage.h"
  11. #import "DeviceMessage.h"
  12. #import "DisplayCommandMessage.h"
  13. #import "MemberChangeMessage.h"
  14. #import "TurnPageMessage.h"
  15. #import "RoleChangedMessage.h"
  16. #import "AssistantTransferMessage.h"
  17. #import "ApplySpeechMessage.h"
  18. #import "TicketExpiredMessage.h"
  19. #import "InviteUpgradeMessage.h"
  20. #import "ControlDeviceNotifyMessage.h"
  21. #import "SongDownloadMessage.h"
  22. #import "SongDownloadCallbackMessage.h"
  23. #import "AccompanyDownloadMessage.h"
  24. #import "AccompanyDownloadCallbackMessage.h"
  25. #import "KeyChainTools.h"
  26. #import <RongIMKit/RongIMKit.h>
  27. @interface ClassroomService ()
  28. @property (nonatomic, copy) NSString *auth;
  29. @end
  30. @implementation ClassroomService
  31. + (instancetype)sharedService {
  32. static ClassroomService *service;
  33. static dispatch_once_t onceToken;
  34. dispatch_once(&onceToken, ^{
  35. service = [[ClassroomService alloc] init];
  36. });
  37. return service;
  38. }
  39. #pragma mark - IM
  40. - (void)registerCommandMessages {
  41. [[RCIM sharedRCIM] registerMessageType:[MemberChangeMessage class]];
  42. [[RCIM sharedRCIM] registerMessageType:[WhiteboardMessage class]];
  43. [[RCIM sharedRCIM] registerMessageType:[DeviceMessage class]];
  44. [[RCIM sharedRCIM] registerMessageType:[DisplayCommandMessage class]];
  45. [[RCIM sharedRCIM] registerMessageType:[TurnPageMessage class]];
  46. [[RCIM sharedRCIM] registerMessageType:[RoleChangedMessage class]];
  47. [[RCIM sharedRCIM] registerMessageType:[AssistantTransferMessage class]];
  48. [[RCIM sharedRCIM] registerMessageType:[ApplySpeechMessage class]];
  49. [[RCIM sharedRCIM] registerMessageType:[ApplySpeechResultMessage class]];
  50. [[RCIM sharedRCIM] registerMessageType:[TicketExpiredMessage class]];
  51. [[RCIM sharedRCIM] registerMessageType:[InviteUpgradeMessage class]];
  52. [[RCIM sharedRCIM] registerMessageType:[ControlDeviceNotifyMessage class]];
  53. [[RCIM sharedRCIM] registerMessageType:[NodePlayMessage class]];
  54. [[RCIM sharedRCIM] registerMessageType:[SongDownloadMessage class]];
  55. [[RCIM sharedRCIM] registerMessageType:[SongDownloadCallbackMessage class]];
  56. [[RCIM sharedRCIM] registerMessageType:[AccompanyDownloadMessage class]];
  57. [[RCIM sharedRCIM] registerMessageType:[AccompanyDownloadCallbackMessage class]];
  58. }
  59. - (BOOL)isHoldMessage:(RCMessage *)message {
  60. BOOL needHold = NO;
  61. if ([message.content isKindOfClass:[MemberChangeMessage class]]) {
  62. needHold = NO;
  63. [self onReceiveCommandMessage:(MemberChangeMessage*)message.content];
  64. } else if ([message.content isKindOfClass:[WhiteboardMessage class]]) {
  65. needHold = YES;
  66. [self onReceiveWhiteboardMessage:(WhiteboardMessage*)message.content];
  67. } else if ([message.content isKindOfClass:[DeviceMessage class]]) {
  68. needHold = YES;
  69. [self onReceiveDeviceMessage:(DeviceMessage*)message.content withSenderId:message.senderUserId];
  70. } else if([message.content isKindOfClass:[DisplayCommandMessage class]]) {
  71. needHold = YES;
  72. [self onReceiveDisplayCommandMessage:(DisplayCommandMessage*)message.content];
  73. } else if([message.content isKindOfClass:[ApplySpeechMessage class]]) {
  74. needHold = YES;
  75. [self onReceiveApplySpeechMessage:(ApplySpeechMessage*)message.content];
  76. } else if([message.content isKindOfClass:[TurnPageMessage class]]) {
  77. needHold = YES;
  78. [self onReceiveTurnPageMessage:(TurnPageMessage*)message.content];
  79. } else if([message.content isKindOfClass:[RoleChangedMessage class]]) {
  80. needHold = YES;
  81. [self onReceiveRoleChangedMessage:(RoleChangedMessage*)message.content];
  82. } else if([message.content isKindOfClass:[AssistantTransferMessage class]]) {
  83. needHold = YES;
  84. [self onReceiveAssistantTransferMessage:(AssistantTransferMessage*)message.content];
  85. } else if([message.content isKindOfClass:[ApplySpeechResultMessage class]]) {
  86. needHold = YES;
  87. [self onReceiveSpeechResultMessage:(ApplySpeechResultMessage*)message.content];
  88. } else if ([message.content isKindOfClass:[TicketExpiredMessage class]]) {
  89. needHold = YES;
  90. [self onReceiveTicketExpiredMessage:(TicketExpiredMessage *)message.content];
  91. } else if ([message.content isKindOfClass:[InviteUpgradeMessage class]]) {
  92. needHold = YES;
  93. [self onReceiveInviteUpgradeMessage:(InviteUpgradeMessage *)message.content];
  94. } else if ([message.content isKindOfClass:[ControlDeviceNotifyMessage class]]) {
  95. needHold = YES;
  96. [self onReceiveControlDeviceNotifyMessage:(ControlDeviceNotifyMessage *)message.content];
  97. }
  98. else if ([message.content isKindOfClass:[NodePlayMessage class]]) {
  99. needHold = YES;
  100. [self onReceiveNodePlayMessage:(NodePlayMessage *)message.content];
  101. }
  102. else if ([message.content isKindOfClass:[SongDownloadMessage class]]) {
  103. needHold = YES;
  104. }
  105. else if ([message.content isKindOfClass:[SongDownloadCallbackMessage class]]) {
  106. needHold = YES;
  107. }
  108. else if ([message.content isKindOfClass:[AccompanyDownloadMessage class]]) { // 下载伴奏消息
  109. needHold = YES;
  110. [self onReceiveDownloadAccompanyMessage:(AccompanyDownloadMessage *)message.content];
  111. }
  112. else if ([message.content isKindOfClass:[AccompanyDownloadCallbackMessage class]]) {
  113. needHold = YES;
  114. }
  115. return needHold;
  116. }
  117. #pragma mark - HTTP
  118. - (void)joinClassroom:(NSString *)roomId
  119. userName:(NSString *)userName
  120. isAudience:(BOOL)audience
  121. success:(void (^)(Classroom * _Nonnull))successBlock
  122. error:(void (^)(ErrorCode, NSString * _Nonnull))errorBlock {
  123. if (roomId.length == 0 || userName.length == 0) {
  124. [self callbackFailureDescription:ErrorCodeParameterError];
  125. return;
  126. }
  127. [KSNetworkingManager roomJoinRequest:KS_POST roomId:roomId success:^(NSDictionary * _Nonnull dic) {
  128. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  129. Classroom *room = [Classroom classroomFromJson:[dic dictionaryValueForKey:@"data"]];
  130. self.currentRoom = room;
  131. if (successBlock) {
  132. dispatch_main_async_safe(^{
  133. successBlock(room);
  134. })
  135. }
  136. }
  137. else {
  138. errorBlock([dic integerValueForKey:@"code"], MESSAGEKEY);
  139. }
  140. } faliure:^(NSError * _Nonnull error) {
  141. if (errorBlock) {
  142. dispatch_main_async_safe(^{
  143. errorBlock(error.code, @"加入房间失败");
  144. })
  145. }
  146. }];
  147. }
  148. - (void)joinRoomFailerNotify {
  149. if (![self checkWhetherInRoom]) {
  150. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  151. [self.classroomDelegate roomDidLeave];
  152. }
  153. return;
  154. }
  155. [KSNetworkingManager joinRoomFailureRequest:KS_POST roomId:self.currentRoom.roomId success:^(NSDictionary * _Nonnull dic) {
  156. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  157. NSLog(@"------ 通知成功");
  158. }
  159. else {
  160. NSLog(@"------ 通知失败");
  161. }
  162. } faliure:^(NSError * _Nonnull error) {
  163. NSLog(@"------ 通知失败");
  164. }];
  165. }
  166. - (void)leaveClassroom {
  167. if (![self checkWhetherInRoom]) {
  168. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  169. [self.classroomDelegate roomDidLeave];
  170. }
  171. return;
  172. }
  173. NSLog(@"leave classroom start");
  174. [KSNetworkingManager roomLeaveRequest:KS_POST roomId:self.currentRoom.roomId success:^(NSDictionary * _Nonnull dic) {
  175. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  176. dispatch_main_async_safe(^{
  177. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  178. [self.classroomDelegate roomDidLeave];
  179. }
  180. });
  181. }
  182. else {
  183. dispatch_main_async_safe(^{
  184. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  185. [self.classroomDelegate roomDidLeave];
  186. }
  187. });
  188. NSLog(@"退出失败:%@",MESSAGEKEY);
  189. }
  190. } faliure:^(NSError * _Nonnull error) {
  191. dispatch_main_async_safe(^{
  192. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  193. [self.classroomDelegate roomDidLeave];
  194. }
  195. });
  196. NSLog(@"退出失败");
  197. }];
  198. }
  199. // 下载伴奏完成回调
  200. - (void)adjustAccompanySongNotifer:(NSString *)songId status:(BOOL)status {
  201. if (![self checkWhetherInRoom]) {
  202. [self callbackFailureDescription:ErrorCodeUserNotExistInRoom];
  203. return;
  204. }
  205. NSString *statusString = status == YES ? @"1" : @"2";
  206. [KSNetworkingManager musicSheetDownNotifyRequest:KS_POST roomId:self.currentRoom.roomId status:statusString accompanimentId:songId success:^(NSDictionary * _Nonnull dic) {
  207. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  208. }
  209. else {
  210. [self callbackFailureDescription:ErrorCodeOther];
  211. }
  212. } faliure:^(NSError * _Nonnull error) {
  213. [self callbackFailureDescription:ErrorCodeOther];
  214. }];
  215. }
  216. #pragma mark 操作当前用户设备状态,仅老师/学员有权限
  217. - (void)enableDevice:(BOOL)enable
  218. withType:(DeviceType)type {
  219. if (![self checkWhetherInRoom]) {
  220. [self callbackFailureDescription:ErrorCodeUserNotExistInRoom];
  221. return;
  222. }
  223. if (type == DeviceTypeHandup) {
  224. if (self.currentRoom.currentDisplayType == DisplayTypeStudent && [self.currentRoom.currentDisplayURI isEqualToString:UserDefault(UIDKey)]) {
  225. return;
  226. }
  227. }
  228. NSString *deviceType = [self getDeviceTypeDesc:type];
  229. [KSNetworkingManager roomDeviceSync:KS_POST deviceType:deviceType roomId:self.currentRoom.roomId enable:enable success:^(NSDictionary * _Nonnull dic) {
  230. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  231. if (type == DeviceTypeMicrophone) {
  232. [self.currentRoom updateMember:self.currentRoom.currentMember.userId forMicrophone:enable];
  233. } else if (type == DeviceTypeCamera) {
  234. [self.currentRoom updateMember:self.currentRoom.currentMember.userId forCamera:enable];
  235. }
  236. else if (type == DeviceTypeMusicMode) {
  237. [self.currentRoom updateMember:self.currentRoom.currentMember.userId forMusicMode:enable];
  238. }
  239. }
  240. else {
  241. [self callbackFailureDescription:ErrorCodeOther];
  242. }
  243. } faliure:^(NSError * _Nonnull error) {
  244. [self callbackFailureDescription:ErrorCodeOther];
  245. }];
  246. }
  247. - (void)approveEnableDevice:(DeviceType)type {
  248. if (![self checkWhetherInRoom]) {
  249. [self callbackFailureDescription:ErrorCodeUserNotExistInRoom];
  250. return;
  251. }
  252. NSString *deviceType = [self getDeviceTypeDesc:type];
  253. [KSNetworkingManager deviceApprove:KS_POST deviceType:deviceType roomId:self.currentRoom.roomId success:^(NSDictionary * _Nonnull dic) {
  254. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  255. }
  256. else {
  257. [self callbackFailureDescription:ErrorCodeOther];
  258. }
  259. } faliure:^(NSError * _Nonnull error) {
  260. [self callbackFailureDescription:ErrorCodeOther];
  261. }];
  262. }
  263. - (void)rejectEnableDevice:(DeviceType)type {
  264. if (![self checkWhetherInRoom]) {
  265. [self callbackFailureDescription:ErrorCodeUserNotExistInRoom];
  266. return;
  267. }
  268. NSString *deviceType = [self getDeviceTypeDesc:type];
  269. [KSNetworkingManager deviceReject:KS_POST deviceType:deviceType roomId:self.currentRoom.roomId success:^(NSDictionary * _Nonnull dic) {
  270. if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
  271. }
  272. else {
  273. [self callbackFailureDescription:ErrorCodeOther];
  274. }
  275. } faliure:^(NSError * _Nonnull error) {
  276. [self callbackFailureDescription:ErrorCodeOther];
  277. }];
  278. }
  279. #pragma mark - Util
  280. - (NSString *)getDeviceTypeDesc:(DeviceType)type {
  281. switch (type) {
  282. case DeviceTypeCamera:
  283. return @"CAMERA";
  284. case DeviceTypeMicrophone:
  285. return @"MICROPHONE";
  286. case DeviceTypeMusicMode:
  287. return @"MUSIC_MODE";
  288. case DeviceTypeHandup:
  289. return @"HAND_UP";
  290. case DeviceTypeExamSong:
  291. return @"EXAM_SONG";
  292. case DeviceTypeMusicScore:
  293. return @"MUSIC_SHEET";
  294. case DeviceTypeAccompany:
  295. return @"ACCOMPANIMENT";
  296. default:
  297. return @"";
  298. }
  299. }
  300. #pragma mark - Helper
  301. - (BOOL)checkWhetherInRoom {
  302. return self.currentRoom.roomId.length > 0;
  303. }
  304. - (void)callbackFailureDescription:(ErrorCode)code {
  305. dispatch_main_async_safe(^{
  306. if ([self.classroomDelegate respondsToSelector:@selector(errorDidOccur:)]) {
  307. [self.classroomDelegate errorDidOccur:code];
  308. }
  309. });
  310. }
  311. - (void)onReceiveCommandMessage:(MemberChangeMessage *)msg{
  312. dispatch_main_async_safe(^{
  313. if(msg.action == MemberChangeActionJoin) {
  314. if([self.classroomDelegate respondsToSelector:@selector(memberDidJoin:)]) {
  315. RoomMember *mem = [[RoomMember alloc] init];
  316. mem.userId = msg.userId;
  317. mem.name = msg.userName;
  318. mem.role = (Role)msg.role;
  319. mem.joinTime = msg.timestamp;
  320. mem.cameraEnable = YES;
  321. mem.microphoneEnable = YES;
  322. mem.headUrl = msg.avatar;
  323. if ([self.currentRoom addMemeber:mem]) {
  324. [self.classroomDelegate memberDidJoin:mem];
  325. }
  326. }
  327. }else if(msg.action == MemberChangeActionLeave){
  328. if([self.classroomDelegate respondsToSelector:@selector(memberDidLeave:)]) {
  329. RoomMember *mem = [[RoomMember alloc] init];
  330. mem.userId = msg.userId;
  331. mem.name = msg.userName;
  332. mem.role = (Role)msg.role;
  333. mem.joinTime = msg.timestamp;
  334. if([self.currentRoom removeMemeber:mem]) {
  335. [self.classroomDelegate memberDidLeave:mem];
  336. }
  337. }
  338. }else if(msg.action == MemberChangeActionKick) {
  339. if ([msg.userId isEqualToString:self.currentRoom.currentMember.userId]) {
  340. if ([self.classroomDelegate respondsToSelector:@selector(roomDidLeave)]) {
  341. [self.classroomDelegate roomDidLeave];
  342. }
  343. } else {
  344. RoomMember *mem = [self.currentRoom getMember:msg.userId];
  345. [self.currentRoom removeMemeber:mem];
  346. if([self.classroomDelegate respondsToSelector:@selector(memberDidKick:)]) {
  347. [self.classroomDelegate memberDidKick:mem];
  348. }
  349. }
  350. }
  351. });
  352. }
  353. - (void)onReceiveWhiteboardMessage:(WhiteboardMessage *)msg{
  354. dispatch_main_async_safe(^{
  355. if(WhiteboardActionCreate == msg.action) {
  356. if([self.classroomDelegate respondsToSelector:@selector(whiteboardDidCreate:)]) {
  357. Whiteboard *wBoard = [[Whiteboard alloc] init];
  358. wBoard.boardId = msg.whiteboardId;
  359. wBoard.name = msg.whiteboardName;
  360. [self.classroomDelegate whiteboardDidCreate:wBoard];
  361. }
  362. }else if (WhiteboardActionDelete == msg.action) {
  363. if([self.classroomDelegate respondsToSelector:@selector(whiteboardDidDelete:)]) {
  364. Whiteboard *wBoard = [[Whiteboard alloc] init];
  365. wBoard.boardId = msg.whiteboardId;
  366. wBoard.name = msg.whiteboardName;
  367. [self.classroomDelegate whiteboardDidDelete:wBoard];
  368. }
  369. }
  370. });
  371. }
  372. - (void)onReceiveDeviceMessage:(DeviceMessage *)msg withSenderId:(NSString *)senderId{
  373. dispatch_main_async_safe(^{
  374. if (msg.type == DeviceTypeCamera) {
  375. [self.currentRoom updateMember:msg.userId forCamera:msg.enable];
  376. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  377. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeCamera forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  378. }
  379. } else if (msg.type == DeviceTypeMicrophone) {
  380. [self.currentRoom updateMember:msg.userId forMicrophone:msg.enable];
  381. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  382. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeMicrophone forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  383. }
  384. }
  385. else if (msg.type == DeviceTypeMusicMode) {
  386. [self.currentRoom updateMember:msg.userId forMusicMode:msg.enable];
  387. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  388. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeMusicMode forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  389. }
  390. }
  391. else if (msg.type == DeviceTypeHandup) {
  392. [self.currentRoom updateMember:msg.userId forHandsUp:msg.enable];
  393. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  394. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeHandup forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  395. }
  396. }
  397. else if (msg.type == DeviceTypeExamSong) {
  398. [self.currentRoom updateMember:msg.userId forExamSong:msg.enable];
  399. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  400. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeExamSong forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  401. }
  402. }
  403. else if (msg.type == DeviceTypeAccompany) { // 伴奏
  404. self.currentRoom.soundVolume = msg.soundVolume;
  405. [self.currentRoom updateMember:msg.userId forAccompany:msg.enable songId:msg.songId];
  406. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  407. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeAccompany forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  408. }
  409. }
  410. else if (msg.type == DeviceTypeMusicScore) { // 原声
  411. self.currentRoom.soundVolume = msg.soundVolume;
  412. [self.currentRoom updateMember:msg.userId forMusicScore:msg.enable songId:msg.songId];
  413. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidEnable:type:forUser:operator:)]) {
  414. [self.classroomDelegate deviceDidEnable:msg.enable type:DeviceTypeMusicScore forUser:[self.currentRoom getMember:msg.userId] operator:senderId];
  415. }
  416. }
  417. });
  418. }
  419. - (void)onReceiveDisplayCommandMessage:(DisplayCommandMessage *)msg{
  420. NSLog(@"%@--------",msg.display);
  421. dispatch_main_async_safe(^{
  422. [self.currentRoom updateDisplayUri:msg.display];
  423. DisplayType type = self.currentRoom.currentDisplayType;
  424. if (type == DisplayTeacher) {
  425. NSLog(@"------- DisplayTeacher");
  426. if ([self.classroomDelegate respondsToSelector:@selector(teacherDidDisplay)]) {
  427. [self.classroomDelegate teacherDidDisplay];
  428. }
  429. } else if (type == DisplayWhiteboard) {
  430. if ([self.classroomDelegate respondsToSelector:@selector(whiteboardDidDisplay:)]) {
  431. [self.classroomDelegate whiteboardDidDisplay:self.currentRoom.currentDisplayURI];
  432. }
  433. } else if (type == DisplaySharedScreen) {
  434. if ([self.classroomDelegate respondsToSelector:@selector(sharedScreenDidDisplay:)]) {
  435. [self.classroomDelegate sharedScreenDidDisplay:self.currentRoom.currentDisplayURI];
  436. }
  437. } else if (type == DisplayNone) {
  438. if ([self.classroomDelegate respondsToSelector:@selector(noneDidDisplay)]) {
  439. [self.classroomDelegate noneDidDisplay];
  440. }
  441. }
  442. else if (type == DisplayTypeStudent) {
  443. if ([self.classroomDelegate respondsToSelector:@selector(studentDidDisplay:)]) {
  444. [self.classroomDelegate studentDidDisplay:self.currentRoom.currentDisplayURI];
  445. }
  446. }
  447. });
  448. }
  449. - (void)onReceiveApplySpeechMessage:(ApplySpeechMessage *)msg {
  450. }
  451. - (void)onReceiveSpeechResultMessage:(ApplySpeechResultMessage *)msg {
  452. }
  453. - (void)onReceiveTurnPageMessage:(TurnPageMessage *)msg {
  454. }
  455. - (void)onReceiveRoleChangedMessage:(RoleChangedMessage *)msg {
  456. }
  457. - (void)onReceiveAssistantTransferMessage:(AssistantTransferMessage *)msg {
  458. }
  459. - (void)onReceiveTicketExpiredMessage:(TicketExpiredMessage *)msg {
  460. }
  461. - (void)onReceiveInviteUpgradeMessage:(InviteUpgradeMessage *)msg {
  462. }
  463. - (void)onReceiveControlDeviceNotifyMessage:(ControlDeviceNotifyMessage *)msg {
  464. dispatch_main_async_safe(^{
  465. if (msg.action == ControlDeviceActionInvite) {
  466. if ([self.classroomDelegate respondsToSelector:@selector(deviceDidInviteEnable:ticket:)]) {
  467. [self.classroomDelegate deviceDidInviteEnable:msg.type ticket:msg.ticket];
  468. }
  469. } else if (msg.action == ControlDeviceActionApprove) {
  470. } else if (msg.action == ControlDeviceActionReject) {
  471. }
  472. });
  473. }
  474. - (void)onReceiveNodePlayMessage:(NodePlayMessage *)msg {
  475. dispatch_main_async_safe(^{
  476. if (self.currentRoom.currentMember.role == RoleStudent) {
  477. if ([self.classroomDelegate respondsToSelector:@selector(playNodeAction:userId:rate:beatType:volume:)]) {
  478. [self.classroomDelegate playNodeAction:msg.enable userId:msg.userId rate:msg.rate beatType:msg.customType volume:msg.playVolume];
  479. }
  480. }
  481. });
  482. }
  483. // 通知下载曲目
  484. - (void)onReceiveDownloadAccompanyMessage:(AccompanyDownloadMessage *)msg {
  485. // 通知下载曲目
  486. dispatch_main_async_safe(^{
  487. NSString *songUrl = msg.url;
  488. NSString *accompanyUrl = msg.mp3Url;
  489. BOOL isEmpty = [NSString isEmptyString:songUrl] && [NSString isEmptyString:accompanyUrl];
  490. if (self.currentRoom.currentMember.role == RoleStudent) {
  491. if ([self.classroomDelegate respondsToSelector:@selector(accompanyDownloadCallback:accompanyUrl:songId:)] && !isEmpty) {
  492. // 记录曲目
  493. ClassSongMessage *songMessage = [[ClassSongMessage alloc] init];
  494. songMessage.musicScoreAccompanimentId = msg.examSongId.intValue;
  495. songMessage.speed = msg.speed;
  496. songMessage.url = msg.url;
  497. songMessage.mp3Url = msg.mp3Url;
  498. [self.currentRoom updateMemberAccompamy:self.currentRoom.currentMember.userId songMessage:songMessage];
  499. [self.classroomDelegate accompanyDownloadCallback:songUrl accompanyUrl:accompanyUrl songId:msg.examSongId];
  500. }
  501. }
  502. });
  503. }
  504. @end