123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- //
- // VideoManager.m
- // SikeyComm
- //
- // Created by 刘振兴 on 2024/3/21.
- // Copyright © 2024 BaH Cy. All rights reserved.
- //
- #import "VideoManager.h"
- #import "VideoManager+timer.h"
- @interface VideoManager() <JCClientCallback, JCMediaDeviceCallback, JCCallCallback>
- @end
- @implementation VideoManager
- + (VideoManager *)shared {
- static VideoManager *manager;
- static dispatch_once_t token;
- dispatch_once(&token, ^{
- manager = [[VideoManager alloc] init];
- });
- return manager;
- }
- //初始化
- - (BOOL)initJuphoon {
- self.mJuphoonClient = [JCClient create:APP_KEY_JUPHOON callback:self createParam:nil];
- self.mJuphoonMediaDevice = [JCMediaDevice create:self.mJuphoonClient callback:self];
- self.mJuphoonCall = [JCCall create:self.mJuphoonClient mediaDevice:self.mJuphoonMediaDevice callback:self];
- self.mJuphoonCall.mediaConfig = [JCCallMediaConfig generateByMode:JCCallMediaConfigModeIOT];
-
- // 现在设置屏幕方向固定,竖直角度
- //self.mJuphoonMediaDevice.autoRotate = false;
- //[self.mJuphoonMediaDevice setSawtooth:YES];
- [self.mJuphoonMediaDevice setCameraProperty:640 height:360 framerate:10];
-
- //Zmf_VideoCaptureListenRotation(0, 0);
- //Zmf_VideoRenderListenRotation(0,0);
-
- return self.mJuphoonClient.state == JCClientStateIdle;
- }
- - (void)loginJuphoon {
- NSString* uid = [DataManager shared].loginModel.uid;
- NSString* password = @"123456";
-
- JCClientLoginParam* loginParam = [[JCClientLoginParam alloc] init];
- BOOL isOK = [self.mJuphoonClient login:uid password:password loginParam:loginParam];
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: login call: %d", isOK]));
- }
- - (void)logoutJuphoon {
- if (self.mJuphoonClient) {
- [self.mJuphoonClient logout];
- }
- }
- #pragma mark - JCMediaDeviceCallback
- /**
- * 登录结果回调
- *
- * 在调用 {@link JCClient#login:password:loginParam: login} 方法成功后会收到此回调
- *
- * @param result 登录是否成功
- * - true:登录成功
- * - false:登录失败
- * @param reason 登录失败原因,当 result 为 false 时该值有效。参见:@ref JCClientReason "错误原因"
- */
- - (void)onLogin:(bool)result reason:(JCClientReason)reason {
- @weakify(self);
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: login Result:%d Reason:%ld", result, reason]));
- if (result) {// 登录成功
-
- } else if (reason == JCClientReasonAuth) {// 账号密码错误
-
- } else {
- //如果没有成功//
- if (reason != JCClientReasonNone && reason != JCClientReasonStateCannotLogin) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [weak_self loginJuphoon];
- });
-
- }
- }
- }
- /**
- * 登出回调
- *
- * 在调用 {@link JCClient#logout logout} 方法成功会收到此回调
- *
- * @param reason 登出失败原因,参见:@ref JCClientReason "错误原因"
- */
- - (void)onLogout:(JCClientReason)reason {
- HDNormalLog(@"SKJuphoon: onLogout");
- }
- /**
- * 登录状态变化回调
- *
- * 在用户的登录状态发生改变时会收到此回调,登录状态:
- * - @ref JCClientStateNotInit : 未初始化
- * - @ref JCClientStateIdle : 未登录
- * - @ref JCClientStateLogining : 登录中
- * - @ref JCClientStateLogined : 登录成功
- * - @ref JCClientStateLogouting : 登出中
- *
- * @param state 当前状态值
- * @param oldState 之前状态值
- */
- - (void)onClientStateChange:(JCClientState)state oldState:(JCClientState)oldState {
- if (state == JCClientStateIdle) {
- [self loginJuphoon];
- }
- }
- #pragma mark - JCCallCallback
- /**
- * 新增通话回调
- *
- * 当上层收到此回调时,可以根据 JCCallItem 对象获得该通话的所有信息及状态,从而更新该通话相关UI
- *
- * @param item JCCallItem 对象
- */
- - (void)onCallItemAdd:(JCCallItem* __nonnull)item {
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: onCallItemAdd direction: %ld", (long)item.direction]));
- NSDictionary *dic = @{kCallIetmKey:item};
- [[NSNotificationCenter defaultCenter] postNotificationName:kCallNotification object:nil userInfo:dic];
- if (self.mJuphoonCall.callItems.count == 1) {
- [self showInCallVC];
- }
- }
- /**
- * 移除通话回调
- *
- * 当上层收到此回调时,可以根据 JCCallItem 对象获得该通话的所有信息及状态,从而更新该通话相关UI
- *
- * @param item JCCallItem 对象
- * @param reason 通话结束原因,参见:@ref JCCallReason "通话结束原因"
- * @param description 通话结束原因的描述,只有被动挂断的时候,才会收到这个值,其他情况下则返回空字符串
- */
- - (void)onCallItemRemove:(JCCallItem *)item reason:(JCCallReason)reason description:(NSString *)description {
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: onCallItemRemove reason:%ld", reason]));
- [[NSNotificationCenter defaultCenter] postNotificationName:kCallNotification object:nil];
- [self removeInCallVC];
- switch (reason) {
- case JCCallReasonNone:
- [EasyTextView showInfoText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.Hangup", nil)]];
- break;
-
- case JCCallReasonNotFound:
- [EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.User.No", nil)]];
- break;
-
- case JCCallReasonUserOffline:
- [EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.User.Offline", nil)]];
- [self loginJuphoon];
- break;
-
- case JCCallReasonNotLogin:
- [EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.User.Login", nil)]];
- break;
-
- case JCCallReasonTimeOut:
- //[EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.Timeout", nil)]];
- break;
-
- case JCCallReasonNetWork:
- [EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.Network", nil)]];
- break;
-
- default: {
- break;
- }
- }
- }
- /**
- * 通话状态更新回调
- *
- * 当上层收到此回调时,可以根据 JCCallItem 对象获得该通话的所有信息及状态,从而更新该通话相关UI
- *
- * @param item JCCallItem 对象
- * @param changeParam JCCallChangeParam 更新标识对象
- */
- - (void)onCallItemUpdate:(JCCallItem* __nonnull)item changeParam:(JCCallChangeParam * __nullable)changeParam {
- if (item.state == JCCallStateTalking && [self.mInCallVC getRemoteCanvas] == nil && item.uploadVideoStreamOther) {
- [self stopVideoTimer];
- }
- [[NSNotificationCenter defaultCenter] postNotificationName:kCallNotification object:nil];
- }
- - (void)requestVideo:(NSString*)sid ticket:(NSString*)ticket dial:(NSInteger)dial {
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: requestVideo ticket:%@ dial:%ld", ticket, dial]));
- NSDictionary *param = @{
- @"sid":sid,
- @"roomId":ticket,
- @"dial":@(dial), //是否是拨号 -1 挂断 1 拨号
- };
- NSString* url = dial == 1? URL_VIDEO_DIAL : URL_VIDEO_HANGUP;
- [ERequest httpRequest:param httpURL:url httpMethod:@"GET" onSuccess:^(NSDictionary *result) {
- if ([ERequest isSuccessWithResult:result]) {
- } else {
- [EasyTextView showErrorText:result[@"message"]];
- }
- } onFailure:^(NSError *error) {
- [EasyTextView showErrorText:NSLocalizedString(@"Network.Error", nil)];
- }];
- }
- - (void)videoStart:(NSString*)sid ticket:(NSString*)ticket dial:(NSInteger)dial {
- BOOL isReachable = [[AFNetworkReachabilityManager sharedManager] isReachable];
- if (!isReachable) {
- [EasyTextView showErrorText:NSLocalizedString(@"Network.Error", nil)];
- return;
- }
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: videoStart: sid:%@ ticket:%@ dial:%ld", sid, ticket, dial]));
- self.mSID = sid;
- self.mTicket = ticket;
- JCCallParam* callParam = [JCCallParam callParamWithExtraParam:@"" ticket:ticket];
- BOOL isok = [self.mJuphoonCall call:ticket video:true callParam:callParam];
- if (!isok) {
- //如果失败,很有可能登录失败,重新登录//
- [self loginJuphoon];
- [EasyTextView showErrorText:[NSString stringWithFormat:NSLocalizedString(@"Video.Error.User.Login", nil)]];
- } else {
- [self requestVideo:sid ticket:ticket dial:1];
- [self startVideoTimer];
- }
- }
- - (void)videoEnd:(BOOL)isIncomming isSendMessage:(BOOL)isSendMessage {
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: videoEnd:%d", isIncomming]));
- //发消息
- if (isSendMessage) {
- JCCallItem *activeCall = self.mJuphoonCall.callItems.firstObject;
- if(activeCall.state == JCCallStateInit || activeCall.state == JCCallStatePending) {
- NSString* ticket = [self getJuphoonName];
- NSString* sid = [self getJuphoonSID];
- [self requestVideo:sid ticket:ticket dial:-1];
- }
- }
- [self autoTerm];
- }
- #pragma mark -
- - (void)actionFromSocket:(SocketModel*)model dial:(NSInteger)dial {
- if (dial <= 0) {
- NSString* talkId = [self getJuphoonName];
- ChildModel* childModel = [[DataManager shared] getChildWithTicket:talkId];
- BOOL isEquel = [model.sendId isEqualToString:childModel.cid];
- if (isEquel) {
- [EasyTextView showInfoText:NSLocalizedString(@"Video.Error.Hangup", nil)];
- [self autoTerm];
- }
- } else {
- [self loginJuphoon];
- }
- }
- - (void)showInCallVC {
- if (self.mInCallVC)
- return;
- NSLog(@"SKJuphoon: showInCallVC");
- UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
- self.mInCallVC = [storyboard instantiateViewControllerWithIdentifier:@"InCallVC"];
- [self.mInCallVC setHidesBottomBarWhenPushed:YES];
- [EUtil pushViewController:self.mInCallVC animated:YES];
- }
- - (void)removeInCallVC {
- if (self.mInCallVC) {
- [self.mInCallVC.navigationController popViewControllerAnimated:YES];
- }
- self.mInCallVC = nil;
- }
- //挂断
- - (void)autoTerm {
- for (JCCallItem* item in self.mJuphoonCall.callItems) {
- if (item.active) {
- [self.mJuphoonCall term:item reason:JCCallReasonNone description:@"test"];
- return;
- }
- }
- }
- - (void)autoTermWithTimeout {
- NSString* sid = [self getJuphoonSID];
- NSString* ticket = [self getJuphoonName];
- if (!ticket || ticket.length <= 0)
- return;
- [EasyTextView showErrorText:NSLocalizedString(@"Video.Error.Timeout", nil)];
- [self requestVideo:sid ticket:ticket dial:-1];
- [self autoTerm];
- }
- - (NSString*)getJuphoonSID {
- JCCallItem *activeCall = self.mJuphoonCall.callItems.firstObject;
- if (activeCall.direction == JCCallDirectionOut) {
- return self.mSID;
- } else {
- return activeCall.userId;
- }
- }
- - (NSString*)getJuphoonName {
- JCCallItem *activeCall = self.mJuphoonCall.callItems.firstObject;
- if (activeCall.direction == JCCallDirectionOut) {
- return self.mTicket;
- } else {
- return activeCall.userId;
- }
- }
- - (NSString*)getTalkName {
- NSString* talkId = [self getJuphoonName];
- ChildModel* model = [[DataManager shared] getChildWithTicket:talkId];
- return model ? model.name : @"";
- }
- - (NSString*)getTalkHeadImageURL {
- NSString* talkId = [self getJuphoonName];
- ChildModel* model = [[DataManager shared] getChildWithTicket:talkId];
- return model ? model.avatar : @"";
- }
- @end
|