// // YOUPAILZChatRoomManager.m // VQU // // Created by CY on 2021/10/25. // Copyright © 2021 MS. All rights reserved. // #import "YOUPAILZChatRoomManager.h" #import "YOUPAILZMusicModel.h" static YOUPAILZChatRoomManager *_manager; static dispatch_once_t _onceToken; @interface YOUPAILZChatRoomManager () @property (nonatomic, strong) NSURLSessionDataTask *sessionDataTask; @end @implementation YOUPAILZChatRoomManager + (instancetype)shareManager{ dispatch_once(&_onceToken, ^{ _manager = [[YOUPAILZChatRoomManager alloc] init]; }); return _manager; } + (void)clear{ [_manager youpaifcloseChatRoom]; [_manager.chatroomWindow removeFromSuperview]; _manager = nil; _onceToken = 0; } - (instancetype)init{ if (self = [super init]) { [self youpaifinitUI]; } return self; } - (void)youpaifinitUI{ YOUPAILZChatRoomWindow *chatroomWindow = [[YOUPAILZChatRoomWindow alloc] init]; chatroomWindow.frame = CGRectMake(KScreenWidth - 16.0f - 64.0f, KScreenHeight - TabbarHeight - 100.0f - 27.0f - 64.0f, 64.0f, 64.0f); @weakify(self); [chatroomWindow setYoupaipcloseBlock:^{ @strongify(self); [self youpaifcloseChatRoom]; }]; [chatroomWindow setShowChatRoomBlock:^{ @strongify(self); [self youpaifshowChatRoom]; }]; [[UIApplication sharedApplication].keyWindow addSubview:chatroomWindow]; self.chatroomWindow = chatroomWindow; } - (void)youpaifshowChatRoom{ NSMutableArray *vcs = [[LCTools getContainNavigationControllerCurrentVC].navigationController.viewControllers mutableCopy]; if ([vcs containsObject:self.chatroomController]) { [[LCTools getContainNavigationControllerCurrentVC].navigationController popToViewController:self.chatroomController animated:YES]; }else{ [vcs addObject:self.chatroomController]; [[LCTools getContainNavigationControllerCurrentVC].navigationController setViewControllers:vcs animated:YES]; } } - (void)youpaifinitializeAgoraEngine{ self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:AgoraID delegate:self]; [self.agoraKit setAudioProfile:AgoraAudioProfileMusicHighQuality scenario:AgoraAudioScenarioGameStreaming]; //设置频道场景 [self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting]; //设置用户角色 [self.agoraKit setClientRole:AgoraClientRoleAudience]; // 将录音音量设置 [self.agoraKit adjustRecordingSignalVolume:100]; // 将本地播放的所有远端用户音量 [self.agoraKit adjustPlaybackSignalVolume:100]; // 启用音频音量指示 // [self.agoraKit enableAudioVolumeIndication:2000 smooth:3 report_vad:YES]; //启用与Agora Web SDK的互操作性。 [self.agoraKit enableWebSdkInteroperability:YES]; } /// 设置角色类型 - (void)youpaifsetClientRole:(AgoraClientRole)youpaifclientRole{ [self.agoraKit setClientRole:youpaifclientRole]; } /// 是否关闭麦克风 - (void)youpaifmuteLocalAudioStream:(BOOL)mute{ [self.agoraKit muteLocalAudioStream:mute]; } /// 是否禁用远端声音 - (void)youpaifmuteAllRemoteAudioStreams:(BOOL)mute{ [self.agoraKit muteAllRemoteAudioStreams:mute]; } - (void)youpaifjoinChannelById:(NSString *)channelId uid:(NSInteger)uid{ @weakify(self); [self.agoraKit joinChannelByToken:nil channelId:channelId info:nil uid:uid joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) { @strongify(self); //检查扬声器是否已启用 if([self.agoraKit isSpeakerphoneEnabled]){ //设置扬声器 [self.agoraKit setEnableSpeakerphone:YES]; } // 设置不自动锁屏 [UIApplication sharedApplication].idleTimerDisabled = YES; }]; } - (void)youpaifjoinChatRoomById:(NSString *)roomId isComeinRoomHide:(NSInteger)isComeinRoomHide completion:(NIMChatroomEnterHandler)completion{ NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init]; request.roomId = roomId; NSDictionary *roomNotifyExt = @{ @"is_comein_room_hide":@(isComeinRoomHide) }; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:roomNotifyExt options:0 error:0]; NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; request.roomNotifyExt = dataStr; @weakify(self); [[[NIMSDK sharedSDK] chatroomManager] enterChatroom:request completion:^(NSError *error,NIMChatroom *chatroom,NIMChatroomMember *me) { @strongify(self); if (error == nil){ // 加入成功 /// 监听聊天室连接变化 [[NIMSDK sharedSDK].chatroomManager addDelegate:self]; /// 添加聊天委托 [[NIMSDK sharedSDK].chatManager addDelegate:self]; if (completion != nil) { completion(error,chatroom,me); } }else{ // 加入失败 NSString *toast = [NSString stringWithFormat:@"%@ code:%zd", @"进入失败", error.code]; } }]; } - (void)youpaifleaveChannel{ [self.agoraKit leaveChannel:nil]; @weakify(self); [[[NIMSDK sharedSDK] chatroomManager] exitChatroom:self.chatroomModel.youpaiproom_id completion:^(NSError * _Nullable error) { @strongify(self); [[NIMSDK sharedSDK].chatroomManager removeDelegate:self]; [[NIMSDK sharedSDK].chatManager removeDelegate:self]; }]; NSMutableArray *vcs = [[LCTools getContainNavigationControllerCurrentVC].navigationController.viewControllers mutableCopy]; if ([vcs containsObject:self.chatroomController]) { [vcs removeObject:self.chatroomController]; [[LCTools getContainNavigationControllerCurrentVC].navigationController setViewControllers:vcs]; } [self.chatroomController.youpaiplyrieView youpaifclose]; self.chatroomController = nil; } - (void)youpaifcloseChatRoom{ if (self.chatroomModel.youpaiproom_id.length != 0) { @weakify(self); [LCHttpHelper requestWithURLString:OutTalk parameters:@{@"room_id":self.chatroomModel.youpaiproom_id} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { @strongify(self); self.chatroomWindow.hidden = YES; } failure:^(NSError *error) { }]; } [self youpaifleaveChannel]; } #pragma mark - AgoraRtcEngineDelegate // 获取瞬时说话音量最高的几个用户(即说话者)的用户 ID、他们的音量及本地用户是否在说话。 // @param speakers 为一个数组,包含说话者的用户 ID 、音量及本地用户人声状态。音量的取值范围为 [0, 255]。 // @param totalVolume 指混音后频道内的总音量,取值范围为 [0, 255]。 - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray *)speakers totalVolume:(NSInteger)totalVolume{ if (self.reportAudioVolumeIndicationOfSpeakersBlock != nil) { self.reportAudioVolumeIndicationOfSpeakersBlock(engine, speakers, totalVolume); } } /// 本地音乐文件播放已结束回调 - (void)rtcEngineLocalAudioMixingDidFinish:(AgoraRtcEngineKit *)engine{ [[YOUPAILZMusicManager shareManager] youpaifnext]; } /// 本地用户的音乐文件播放状态已改变回调 //- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine localAudioMixingStateDidChanged:(AgoraAudioMixingStateCode)state errorCode:(AgoraAudioMixingErrorCode)errorCode{ // switch (state) { // case AgoraAudioMixingStateFailed: // [[YOUPAILZMusicManager shareManager] youpaifnext]; // break; // // default: // break; // } //} #pragma mark - NIMChatroomManagerDelegate /// 被踢回调 - (void)chatroomBeKicked:(NIMChatroomBeKickedResult *)result{ NSLog(@"被踢了"); } #pragma mark - NIMChatManagerDelegate /// 发送消息完成回调 - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(nullable NSError *)error{ NIMSession *session = message.session; if (![session.sessionId isEqual:self.chatroomModel.youpaiproom_id]){ return; } if (self.sendMessageSuccessBlock != nil) { self.sendMessageSuccessBlock(message, error); } } /// 收到消息回调 - (void)onRecvMessages:(NSArray *)messages{ NIMMessage *message = messages.firstObject; NIMSession *session = message.session; if (![session.sessionId isEqual:self.chatroomModel.youpaiproom_id] || !messages.count){ return; } if (self.onRecvMessagesBlock != nil) { self.onRecvMessagesBlock(messages); } } - (void)setChatroomModel:(YOUPAILZChatRoomModel *)chatroomModel{ _chatroomModel = chatroomModel; self.chatroomWindow.youpaipchatroomModel = chatroomModel; } /// 获取音乐信息 - (void)youpaifloadMusicInfoWithModel:(YOUPAILZMusicListItemModel *)model{ @weakify(self); if (self.sessionDataTask != nil) { [self.sessionDataTask cancel]; } self.sessionDataTask = [LCHttpHelper requestWithURLString:GetSong parameters:@{@"songCode":model.youpaipsongCode,@"duration":model.youpaipduration} needToken:YES type:HttpRequestTypePost success:^(id responseObject) { @strongify(self); NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code == 0) { // NSLog(@"-----%@",[dict objectForKey:@"data"]); YOUPAILZMusicModel *youpaipmusicModel = [YOUPAILZMusicModel mj_objectWithKeyValues:[dict objectForKey:@"data"]]; youpaipmusicModel.youpaipname = model.youpaipname; if (model.youpaipposter.length != 0) { youpaipmusicModel.youpaipposter = model.youpaipposter; } if (youpaipmusicModel.youpaiplyric.length != 0) { dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_async(queue, ^{ NSString *lrcStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:youpaipmusicModel.youpaiplyric] encoding:NSUTF8StringEncoding error:nil]; [youpaipmusicModel youpaifparseLrc:lrcStr]; dispatch_async(dispatch_get_main_queue(), ^{ @strongify(self); [[NSNotificationCenter defaultCenter] postNotificationName:@"VQUMusicInfoChangeNotification" object:youpaipmusicModel userInfo:nil]; [self youpaifstartPlayMusicWithPath:youpaipmusicModel.youpaipplayUrl]; }); }); }else{ youpaipmusicModel.youpaipwordArray = @[youpaipmusicModel.youpaipname,@""].mutableCopy; [[NSNotificationCenter defaultCenter] postNotificationName:@"VQUMusicInfoChangeNotification" object:youpaipmusicModel userInfo:nil]; [self youpaifstartPlayMusicWithPath:youpaipmusicModel.youpaipplayUrl]; } }else{ [ZCHUDHelper showTitle:[dict objectForKey:@"message"]]; } self.sessionDataTask = nil; } failure:^(NSError *error) { // [ZCHUDHelper showTitle:error.localizedDescription]; self.sessionDataTask = nil; }]; } /// 播放音乐 - (void)youpaifstartPlayMusicWithPath:(NSString *)path{ // 设置是否只在本地播放音乐文件。true 表示只有本地用户能听到音乐;false 表示本地用户和远端用户都能听到音乐。 BOOL youpaiploopback = NO; // 设置是否用音乐文件替换麦克风采集的音频。true 表示用户只能听到音乐;false 表示用户可以听到音乐和麦克风采集的音频。 BOOL youpaipreplace = NO; // 设置音乐文件的播放次数。1 表示播放 1 次。 NSInteger cycle = 1; // [self.agoraKit startAudioMixing:path loopback:youpaiploopback replace:youpaipreplace cycle:cycle startPos:0]; // 调节音乐文件的播放音量 [self.agoraKit adjustAudioMixingVolume:30]; } /// 退出音乐 - (void)youpaifStopPlayMusic{ [self.chatroomController.youpaiplyrieView youpaifclose]; [self.agoraKit stopAudioMixing]; } @end