1.1、實時音頻、實時視頻均通過相同的接口進行調用,遵循相同的業務流程。不同的業務通過呼叫接口參數CallType進行區分,VIDEO視頻、VOICE音頻等。
1.2、接口邏輯:
接口調用是采取異步調用的方式。所有的呼叫相關接口的調用結果通過回調接口ECVoIPCallDelegate中的方法OnCallEvents來接受服務端返回的各種狀態。
1.3、業務流程
(1)客戶A呼叫客戶B發起請求
(2)云通訊服務端收到A請求并把請求轉發給B
(3)客戶B收到請求并應答
(4)云通訊服務端收到B應答并轉發A
(5)A收到應答,通話建立
2.1、呼叫界面處理
self.callID = [[ECDevice sharedInstance].VoIPManager makeCallWithType:VOICE andCalled:@ "John的登錄賬號"]; if (self.callid.length <= 0)//獲取CallID失敗,即撥打失敗 { } 說明:self.callID如果返回空則代表呼叫失敗,可能是參數錯誤引起。否則返回是一串數字,是當前通話的標識。
[[ECDevice sharedInstance].VoIPManager setVideoView:remoteVideoView andLocalView:localVideoView]; self.callID = [[ECDevice sharedInstance].VoIPManager makeCallWithType:VIDEO andCalled: @ "John的登錄號碼"]; if (self.callid.length <= 0)//獲取CallID失敗,即撥打失敗 { } 說明:self.callID如果返回空則代表呼叫失敗,可能是參數錯誤引起。否則返回是一串數字,是當前通話的標識。 視頻時(包含點對點和會議),設置遠端UIView的屬性contentMode:(setVideoView:remoteVideoView) UIViewContentModeScaleToFill //view默認值,圖像數據顯示,填充view,但不等比例拉伸 UIViewContentModeScaleAspectFit //圖像等比例拉伸,完全顯示內容 UIViewContentModeScaleAspectFill //圖像等比例拉伸,填充view,部分內容可能不顯示
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSError *parseError = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userInfo options:NSJSONWritingPrettyPrinted error:&parseError]; NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"推送內容" message:str delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", @"OK") otherButtonTitles:nil]; [alert show]; NSLog(@"遠程推送str:%@",str); NSLog(@"遠程推送1:%@",userInfo); NSLog(@"遠程推送r:%@",[userInfo objectForKey:@"r"]); NSLog(@"遠程推送s:%@",[userInfo objectForKey:@"s"]); self.callid = nil; NSString *userdata = [userInfo objectForKey:@"c"]; NSLog(@"遠程推送userdata:%@",userdata); if (userdata) { NSDictionary*callidobj = [NSJSONSerialization JSONObjectWithData:[userdata dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"遠程推送callidobj:%@",callidobj); if ([callidobj isKindOfClass:[NSDictionary class]]) { self.callid = [callidobj objectForKey:@"callid"]; } } NSLog(@"遠程推送 callid=%@",self.callid); } 然后需要實現 /** @brief 需要獲取的離線呼叫CallId (用于蘋果推送下來的離線呼叫callid) @return 消息數 -1:全部獲取 0:不獲取 */ - (NSString*)onGetOfflineCallId { NSLog(@"推送 onGetOfflineCallId=%@", [AppDelegate shareInstance].callid); return [AppDelegate shareInstance].callid; }
注意:在集成音視頻通話的時候,當結束當前通話的時候,需要在處理回調事件的onCallEvents中調用一下releaseCall方法,以保證當前通話占用的資源都釋放了,避免在下次呼叫的時候出現線路被占用現象。(android、ios均需這樣操作),Ios的調用地方,onCallEvents中的ECallEnd,代碼如下:
//有呼叫,調起對應的界面 - (NSString*)onIncomingCallReceived:(NSString*)callid withCallerAccount:(NSString *)caller withCallerPhone:(NSString *)callerphone withCallerName:(NSString *)callername withCallType:(CallType)calltype;{ //注意:如果Tony呼叫的是John的電話,則John的程序不會收到通知回調,而且直接 //進入PSTN網絡,和正常打電話一樣了。 if(calltype == VOICE) { NSlog(@“網絡音頻呼叫,調起音頻呼叫的界面”); else if(CallType == VIDEO) { NSLog (@“網絡音頻呼叫,調起視頻呼叫的界面”); } } // 主叫端呼叫的時候,會有多種狀態 呼叫事件的回調 (1)需要注冊一個通知,告知外部呼叫的狀態 - (void)onCallEvents:(VoIPCall*)voipCall { [[NSNotificationCenter defaultCenter] postNotificationName:KNOTIFICATION_onCallEvent object:voipCall]; } (2)外部成為觀察者,并在通知里面監聽呼叫的狀態 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onCallEvents:) name:KNOTIFICATION_onCallEvent object:nil]; 監聽呼叫的狀態 -(void)onCallEvents:(NSNotification *)notification { VoIPCall* voipCall = notification.object; if (![self.callID isEqualToString:voipCall.callID]){return;} // 呼叫的狀態 ECallProceeding = 0, //外呼,服務器回100Tring ECallAlerting, //外呼對方振鈴 ECallFailed, //外呼失敗 ECallRing, //呼叫振鈴 ECallStreaming, //通話,外呼和來電 ECallReleasing, //釋放呼叫請求中 ECallPaused, //呼叫保持 ECallPausedByRemote, //呼叫被保持 ECallResumed, //呼叫恢復 ECallResumedByRemote, //呼叫被恢復 ECallTransfered, //呼叫被轉移 ECallEnd //呼叫釋放 switch (voipCall.callStatus) { case ECallProceeding: { } break; case ECallStreaming: { } break; case ECallAlerting: { } break; case ECallEnd: { } break; case ECallRing: { } break; case ECallPaused: { } break; case ECallPausedByRemote: { } break; case ECallResumed: { } break; case ECallResumedByRemote: { } break; case ECallTransfered: { } break; case ECallFailed: { NSlog(@"Tony收到呼叫John失敗的回調"); if( voipCall.reason == ECErrorType_NoResponse) { NSLog(@"網絡不給力"); } else if( voipCall.reason == ECErrorType_BadCredentials ) { NSLog(@"鑒權失敗"); } else if ( voipCall.reason == ECErrorType_CallBusy || voipCall.reason == ECErrorType_Declined ) { NSLog(@"您撥叫的用戶正忙,請稍后再撥"); } else if( voipCall.reason == ECErrorType_NoResponse) { NSLog(@"對方不在線"); } else if( voipCall.reason == ECErrorType_CallMissed ) { NSLog(@"呼叫超時"); } else if( voipCall.reason == ECErrorType_NoNetwork ) { NSLog(@"當前無網絡"); } else if( voipCall.reason == ECErrorType_SDKUnSupport) { NSLog(@"該版本不支持此功能"); } else if( voipCall.reason == ECErrorType_CalleeSDKUnSupport ) { NSLog(@"對方版本不支持音頻"); } else { NSLog(@"呼叫失敗"); } } break; case ECallEnd: { //無論是Tony還是John主動結束通話,雙方都會進入到此回調 NSLog(@"掛機"); } break; default: break; } }
2.2、被叫端界面的處理
假設John側調起來音頻或者視頻呼入的界面,界面上有“接受”和“拒絕”兩個按鈕:
(1)John點擊“接受”按鈕,則調用的代碼是 //如果視頻呼叫,則在接受呼叫之前,需要先設置視頻通話顯示的view [[ECDevice sharedInstance].VoIPManager setVideoView:remoteVideoView andLocalView:localVideoView]; NSInteger ret = [[ECDevice ShareIntance].VoIPManager acceptCall:self.callID withType: VOICE(視頻: VIDEO)]; if (ret == 0)// 音頻或視頻通話界面 { NSLog (@“被叫端接受呼叫成功”); } else { NSlog(@“被叫端接受呼叫失敗”); } (2)John點擊“拒絕”按鈕,音視頻拒絕的代碼是一致的,調用的代碼是: NSInteger ret = [[ECDevice ShareIntance].VoIPManager rejectCall:self.callID withType: CallType.Voice]; if (ret == 0) { NSLog (@“被叫端拒絕呼叫成功”); } else { NSLog (@“被叫端拒絕呼叫失敗”); }
[[ECDevice ShareIntance].VoIPManager releaseCall:mCurrentID];
(1)獲取通話ID
[[ECDevice sharedInstance].VoIPManager getCurrentCall; 功能:獲取當前通話的callid, 參數:無 返回值:當前通話id
(2)發送DTMF
[[ECDevice sharedInstance].VoIPManager sendDTMF:(NSString *)callid dtmf:(NSString *)dtmf; 功能:獲取當前通話的callid, 參數:callid-通話id dtmf-鍵值 - 返回值:當前通話id
(3)設置揚聲器狀態
[ECDevice sharedInstance] .VoIPManager enableLoudsSpeaker:(BOOL)enable; 功能:免提設置 參數:enable - NO:關閉 YES:打開 返回值:無
(4)獲取揚聲器狀態
[ECDevice sharedInstance].VoIPManager getLoudsSpeakerStatus; 功能:獲取當前免提狀態 參數:enable - NO:關閉 YES:打開 返回值:無
(5)設置靜音
[ECDevice sharedInstance].VoIPManager setMute:(BOOL)on 功能:靜音設置 參數:enable - NO:正常 YES:靜音 返回值:無
(6)獲取靜音的狀態
[ECDevice sharedInstance].VoIPManager getMuteStatus 功能:獲取當前靜音狀態 參數:enable - NO:正常 YES:靜音 返回值:無
(7)接近檢測,通話時如果貼近聽筒,關閉屏幕(暫緩提供)
[ECDevice sharedInstance].VoIPManager enterVoipCallFlow:(BOOL)status 功能:是否抑制馬賽克 參數:NO:關閉 YES:打開 返回值:無
(8)設置視頻通話顯示的窗口
[ECDevice sharedInstance].VoIPManager setVideoView:(UIView*)view andLocalView:(UIView*)localView 功能:視頻通話顯示的view, 參數:view-對方顯示視圖和本地顯示視圖 返回值:無
(9)獲取手機攝像頭參數
[ECDevice sharedInstance].VoIPManager getCameraInfo 功能:獲取攝像設備信息 參數:無 返回值: 攝像設備信息數組
(10)切換前置和后置攝像頭
[[ECDevice sharedInstance].VoIPManager selectCamera:(NSInteger)cameraIndex capability:(NSInteger)capabilityIndex fps:(NSInteger)fps rotate:(ECRotate)rotate force:(BOOL)isForce scale:(CGFloat)scale] 功能:選擇使用的攝像設備 參數:cameraIndex-設備index capabilityIndex-能力index fps-幀率 rotate-旋轉的角度 isForce 是否強制啟動本SDK調用的攝像頭,默認使用NO scale 編碼縮放,正實數。默認1.0,小于1.0縮小,大于1.0放大 返回值: 攝像設備信息數組
(11)設置編碼范式
[ECDevice sharedInstance].VoIPManager setCodecEnabledWithCodec:(ECCodec) codec andEnabled:(BOOL) enabled 功能:設置支持的編解碼方式 參數:codec-編解碼類型 enabled- NO:不支持 YES:支持 返回值: 無
(12)獲取編解碼方式是否支持
[ECDevice sharedInstance].VoIPManager getCondecEnabelWithCodec:(ECCodec) codec 功能:獲取編解碼方式是否支持 參數:codec-編解碼類型 返回值: NO:不支持 YES:支持
(13)設置音頻處理的類型和對用的處理模式
[ECDevice sharedInstance].VoIPManager setAudioConfigEnabledWithType:(ECAudioType) type andEnabled:(BOOL) enabled andMode:(NSInteger) mode 功能:設置音頻處理的開關 參數:type-音頻處理類型 enabled-YES:開啟,NO:關閉 mode-各自對應的模式: AUDIO_AgcMode、AUDIO_EcMode、AUDIO_NsMode. 返回值: 成功 0 失敗 -1
(14)獲取音頻處理的開關
[ECDevice sharedInstance].VoIPManager getAudioConfigEnabelWithType:(ECAudioType) type 功能:獲取音頻處理的開關 參數:type-音頻處理類型 enabled-YES:開啟,NO:關閉 返回值: 成功:音頻屬性結構 失敗:nil
(15)統計通話質量
[ECDevice sharedInstance].VoIPManager getCallStatisticsWithCallid:(NSString*) digid andType:(CallType)type 功能:統計通話質量 返回值: 返回丟包率等通話質量信息對象
(16)獲取通話的網絡流量信息
[ECDevice sharedInstance].VoIPManager getNetworkStatisticWithCallId:(NSString*) callid 獲取通話的網絡流量信息 參數:callid :會話ID,會議類傳入房間號 返回值:網絡流量信息對象
(17)設置視頻通話碼率
[ECDevice sharedInstance].VoIPManager setVideoBitRates:(NSInteger)bitrates 設置視頻通話碼率 參數:bitrates 視頻碼流,kb/s,范圍30-300 返回值:無
(18)獲取服務器callSid,建議通話建立后獲取。
[[ECDevice sharedInstance].VoIPManager getServerIdFromCallId:callid 參數:callid-通話id 返回值:callSid
(19)獲取用戶在線狀態
/** @brief 獲取用戶在線狀態 @brief userAccs 用戶賬號數組 @param completion 執行結果回調block */ -(void)getUsersState:(NSArray *)userAccs completion:(void(^)(ECError* error, NSArray* usersState)) completion; 例: userAccs = @”用戶賬號數組”;//每次最多獲取50人 [[ECDevice sharedInstance] getUsersState: userAccs completion:^(ECError* error, NSArray* usersState) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([strongSelf.sessionId isEqualToString:state.userAccs]) {// 判斷是否是本次會話id if (state.isOnline) { //顯示他人的在線狀態 _stateLabel.text = [NSString stringWithFormat:@"%@-%@", [strongSelf getDeviceWithType:state.deviceType], [strongSelf getNetWorkWithType:state.network]]; } else { //顯示他人的不在線狀態 _stateLabel.text = @"對方不在線"; } } }];
(20)單應用多證書
/** @brief 多證書設置 @param pushCerKey 推送證書標識,與服務器上傳證書保持一致 */ [[ECDevice sharedInstance] setPushCerKey:@"小余6位數字或字母"];
(21)設置網絡代理
/** @brief 設置網絡代理,需要走代理時登錄前設置,不支持ssl;socks5代理支持IM和點對點音視頻(關閉p2p),http代理支持IM @param proxyHost 代理服務器地址,最大長度255。當設置空時,取消代理 @param proxyPort 代理端口 @param type 鑒權類型。 目前支持 0 不鑒權;2 用戶名密碼鑒權 @param authName 用戶名,最大長度255。authType=2時有效 @param authPwd 用戶名密碼,最大長度255。authType=2時有效 @param proxyType 代理類型。 目前支持 0 socks5代理;1 http代理 @return 0成功,非0失敗 */ [[ECDevice sharedInstance] setNetworkProxy:(NSString*)proxyHost port:(NSInteger)proxyPort authType:(NSInteger)type name:(NSString*)authName pwd:(NSString*)authPwd ProxyType:(NSInteger)proxyType];
文檔更新時間:2017年12月4日