// // AudioChatTool.m // BuguLive // // Created by Kylin on 2024/12/2. // Copyright © 2024 xfg. All rights reserved. // #import "AudioChatTool.h" #import @interface AudioChatTool () @property (nonatomic,assign) BOOL limitJoinRoom; @end @implementation AudioChatTool static dispatch_once_t onceToken; static AudioChatTool *_voiceRoomVC; + (instancetype)shareInstance{ dispatch_once(&onceToken, ^{ _voiceRoomVC = [[AudioChatTool alloc] init]; }); return _voiceRoomVC; } #pragma mark 进入房间 /**回到主线程跳转*/ - (void)audioGetMainPushVoiceRoomIsZhuDongCall:(BOOL)isZhuDongCall withFriendObj:(SFriendObj *)friendObj loadEndBlock:(void (^)(void))block { NSLog(@"要打开房间了。。。。。。。。。。。"); if (self.limitJoinRoom) { return; } self.limitJoinRoom = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.limitJoinRoom = NO; }); dispatch_async(dispatch_get_main_queue(), ^{ AudioChatViewController * voiceRoomVC = [AudioChatViewController shareVoiceRoomVC]; voiceRoomVC.mChatFriend = friendObj; voiceRoomVC.isZhuDongCall = isZhuDongCall; self.recordAudioChatViewController = voiceRoomVC; voiceRoomVC.hidesBottomBarWhenPushed = YES; UIWindow *window = [UIApplication sharedApplication].keyWindow; UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:voiceRoomVC]; nav.modalPresentationStyle = UIModalPresentationOverFullScreen; nav.modalTransitionStyle = UIModalTransitionStyleCoverVertical; nav.hidesBottomBarWhenPushed = YES; [window.rootViewController presentViewController:nav animated:YES completion:^{ NSLog(@"打开房间了。。。。。。。。。。。"); if (block) { block(); } }]; }); } #pragma mark 进入房间 /**回到主线程跳转*/ - (void)videoGetMainPushVoiceRoomIsZhuDongCall:(BOOL)isZhuDongCall withFriendObj:(SFriendObj *)friendObj loadEndBlock:(void (^)(void))block { NSLog(@"要打开房间了。。。。。。。。。。。"); if (self.limitJoinRoom) { return; } self.limitJoinRoom = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.limitJoinRoom = NO; }); dispatch_async(dispatch_get_main_queue(), ^{ AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; VideoChatVC * voiceRoomVC = [VideoChatVC shareVoiceRoomVC]; voiceRoomVC.mChatFriend = friendObj; voiceRoomVC.isZhuDongCall = isZhuDongCall; self.recordVideoChatVC = voiceRoomVC; voiceRoomVC.hidesBottomBarWhenPushed = YES; UIWindow *window = [UIApplication sharedApplication].keyWindow; UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:voiceRoomVC]; nav.modalPresentationStyle = UIModalPresentationOverFullScreen; nav.modalTransitionStyle = UIModalTransitionStyleCoverVertical; nav.hidesBottomBarWhenPushed = YES; [window.rootViewController presentViewController:nav animated:YES completion:^{ NSLog(@"打开房间了。。。。。。。。。。。"); if (block) { block(); } }]; }); } #pragma mark - 在线收到消息互动 - (void)receiveCallWithNotification:(NSNotification *)notifcation { SIMMsgObj *thatmsg = (SIMMsgObj *) notifcation.object; SFriendObj* mChatFriend = [[SFriendObj alloc]initWithUserId:thatmsg.mSenderId]; mChatFriend.mNick_name = thatmsg.mCoreTMsg.nickName; mChatFriend.mHead_image = thatmsg.mHeadImgUrl; // chattag.is_robot = thatmsg.is_robot; //不在通话中,忽略消息 if (AppDelegate.sharedAppDelegate.isInAudioVideoChatVc == NO && thatmsg.callAudioType > AudioChatType_call) { return; } if (thatmsg.mMsgType == MSG_PRIVATE_CallAudio) { //收到语音请求 if (thatmsg.callAudioType == AudioChatType_call) { if (AppDelegate.sharedAppDelegate.isEnterLiveVC || AppDelegate.sharedAppDelegate.isInAudioVideoChatVc) { WeakSelf SIMMsgObj *obj = [mChatFriend sendCustomCallAudioTextMsg:@"接听者,忙线中" callAudioType:AudioChatType_isBusy isCall:NO block:^(SResBase *resb, SIMMsgObj *newObj) { if (!resb.msuccess) { [SVProgressHUD showErrorWithStatus:resb.mmsg]; } else { } }]; return; } [AudioChatTool.shareInstance audioGetMainPushVoiceRoomIsZhuDongCall:NO withFriendObj:mChatFriend loadEndBlock:^{ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; }]; } else if (thatmsg.callAudioType == AudioChatType_receive) { //接收者,接听语音 [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_zhudongClose) { /** 3、挂断通话,发起者主动挂断,A给B发 */ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_beidongClose) { /** 4、挂断电话,接收者挂断,B给A发 */ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_isBusy) { /** 5、挂断电话,接收者忙线中,语音中或者在直播间中,B给A发 */ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_askIsNormal && thatmsg.isCall == NO) { /** 6、主动询问A是否在房间等着B通话,B给A发 */ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_notificationChatNormal && thatmsg.isCall) { /** 7、告诉B等着你呢,快来通话吧,A给B发 */ AudioChatTool.shareInstance.recordAudioChatViewController.callIsNormal = YES; } } else if (thatmsg.mMsgType == MSG_PRIVATE_CallVideo) { //收到视频请求 if (thatmsg.callAudioType == AudioChatType_call) { if (AppDelegate.sharedAppDelegate.isEnterLiveVC || AppDelegate.sharedAppDelegate.isInAudioVideoChatVc) { WeakSelf SIMMsgObj *obj = [mChatFriend sendCustomCallVideoTextMsg:@"接听者,忙线中" callAudioType:AudioChatType_isBusy isCall:NO block:^(SResBase *resb, SIMMsgObj *newObj) { if (!resb.msuccess) { [SVProgressHUD showErrorWithStatus:resb.mmsg]; } else { } }]; return; } WeakSelf [AudioChatTool.shareInstance videoGetMainPushVoiceRoomIsZhuDongCall:NO withFriendObj:mChatFriend loadEndBlock:^{ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; }]; } else if (thatmsg.callAudioType == AudioChatType_receive) { //接收者,接听语音 [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_zhudongClose) { /** 3、挂断通话,发起者主动挂断,A给B发 */ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_beidongClose) { /** 4、挂断电话,接收者挂断,B给A发 */ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_isBusy) { /** 5、挂断电话,接收者忙线中,语音中或者在直播间中,B给A发 */ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_askIsNormal && thatmsg.isCall == NO) { /** 6、主动询问A是否在房间等着B通话,B给A发 */ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:thatmsg.callAudioType]; } else if (thatmsg.callAudioType == AudioChatType_notificationChatNormal && thatmsg.isCall) { /** 7、告诉B等着你呢,快来通话吧,A给B发 */ AudioChatTool.shareInstance.recordVideoChatVC.callIsNormal = YES; } } } #pragma mark - VOIP推送 - (void)receivePushVoipMsgWithNotification:(NSDictionary *)notification { /* "callUserID" : 167720, "callAudioType" : 1, "callNickName" : "张三", "callHeaderImg" : "", "callType" : 666 */ NSDictionary * dict = notification[@"aps"][@"Extras"]; if (![dict isKindOfClass:NSDictionary.class] || dict == nil) { return; } BOOL isVideo = [dict[@"callType"] intValue] == MSG_PRIVATE_CallVideo ? YES : NO; if (AppDelegate.sharedAppDelegate.isEnterLiveVC || AppDelegate.sharedAppDelegate.isInAudioVideoChatVc) { SFriendObj* mChatFriend = [[SFriendObj alloc]initWithUserId:[dict[@"callUserID"] intValue]]; mChatFriend.mNick_name = dict[@"callNickName"]; mChatFriend.mHead_image = dict[@"callHeaderImg"]; BOOL isVideo = [dict[@"callType"] intValue] == MSG_PRIVATE_CallVideo ? YES : NO; if (isVideo) { SIMMsgObj *obj = [mChatFriend sendCustomCallVideoTextMsg:@"接听者,忙线中" callAudioType:AudioChatType_isBusy isCall:NO block:^(SResBase *resb, SIMMsgObj *newObj) { if (!resb.msuccess) { [SVProgressHUD showErrorWithStatus:resb.mmsg]; } }]; return; } SIMMsgObj *obj = [mChatFriend sendCustomCallAudioTextMsg:@"接听者,忙线中" callAudioType:AudioChatType_isBusy isCall:NO block:^(SResBase *resb, SIMMsgObj *newObj) { if (!resb.msuccess) { [SVProgressHUD showErrorWithStatus:resb.mmsg]; } }]; return; } NSString * subTitle = ASLocalizedString(@"邀请你语音通话"); if (isVideo) { subTitle = ASLocalizedString(@"邀请你视频通话"); } UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init]; content.title = @"711 Live"; content.userInfo = dict; content.body = [NSString localizedUserNotificationStringForKey:[NSString stringWithFormat:@"%@%@", dict[@"callNickName"],subTitle] arguments:nil]; UNNotificationSound *customSound = [UNNotificationSound soundNamed:@"phone_ringing.mp3"]; content.sound = customSound; UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO]; UNNotificationRequest * request = [UNNotificationRequest requestWithIdentifier:[NSString stringWithFormat:@"%@",dict[@"callUserID"]] content:content trigger:trigger]; [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { NSLog(@"结束"); }]; /** 初始化计时器 每一秒振动一次 @param playkSystemSound 振动方法 @return */ // if(_vibrationTimer){ // [_vibrationTimer invalidate]; // _vibrationTimer = nil; // }else{ // _vibrationTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(playkSystemSound) userInfo:nil repeats:YES]; // } } //振动 //- (void)playkSystemSound{ // AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); //} - (void)pushAudioChatWithDict:(NSDictionary *)dict { // { // UIAlertView *alert = [UIAlertView bk_showAlertViewWithTitle:NSLocalizedString(@"TCVideoRecordView.AbandonRecord", nil) message:[NSString stringWithFormat:@"%@",dict] cancelButtonTitle:NSLocalizedString(@"Common.Cancel", nil) otherButtonTitles:@[NSLocalizedString(@"Common.OK", nil)] handler:^(UIAlertView *alertView, NSInteger buttonIndex) { // // }]; // [alert show]; // } //过期的推送,直接拦截,不再唤起接听页面 if ([dict[@"callAudioType"] intValue] == AudioChatType_notificationChatExpired) { return; } SFriendObj * mChatFriend = [[SFriendObj alloc]initWithUserId:[dict[@"callUserID"] intValue]]; mChatFriend.mNick_name = dict[@"callNickName"]; mChatFriend.mHead_image = dict[@"callHeaderImg"]; if ([dict[@"callType"] intValue] == MSG_PRIVATE_CallAudio) { [AudioChatTool.shareInstance audioGetMainPushVoiceRoomIsZhuDongCall:NO withFriendObj:mChatFriend loadEndBlock:^{ [AudioChatTool.shareInstance.recordAudioChatViewController reloadDataWithType:AudioChatType_call]; }]; return; } [AudioChatTool.shareInstance videoGetMainPushVoiceRoomIsZhuDongCall:NO withFriendObj:mChatFriend loadEndBlock:^{ [AudioChatTool.shareInstance.recordVideoChatVC reloadDataWithType:AudioChatType_call]; }]; } #pragma mark - 请求接口,推送VOIP - (void)requestCallApplyWithAudio:(BOOL)isAudio block:(void(^)(BOOL isSuccess))block { // if (block) { // block(YES); // } // return; NSMutableDictionary *parmDict = [[NSMutableDictionary alloc] init]; [parmDict setObject:@"games" forKey:@"ctl"]; [parmDict setObject:@"userDiamonds" forKey:@"act"]; [[NetHttpsManager manager] POSTWithParameters:parmDict SuccessBlock:^(NSDictionary *responseJson) { if ([responseJson toInt:@"status"] == 1) { if (block) { block(YES); } return; } if (block) { block(NO); } } FailureBlock:^(NSError *error){ if (block) { block(NO); } }]; } #pragma mark - 获取其他人的在线状态 - (void)getOtherIsOnlineStatusWithUserID:(NSString *)userID block:(void (^)(V2TIMUserStatusType statusType))block { if ([BGUtils isBlankString:userID]) { if (block) { block(V2TIM_USER_STATUS_UNKNOWN); } return; } [V2TIMManager.sharedInstance getUserStatus:@[userID] succ:^(NSArray *result) { // 查询其他人的状态成功 if (result.count <= 0) { //查询失败,按照离线处理 if (block) { block(V2TIM_USER_STATUS_UNKNOWN); } return; } V2TIMUserStatus * obj = result.firstObject; if (block) { block(obj.statusType); } } fail:^(int code, NSString *desc) { //72001 腾讯云管理后台关闭了此功能 //查询失败,按照离线处理 if (block) { block(V2TIM_USER_STATUS_UNKNOWN); } }]; } @end