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日