You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
585 lines
18 KiB
585 lines
18 KiB
// |
|
// BRManager.m |
|
// tongxin |
|
// |
|
// Created by ecell on 2020/11/18. |
|
// Copyright © 2020 xTT. All rights reserved. |
|
// |
|
|
|
#import "BRManager.h" |
|
#import <AnyChatCoreSDK/AnyChatCoreSDK.h> |
|
#import "BRVideoCallView.h" |
|
#import <LSTPopView.h> |
|
#import "UIView+XHRemoteImage.h" |
|
#import "WHToast.h" |
|
|
|
#define kUserID 1001 |
|
#define kAnyChatIP @"iotcloud.anychat.cn" |
|
#define kAnyChatPort 8906 |
|
#define kAnyChatUserName @"AnyChat" |
|
#define kAnyChatAppid @"A3BEE84E-9C7A-D848-85D3-90F233D9A022" |
|
#define kAnyChatDefaultSignUrl @"http://iotcloud.anychat.cn/AnyChatSign/json/getSign" |
|
|
|
#define BRAC_SO_CORESDK_8KAUDIOSAMPLES 249 ///< 8K音频采样模式 |
|
|
|
|
|
@interface BRManager () <AnyChatNotifyMessageDelegate, AnyChatVideoCallDelegate> |
|
{ |
|
AnyChatPlatform *theAnyChat; |
|
AVAudioPlayer *audioPlayer; |
|
} |
|
|
|
@property (strong, nonatomic) LSTPopView *popView; |
|
|
|
@end |
|
|
|
static BRManager* _manager; |
|
static bool _isLogining; |
|
static NSString* _nick; |
|
static NSNumber* _bairuiId; |
|
|
|
|
|
@implementation BRManager |
|
|
|
|
|
+ (BRManager*)shared { |
|
static dispatch_once_t predicate; |
|
|
|
dispatch_once(&predicate, ^{ |
|
_manager = [[self alloc] init]; |
|
//8k设置放在初始化之前 |
|
[AnyChatPlatform SetSDKOptionInt:BRAC_SO_CORESDK_8KAUDIOSAMPLES :1]; |
|
[AnyChatPlatform InitSDK:0]; |
|
[AnyChatPlatform SetSDKOptionInt:BRAC_SO_CORESDK_UPLOADLOGINFO :1]; |
|
[[NSNotificationCenter defaultCenter] addObserver:_manager selector:@selector(AnyChatNotifyHandler:) name:@"ANYCHATNOTIFY" object:nil]; |
|
}); |
|
|
|
|
|
return _manager; |
|
} |
|
|
|
-(bool)initialize { |
|
theAnyChat = [AnyChatPlatform getInstance]; |
|
theAnyChat.notifyMsgDelegate = self; |
|
theAnyChat.videoCallDelegate = self; |
|
return YES; |
|
} |
|
|
|
//0 Unknow,1 Connected,2 Logined,3 In Room,4 Logouted,5 Link Closed |
|
-(BOOL)isUserLogin { |
|
int result = [AnyChatPlatform QueryUserStateInt:-1 :BRAC_USERSTATE_SELFUSERSTATUS]; |
|
|
|
NSLog(@"isUserLogin = %d", result); |
|
|
|
return (result==2 || result==3); |
|
} |
|
|
|
|
|
// 用户离线 "{"errorcode":205}" |
|
-(BOOL)queryRemoteUserOnline:(int)userId { |
|
|
|
NSString *qParam = [NSString stringWithFormat:@"{\"userid\":%d}", userId]; |
|
|
|
NSString *json = [AnyChatPlatform QueryInfoFromServer:ANYCHAT_SERVERQUERY_USERINFOBYID :qParam :0]; |
|
|
|
NSLog(@"json = %@", json); |
|
|
|
if (json) { // MARK add by lsz 2021-12-15 json is nil |
|
|
|
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; |
|
|
|
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; |
|
|
|
NSNumber *code = [dict objectForKey:@"errorcode"]; |
|
|
|
if (code) { |
|
return [code intValue] != 205; |
|
} |
|
} |
|
|
|
return NO; |
|
} |
|
|
|
-(void)uninitialize { |
|
[AnyChatPlatform Release]; |
|
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
} |
|
|
|
|
|
-(void)login:(NSNumber *)bairuiId nick:(NSString *) nick { |
|
|
|
_bairuiId = bairuiId; |
|
_nick = nick; |
|
|
|
[self getSign:@{@"userid": [bairuiId stringValue], @"struserid": @""} success:^(id responseObject) { |
|
|
|
NSLog(@"获取签名成功:%@", responseObject); |
|
|
|
if ([[responseObject objectForKey:@"errorcode"] intValue] ==0) { |
|
int timestamp = [[responseObject objectForKey:@"timestamp"] intValue]; |
|
NSString *signStr = [responseObject objectForKey:@"sigStr"]; |
|
|
|
NSLog(@"开始登录。。。"); |
|
[AnyChatPlatform Connect:kAnyChatIP : kAnyChatPort]; |
|
[AnyChatPlatform LoginEx:nick :[bairuiId intValue] :@"" :kAnyChatAppid :timestamp :signStr :nil]; |
|
|
|
} else { |
|
//[self showSignError]; |
|
NSLog(@"签名获取失败:%d", [[responseObject objectForKey:@"errorcode"] intValue]); |
|
_isLogining = NO; |
|
} |
|
|
|
} failure:^(NSError *error) { |
|
NSLog(@"获取签名失败。。。"); |
|
_isLogining = NO; |
|
}]; |
|
} |
|
|
|
|
|
#pragma mark - AnyChatNotifyMessageDelegate |
|
- (void)AnyChatNotifyHandler:(NSNotification*)notify { |
|
NSDictionary* dict = notify.userInfo; |
|
[theAnyChat OnRecvAnyChatNotify:dict]; |
|
} |
|
|
|
// 连接服务器消息 |
|
- (void) OnAnyChatConnect:(BOOL) bSuccess { |
|
if (!bSuccess) { |
|
NSLog(@"佰锐视频连接失败"); |
|
} else { |
|
NSLog(@"佰锐视频连接成功"); |
|
} |
|
} |
|
|
|
// 用户登陆消息 |
|
- (void) OnAnyChatLogin:(int) dwUserId : (int) dwErrorCode { |
|
|
|
if(dwErrorCode == GV_ERR_SUCCESS) { |
|
NSLog(@"佰锐视频登录成功"); |
|
_isLogining = NO; |
|
// 肯能出现空指针 去掉这行代码 2021-12-24 |
|
//[self queryRemoteUserOnline:dwUserId]; |
|
} else { |
|
[AnyChatPlatform Logout]; |
|
_isLogining = NO; |
|
NSLog(@"佰锐视频登录失败:%d",dwErrorCode); |
|
} |
|
} |
|
|
|
// 用户进入房间消息 |
|
- (void) OnAnyChatEnterRoom:(int) dwRoomId : (int) dwErrorCode { |
|
|
|
VideoViewController *videoVC = [[VideoViewController alloc]init]; |
|
|
|
videoVC.brModel = self.brModel; |
|
videoVC.isReceiveCall = _isReceiveCall; |
|
videoVC.callType = _callType; |
|
videoVC.video_id = self.brModel.video_id; |
|
videoVC.device = self.device; |
|
|
|
self.callViewController = videoVC; |
|
videoVC.hidesBottomBarWhenPushed = YES; |
|
|
|
if (![[self.gMianVC.navigationController.viewControllers lastObject] isKindOfClass:videoVC.class]) { |
|
UIViewController *topVC = [self getCurrentVC]; |
|
[topVC.navigationController pushViewController:videoVC animated:YES]; |
|
// old update by lsz |
|
//[self.gMianVC.navigationController pushViewController:videoVC animated:YES]; |
|
} |
|
|
|
NSLog(@"======OnAnyChatEnterRoom======%d",dwRoomId); |
|
} |
|
|
|
// MARK: 获取顶部视图 add by lsz 2021-06-19 |
|
- (UIViewController *)getCurrentVC |
|
{ |
|
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; |
|
UIViewController *currentVC = [self getCurrentVCFrom:rootViewController]; |
|
return currentVC; |
|
} |
|
|
|
- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC |
|
{ |
|
UIViewController *currentVC; |
|
if ([rootVC presentedViewController]) { |
|
// 视图是被presented出来的 |
|
rootVC = [rootVC presentedViewController]; |
|
} |
|
|
|
if ([rootVC isKindOfClass:[UITabBarController class]]) { |
|
// 根视图为UITabBarController |
|
currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]]; |
|
} else if ([rootVC isKindOfClass:[UINavigationController class]]){ |
|
// 根视图为UINavigationController |
|
currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]]; |
|
} else { |
|
// 根视图为非导航类 |
|
currentVC = rootVC; |
|
} |
|
|
|
return currentVC; |
|
} |
|
|
|
// 房间在线用户消息 |
|
- (void) OnAnyChatOnlineUser:(int) dwUserNum : (int) dwRoomId { |
|
|
|
} |
|
|
|
// 用户进入房间消息 |
|
- (void) OnAnyChatUserEnterRoom:(int) dwUserId { |
|
NSLog(@"======OnAnyChatUserEnterRoom======%d",dwUserId); |
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"ANY_CHAT_USER_ENTER_ROOM" object:nil userInfo:@{@"dwUserId":[NSNumber numberWithInt:dwUserId]}]; |
|
} |
|
|
|
// 用户退出房间消息 |
|
- (void) OnAnyChatUserLeaveRoom:(int) dwUserId { |
|
|
|
} |
|
|
|
// 网络断开消息 |
|
- (void) OnAnyChatLinkClose:(int) dwErrorCode { |
|
//[AnyChatPlatform Logout]; |
|
[self finishVideoCall]; |
|
} |
|
|
|
#pragma mark ---- 网络请求获取签名登录 ---- |
|
- (void)getSign:(NSDictionary*)paramDict success:(void (^)(id))success failure:(void (^)(NSError *))failure { |
|
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kAnyChatDefaultSignUrl]]; |
|
request.HTTPMethod = @"POST"; |
|
request.timeoutInterval = 10.0; |
|
request.HTTPBody = [[NSString stringWithFormat:@"userid=%@&struserid=%@&appid=%@", paramDict[@"userid"], paramDict[@"struserid"], kAnyChatAppid] dataUsingEncoding:NSUTF8StringEncoding]; |
|
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; |
|
NSURLSession *session = [NSURLSession sharedSession]; |
|
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { |
|
dispatch_async(dispatch_get_main_queue(), ^{ |
|
if (!error) { |
|
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; |
|
if (success) success(dict); |
|
} else { |
|
if (failure) failure(error); |
|
} |
|
}); |
|
}] resume]; |
|
} |
|
|
|
|
|
- (void)OnAnyChatVideoCallEventCallBack:(int)dwEventType :(int)dwUserId :(int)dwErrorCode :(int)dwFlags :(int)dwParam :(NSString *)lpUserStr { |
|
//NSString *s_theCallbackUserName = [AnyChatPlatform GetUserName:dwUserId]; |
|
//NSString *callType = lpUserStr; |
|
|
|
switch (dwEventType) { |
|
case BRAC_VIDEOCALL_EVENT_REQUEST: |
|
{ |
|
NSLog(@"收到视频通话请求"); |
|
self.isReceiveCall = YES; |
|
[self doVideoAnswer:dwUserId :lpUserStr]; |
|
|
|
break; |
|
} |
|
case BRAC_VIDEOCALL_EVENT_REPLY: |
|
{ |
|
NSString *status; |
|
|
|
switch (dwErrorCode) |
|
{ |
|
case GV_ERR_VIDEOCALL_CANCEL: |
|
{ |
|
NSLog(@"用户取消会话"); |
|
status = @"用户取消会话"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_REJECT: |
|
{ |
|
NSLog(@"用户拒绝会话"); |
|
status = @"用户拒绝会话"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_OFFLINE: |
|
{ |
|
NSLog(@"对方不在线"); |
|
status = @"对方不在线"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_BUSY: |
|
{ |
|
NSLog(@"用户在忙"); |
|
status = @"用户在忙"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_TIMEOUT: |
|
{ |
|
NSLog(@"会话请求超时"); |
|
status = @"用户在忙"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_DISCONNECT: |
|
{ |
|
NSLog(@"网络断线"); |
|
status = @"对方挂断视频"; |
|
break; |
|
} |
|
case GV_ERR_VIDEOCALL_NOTINCALL: |
|
{ |
|
NSLog(@"用户不在呼叫状态"); |
|
status = @"用户不在呼叫状态"; |
|
break; |
|
} |
|
} |
|
|
|
if (dwErrorCode != 0) { |
|
[self stopRing]; |
|
[self dismissPopView]; |
|
} |
|
|
|
if (status) { |
|
[WHToast showMessage:status duration:3 finishHandler:^{}]; |
|
} |
|
|
|
//if (dwErrorCode == GV_ERR_VIDEOCALL_DISCONNECT) { |
|
// [self finishVideoCall]; |
|
//} |
|
|
|
break; |
|
} |
|
case BRAC_VIDEOCALL_EVENT_START://成功 |
|
{ |
|
//进入房间 |
|
[AnyChatPlatform EnterRoom:dwParam :@""]; |
|
g_isEnterRoom = YES; |
|
NSLog(@"进入房间%d", dwParam); |
|
[self stopRing]; |
|
[self dismissPopView]; |
|
break; |
|
} |
|
case BRAC_VIDEOCALL_EVENT_FINISH: |
|
{ |
|
[self finishVideoCall]; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
-(void)finishVideoCall { |
|
if (g_isEnterRoom) { |
|
g_isEnterRoom = NO; |
|
[AnyChatPlatform LeaveRoom:-1]; |
|
NSLog(@"=======BRAC_VIDEOCALL_EVENT_FINISH LeaveRoom"); |
|
} |
|
|
|
[self.callViewController.navigationController popViewControllerAnimated:YES]; |
|
NSString *callTime = self.callViewController.theVideoTimeLab.text; |
|
self.callViewController = nil; |
|
[self uploadCallTime: callTime]; |
|
|
|
[AnyChatPlatform Logout]; |
|
|
|
[self login:_bairuiId nick:_nick]; |
|
//[self uninitialize]; |
|
NSLog(@"视频通话结束。。。"); |
|
} |
|
|
|
|
|
-(void)uploadCallTime:(NSString *)callTime { |
|
|
|
if(callTime && callTime.length == 8){ |
|
|
|
NSLog(@"upload call time = %@", callTime); |
|
|
|
NSArray *hhmmss = [callTime componentsSeparatedByString:@":"]; |
|
|
|
if (hhmmss && hhmmss.count == 3) { |
|
|
|
int hh = [[NSString stringWithFormat:@"%@", hhmmss[0]] intValue]; |
|
int mm = [[NSString stringWithFormat:@"%@", hhmmss[1]] intValue]; |
|
int ss = [[NSString stringWithFormat:@"%@", hhmmss[2]] intValue]; |
|
|
|
int total = hh*60*60 + mm*60 + ss; |
|
|
|
//MARK:上传视频时间 |
|
|
|
NSMutableDictionary *dic = [NSMutableDictionary dictionary]; |
|
|
|
[dic setValue:@(total) forKey:@"duration"]; |
|
[dic setValue:@(0) forKey:@"wait_duration"];//wait_duration |
|
[dic setValue:@(self.brModel.distinguishability_width) forKey:@"distinguishability_width"]; |
|
[dic setValue:@(self.brModel.distinguishability_heiger) forKey:@"distinguishability_heiger"]; |
|
[dic setValue:self.brModel.video_id forKey:@"video_id"]; |
|
|
|
[UserDefaults setValue:[NSString stringWithFormat:@"%@&%@&%@&%@&%@",@(total),self.brModel.video_id,@(self.brModel.distinguishability_width),@(self.brModel.distinguishability_heiger),@(0)] forKey:VideoTimeAndIDAndWHRecordKey]; |
|
|
|
[cUser postVideoCallTimeParame:[dic copy] deviceModel:self.device success:^(id responseObject) { |
|
xLog(@"上传视频时间成功"); |
|
//MARK: 上传完视频时间后删除存储的 Key |
|
[UserDefaults removeObjectForKey:VideoTimeAndIDAndWHRecordKey]; |
|
|
|
} failure:^{ |
|
xLog(@"上传视频时间失败,重试一次"); |
|
}]; |
|
} |
|
} |
|
} |
|
|
|
// 通话类型 0:视频 1:语音 |
|
-(void)doVideoAnswer:(int)dwUserId :(NSString *)lpUserStr { |
|
|
|
_callType = 0; |
|
if ([@"audio" isEqualToString:lpUserStr]) { |
|
_callType = 1; |
|
} |
|
|
|
WEAKSELF |
|
//声网和菊风共用一个 |
|
[cUser getVideoInfoWithDeviceImei:[NSString stringWithFormat:@"br-%d", dwUserId] CallType:@(_callType).intValue Success:^(id responseObject) { |
|
|
|
weakSelf.brModel = [BairuiModel mj_objectWithKeyValues:responseObject]; |
|
weakSelf.brModel.call_type = _callType; |
|
[weakSelf doVideoAnswerCall:dwUserId]; |
|
|
|
} failure:^{ |
|
|
|
}]; |
|
|
|
} |
|
|
|
- (void)doVideoAnswerCall:(int)dwUserId { |
|
|
|
[self playRing:@"ring"]; |
|
|
|
WEAKSELF |
|
|
|
_device = [cUser getDeviceWithImei:_brModel.imei]; |
|
_brModel.device_username = [NSString stringWithFormat:@"%d", dwUserId]; |
|
|
|
if(_popView) { |
|
return; |
|
} |
|
|
|
UINib *nib = [UINib nibWithNibName:@"BRVideoCallView" bundle:nil]; |
|
BRVideoCallView *view = [nib instantiateWithOwner:nil options:nil].firstObject; |
|
view.nick.text = _device.name; |
|
[view.headImg setImageWithURL:[NSURL URLWithString:_device.avator] placeholer:[UIImage imageNamed:@"icon_girl_head_portrait_1"]]; |
|
view.progress.hidden = YES; |
|
view.cancelCall.hidden = YES; |
|
view.layer.cornerRadius = 10; |
|
view.layer.masksToBounds = YES; |
|
|
|
_popView = [LSTPopView initWithCustomView:view popStyle:LSTPopStyleSmoothFromTop dismissStyle:LSTDismissStyleSmoothToBottom]; |
|
_popView.isClickBgDismiss = NO; |
|
|
|
LSTPopViewWK(_popView) |
|
|
|
view.hungUpBlock = ^{ |
|
[wk__popView dismiss]; |
|
[weakSelf rejectCall:dwUserId]; |
|
}; |
|
|
|
view.pickUpBlock = ^ { |
|
[wk__popView dismiss]; |
|
[weakSelf acceptCall:dwUserId]; |
|
}; |
|
|
|
[_popView pop]; |
|
} |
|
|
|
- (void)dismissPopView { |
|
if (_popView) { |
|
[_popView dismiss]; |
|
_popView = nil; |
|
} |
|
} |
|
|
|
-(void)showCallDialog:(User *)user userId:(int)dwUserId callback:(CancelBlock)callback { |
|
|
|
[self playRing:@"tones"]; |
|
|
|
WEAKSELF |
|
|
|
UINib *nib = [UINib nibWithNibName:@"BRVideoCallView" bundle:nil]; |
|
BRVideoCallView *view = [nib instantiateWithOwner:nil options:nil].firstObject; |
|
view.nick.text = user.name; |
|
[view.headImg setImageWithURL:[NSURL URLWithString:user.avator] placeholer:[UIImage imageNamed:@"icon_girl_head_portrait_1"]]; |
|
view.progress.hidden = NO; |
|
[view.progress startAnimating]; |
|
view.cancelCall.hidden = NO; |
|
view.pickUp.hidden = YES; |
|
view.hungUp.hidden = YES; |
|
view.layer.cornerRadius = 10; |
|
view.layer.masksToBounds = YES; |
|
|
|
_popView = [LSTPopView initWithCustomView:view popStyle:LSTPopStyleSmoothFromTop dismissStyle:LSTDismissStyleSmoothToBottom]; |
|
|
|
_popView.isClickBgDismiss = NO; |
|
|
|
LSTPopViewWK(_popView) |
|
|
|
view.cancelBlock = ^{ |
|
[wk__popView dismiss]; |
|
[weakSelf cancelCall:dwUserId]; |
|
if (callback) { |
|
callback(); |
|
} |
|
}; |
|
|
|
|
|
[_popView pop]; |
|
} |
|
|
|
- (void)acceptCall:(int)dwUserId { |
|
[self stopRing]; |
|
[self dismissPopView]; |
|
[AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REPLY |
|
:dwUserId |
|
:0 |
|
:0 |
|
:0 |
|
:nil]; |
|
} |
|
|
|
- (void)rejectCall:(int)dwUserId { |
|
[self stopRing]; |
|
[self dismissPopView]; |
|
[AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REPLY |
|
:dwUserId |
|
:GV_ERR_VIDEOCALL_REJECT |
|
:0 |
|
:0 |
|
:nil]; |
|
} |
|
|
|
-(void)cancelCall:(int)dwUserId { |
|
[self stopRing]; |
|
[self dismissPopView]; |
|
[AnyChatPlatform VideoCallControl:BRAC_VIDEOCALL_EVENT_REPLY |
|
:dwUserId |
|
:GV_ERR_VIDEOCALL_CANCEL |
|
:0 |
|
:0 |
|
:nil]; |
|
|
|
} |
|
|
|
|
|
//MARK: 响铃的 MP3 |
|
- (void)playRing:(NSString *)name { |
|
[self stopRing]; |
|
AVAudioSession *audioSession = [AVAudioSession sharedInstance]; |
|
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; |
|
[audioSession setActive:YES error:nil]; |
|
|
|
NSURL *path = [[NSBundle mainBundle] URLForResource:name withExtension:@"mp3"]; |
|
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:nil]; |
|
audioPlayer.numberOfLoops = -1; |
|
[audioPlayer play]; |
|
} |
|
|
|
- (void)stopRing { |
|
if (audioPlayer) { |
|
[audioPlayer stop]; |
|
audioPlayer = nil; |
|
} |
|
} |
|
|
|
|
|
@end
|
|
|