YOUPAILZChatRoomManager.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. //
  2. // YOUPAILZChatRoomManager.m
  3. // VQU
  4. //
  5. // Created by CY on 2021/10/25.
  6. // Copyright © 2021 MS. All rights reserved.
  7. //
  8. #import "YOUPAILZChatRoomManager.h"
  9. #import "YOUPAILZMusicModel.h"
  10. static YOUPAILZChatRoomManager *_manager;
  11. static dispatch_once_t _onceToken;
  12. @interface YOUPAILZChatRoomManager () <AgoraRtcEngineDelegate,NIMChatroomManagerDelegate,NIMChatManagerDelegate>
  13. @property (nonatomic, strong) NSURLSessionDataTask *sessionDataTask;
  14. @end
  15. @implementation YOUPAILZChatRoomManager
  16. + (instancetype)shareManager{
  17. dispatch_once(&_onceToken, ^{
  18. _manager = [[YOUPAILZChatRoomManager alloc] init];
  19. });
  20. return _manager;
  21. }
  22. + (void)clear{
  23. [_manager youpaifcloseChatRoom];
  24. [_manager.chatroomWindow removeFromSuperview];
  25. _manager = nil;
  26. _onceToken = 0;
  27. }
  28. - (instancetype)init{
  29. if (self = [super init]) {
  30. [self youpaifinitUI];
  31. }
  32. return self;
  33. }
  34. - (void)youpaifinitUI{
  35. YOUPAILZChatRoomWindow *chatroomWindow = [[YOUPAILZChatRoomWindow alloc] init];
  36. chatroomWindow.frame = CGRectMake(KScreenWidth - 16.0f - 64.0f, KScreenHeight - TabbarHeight - 100.0f - 27.0f - 64.0f, 64.0f, 64.0f);
  37. @weakify(self);
  38. [chatroomWindow setYoupaipcloseBlock:^{
  39. @strongify(self);
  40. [self youpaifcloseChatRoom];
  41. }];
  42. [chatroomWindow setShowChatRoomBlock:^{
  43. @strongify(self);
  44. [self youpaifshowChatRoom];
  45. }];
  46. [[UIApplication sharedApplication].keyWindow addSubview:chatroomWindow];
  47. self.chatroomWindow = chatroomWindow;
  48. }
  49. - (void)youpaifshowChatRoom{
  50. NSMutableArray *vcs = [[LCTools getContainNavigationControllerCurrentVC].navigationController.viewControllers mutableCopy];
  51. if ([vcs containsObject:self.chatroomController]) {
  52. [[LCTools getContainNavigationControllerCurrentVC].navigationController popToViewController:self.chatroomController animated:YES];
  53. }else{
  54. [vcs addObject:self.chatroomController];
  55. [[LCTools getContainNavigationControllerCurrentVC].navigationController setViewControllers:vcs animated:YES];
  56. }
  57. }
  58. - (void)youpaifinitializeAgoraEngine{
  59. self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:AgoraID delegate:self];
  60. [self.agoraKit setAudioProfile:AgoraAudioProfileMusicHighQuality scenario:AgoraAudioScenarioGameStreaming];
  61. //设置频道场景
  62. [self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
  63. //设置用户角色
  64. [self.agoraKit setClientRole:AgoraClientRoleAudience];
  65. // 将录音音量设置
  66. [self.agoraKit adjustRecordingSignalVolume:100];
  67. // 将本地播放的所有远端用户音量
  68. [self.agoraKit adjustPlaybackSignalVolume:100];
  69. // 启用音频音量指示
  70. // [self.agoraKit enableAudioVolumeIndication:2000 smooth:3 report_vad:YES];
  71. //启用与Agora Web SDK的互操作性。
  72. [self.agoraKit enableWebSdkInteroperability:YES];
  73. }
  74. /// 设置角色类型
  75. - (void)youpaifsetClientRole:(AgoraClientRole)youpaifclientRole{
  76. [self.agoraKit setClientRole:youpaifclientRole];
  77. }
  78. /// 是否关闭麦克风
  79. - (void)youpaifmuteLocalAudioStream:(BOOL)mute{
  80. [self.agoraKit muteLocalAudioStream:mute];
  81. }
  82. /// 是否禁用远端声音
  83. - (void)youpaifmuteAllRemoteAudioStreams:(BOOL)mute{
  84. [self.agoraKit muteAllRemoteAudioStreams:mute];
  85. }
  86. - (void)youpaifjoinChannelById:(NSString *)channelId uid:(NSInteger)uid{
  87. @weakify(self);
  88. [self.agoraKit joinChannelByToken:nil channelId:channelId info:nil uid:uid joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) {
  89. @strongify(self);
  90. //检查扬声器是否已启用
  91. if([self.agoraKit isSpeakerphoneEnabled]){
  92. //设置扬声器
  93. [self.agoraKit setEnableSpeakerphone:YES];
  94. }
  95. // 设置不自动锁屏
  96. [UIApplication sharedApplication].idleTimerDisabled = YES;
  97. }];
  98. }
  99. - (void)youpaifjoinChatRoomById:(NSString *)roomId isComeinRoomHide:(NSInteger)isComeinRoomHide completion:(NIMChatroomEnterHandler)completion{
  100. NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init];
  101. request.roomId = roomId;
  102. NSDictionary *roomNotifyExt = @{
  103. @"is_comein_room_hide":@(isComeinRoomHide)
  104. };
  105. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:roomNotifyExt options:0 error:0];
  106. NSString *dataStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  107. request.roomNotifyExt = dataStr;
  108. @weakify(self);
  109. [[[NIMSDK sharedSDK] chatroomManager] enterChatroom:request
  110. completion:^(NSError *error,NIMChatroom *chatroom,NIMChatroomMember *me) {
  111. @strongify(self);
  112. if (error == nil){ // 加入成功
  113. /// 监听聊天室连接变化
  114. [[NIMSDK sharedSDK].chatroomManager addDelegate:self];
  115. /// 添加聊天委托
  116. [[NIMSDK sharedSDK].chatManager addDelegate:self];
  117. if (completion != nil) {
  118. completion(error,chatroom,me);
  119. }
  120. }else{ // 加入失败
  121. NSString *toast = [NSString stringWithFormat:@"%@ code:%zd",
  122. @"进入失败",
  123. error.code];
  124. }
  125. }];
  126. }
  127. - (void)youpaifleaveChannel{
  128. [self.agoraKit leaveChannel:nil];
  129. @weakify(self);
  130. [[[NIMSDK sharedSDK] chatroomManager] exitChatroom:self.chatroomModel.youpaiproom_id completion:^(NSError * _Nullable error) {
  131. @strongify(self);
  132. [[NIMSDK sharedSDK].chatroomManager removeDelegate:self];
  133. [[NIMSDK sharedSDK].chatManager removeDelegate:self];
  134. }];
  135. NSMutableArray *vcs = [[LCTools getContainNavigationControllerCurrentVC].navigationController.viewControllers mutableCopy];
  136. if ([vcs containsObject:self.chatroomController]) {
  137. [vcs removeObject:self.chatroomController];
  138. [[LCTools getContainNavigationControllerCurrentVC].navigationController setViewControllers:vcs];
  139. }
  140. [self.chatroomController.youpaiplyrieView youpaifclose];
  141. self.chatroomController = nil;
  142. }
  143. - (void)youpaifcloseChatRoom{
  144. if (self.chatroomModel.youpaiproom_id.length != 0) {
  145. @weakify(self);
  146. [LCHttpHelper requestWithURLString:OutTalk parameters:@{@"room_id":self.chatroomModel.youpaiproom_id} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) {
  147. @strongify(self);
  148. self.chatroomWindow.hidden = YES;
  149. } failure:^(NSError *error) {
  150. }];
  151. }
  152. [self youpaifleaveChannel];
  153. }
  154. #pragma mark - AgoraRtcEngineDelegate
  155. // 获取瞬时说话音量最高的几个用户(即说话者)的用户 ID、他们的音量及本地用户是否在说话。
  156. // @param speakers 为一个数组,包含说话者的用户 ID 、音量及本地用户人声状态。音量的取值范围为 [0, 255]。
  157. // @param totalVolume 指混音后频道内的总音量,取值范围为 [0, 255]。
  158. - (void)rtcEngine:(AgoraRtcEngineKit *)engine reportAudioVolumeIndicationOfSpeakers:(NSArray<AgoraRtcAudioVolumeInfo *> *)speakers totalVolume:(NSInteger)totalVolume{
  159. if (self.reportAudioVolumeIndicationOfSpeakersBlock != nil) {
  160. self.reportAudioVolumeIndicationOfSpeakersBlock(engine, speakers, totalVolume);
  161. }
  162. }
  163. /// 本地音乐文件播放已结束回调
  164. - (void)rtcEngineLocalAudioMixingDidFinish:(AgoraRtcEngineKit *)engine{
  165. [[YOUPAILZMusicManager shareManager] youpaifnext];
  166. }
  167. /// 本地用户的音乐文件播放状态已改变回调
  168. //- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine localAudioMixingStateDidChanged:(AgoraAudioMixingStateCode)state errorCode:(AgoraAudioMixingErrorCode)errorCode{
  169. // switch (state) {
  170. // case AgoraAudioMixingStateFailed:
  171. // [[YOUPAILZMusicManager shareManager] youpaifnext];
  172. // break;
  173. //
  174. // default:
  175. // break;
  176. // }
  177. //}
  178. #pragma mark - NIMChatroomManagerDelegate
  179. /// 被踢回调
  180. - (void)chatroomBeKicked:(NIMChatroomBeKickedResult *)result{
  181. NSLog(@"被踢了");
  182. }
  183. #pragma mark - NIMChatManagerDelegate
  184. /// 发送消息完成回调
  185. - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(nullable NSError *)error{
  186. NIMSession *session = message.session;
  187. if (![session.sessionId isEqual:self.chatroomModel.youpaiproom_id]){
  188. return;
  189. }
  190. if (self.sendMessageSuccessBlock != nil) {
  191. self.sendMessageSuccessBlock(message, error);
  192. }
  193. }
  194. /// 收到消息回调
  195. - (void)onRecvMessages:(NSArray<NIMMessage *> *)messages{
  196. NIMMessage *message = messages.firstObject;
  197. NIMSession *session = message.session;
  198. if (![session.sessionId isEqual:self.chatroomModel.youpaiproom_id] || !messages.count){
  199. return;
  200. }
  201. if (self.onRecvMessagesBlock != nil) {
  202. self.onRecvMessagesBlock(messages);
  203. }
  204. }
  205. - (void)setChatroomModel:(YOUPAILZChatRoomModel *)chatroomModel{
  206. _chatroomModel = chatroomModel;
  207. self.chatroomWindow.youpaipchatroomModel = chatroomModel;
  208. }
  209. /// 获取音乐信息
  210. - (void)youpaifloadMusicInfoWithModel:(YOUPAILZMusicListItemModel *)model{
  211. @weakify(self);
  212. if (self.sessionDataTask != nil) {
  213. [self.sessionDataTask cancel];
  214. }
  215. self.sessionDataTask = [LCHttpHelper requestWithURLString:GetSong parameters:@{@"songCode":model.youpaipsongCode,@"duration":model.youpaipduration} needToken:YES type:HttpRequestTypePost success:^(id responseObject) {
  216. @strongify(self);
  217. NSDictionary* dict = (NSDictionary*)responseObject;
  218. NSInteger code = [[dict objectForKey:@"code"] integerValue];
  219. if (code == 0) {
  220. // NSLog(@"-----%@",[dict objectForKey:@"data"]);
  221. YOUPAILZMusicModel *youpaipmusicModel = [YOUPAILZMusicModel mj_objectWithKeyValues:[dict objectForKey:@"data"]];
  222. youpaipmusicModel.youpaipname = model.youpaipname;
  223. if (model.youpaipposter.length != 0) {
  224. youpaipmusicModel.youpaipposter = model.youpaipposter;
  225. }
  226. if (youpaipmusicModel.youpaiplyric.length != 0) {
  227. dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  228. dispatch_async(queue, ^{
  229. NSString *lrcStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:youpaipmusicModel.youpaiplyric] encoding:NSUTF8StringEncoding error:nil];
  230. [youpaipmusicModel youpaifparseLrc:lrcStr];
  231. dispatch_async(dispatch_get_main_queue(), ^{
  232. @strongify(self);
  233. [[NSNotificationCenter defaultCenter] postNotificationName:@"VQUMusicInfoChangeNotification" object:youpaipmusicModel userInfo:nil];
  234. [self youpaifstartPlayMusicWithPath:youpaipmusicModel.youpaipplayUrl];
  235. });
  236. });
  237. }else{
  238. youpaipmusicModel.youpaipwordArray = @[youpaipmusicModel.youpaipname,@""].mutableCopy;
  239. [[NSNotificationCenter defaultCenter] postNotificationName:@"VQUMusicInfoChangeNotification" object:youpaipmusicModel userInfo:nil];
  240. [self youpaifstartPlayMusicWithPath:youpaipmusicModel.youpaipplayUrl];
  241. }
  242. }else{
  243. [ZCHUDHelper showTitle:[dict objectForKey:@"message"]];
  244. }
  245. self.sessionDataTask = nil;
  246. } failure:^(NSError *error) {
  247. // [ZCHUDHelper showTitle:error.localizedDescription];
  248. self.sessionDataTask = nil;
  249. }];
  250. }
  251. /// 播放音乐
  252. - (void)youpaifstartPlayMusicWithPath:(NSString *)path{
  253. // 设置是否只在本地播放音乐文件。true 表示只有本地用户能听到音乐;false 表示本地用户和远端用户都能听到音乐。
  254. BOOL youpaiploopback = NO;
  255. // 设置是否用音乐文件替换麦克风采集的音频。true 表示用户只能听到音乐;false 表示用户可以听到音乐和麦克风采集的音频。
  256. BOOL youpaipreplace = NO;
  257. // 设置音乐文件的播放次数。1 表示播放 1 次。
  258. NSInteger cycle = 1;
  259. // [self.agoraKit startAudioMixing:path loopback:youpaiploopback replace:youpaipreplace cycle:cycle startPos:0];
  260. // 调节音乐文件的播放音量
  261. [self.agoraKit adjustAudioMixingVolume:30];
  262. }
  263. /// 退出音乐
  264. - (void)youpaifStopPlayMusic{
  265. [self.chatroomController.youpaiplyrieView youpaifclose];
  266. [self.agoraKit stopAudioMixing];
  267. }
  268. @end