打开NgnSipService.mm文件中有_mSipCallback变量,用来回调事件状态传值。
我们知道idoubs中原来并没有类似于“对方是否在线” “对方是否挂断电话” 但是实际项目中是有这些需求的。
所以,我们自行加入一些变量,用来判断对方的状态!
1.首先我们在定义_NgnSipCallback中来定义几个私有变量:
private:
NgnSipService* mSipService;
NgnBaseService<INgnConfigurationService>* mConfigurationService;
//以下为自己加上的变量
long timeStart; //记录整个开始拨打的时间
long timeEnd; //记录整个结束时间
bool isInComing = false; //判断是否是来电
long inCallTimeStart = 0; //记录接听通话开始的时间
long inCallTimeEnd = 0; //记录接听结束通话的时间
还要给事件添加几个状态:
//枚举
typedef enum NgnInviteEventTypes_othere {
OTHER_DEFAULT, // 对方默认状态
OTHER_ANSWER_NOT, //对方未接听状态
OTHER_ANSWER_OR_REJECT,//对方接听或拒绝状态
OTHER_REJECT //对方拒绝状态
}
NgnInviteEventTypes_other;
//增加属性
@property (nonatomic,assign) NgnInviteEventTypes_other otherInCallstate;
@property (nonatomic,assign) bool otherNotAnswer;
@property (nonatomic,assign) bool otherIsOnLine;
2.找到事件连接状态: tsip_event_code_dialog_connected
再找到 Audio/Video/MSRP(Chat, FileTransfer) 表明是通话的事件
接下来加上代码:
else if (((ngnSipSession = [NgnAVSession getSessionWithId: _sessionId]) != nil) || ((ngnSipSession = [NgnMsrpSession getSessionWithId: _sessionId]) != nil)){
eargs = [[NgnInviteEventArgs alloc]
initWithSessionId: _sessionId
andEvenType:INVITE_EVENT_CONNECTED
andMediaType:((NgnInviteSession*)ngnSipSession).mediaType
andSipPhrase:phrase];
[ngnSipSession setConnectionState:CONN_STATE_CONNECTED];
[((NgnInviteSession*)ngnSipSession) setState:INVITE_STATE_INCALL];
// --------- 拨打电话给对方做判断
if (!isInComing) {
NSLog(@"拨出");
bool otherIsOnLine = true;
bool otherNotAnswer = false;
NgnInviteEventTypes_other otherInCallstate = OTHER_DEFAULT;
timeEnd = [[NSDate date] timeIntervalSince1970];
if (timeStart == 0) {
NSLog(@"对方不在线");
otherIsOnLine = false;
}
else{
otherIsOnLine = true;
NSLog(@"对方在线");
NSLog(@"timeEnd - timeStart === %d",timeEnd - timeStart);
if (timeEnd - timeStart > 28) {
NSLog(@"对方没有接听");
otherNotAnswer = true;
otherInCallstate = OTHER_ANSWER_NOT;
}
else{
NSLog(@"对方接听或拒绝");
otherInCallstate = OTHER_ANSWER_OR_REJECT;
//记录通话开始的时间
inCallTimeStart = [[NSDate date] timeIntervalSince1970];
}
timeStart = 0;
timeEnd = 0;
}
eargs.otherInCallstate = otherInCallstate;
eargs.otherNotAnswer = otherNotAnswer;
eargs.otherIsOnLine = otherIsOnLine;
}
else{
NSLog(@"拨入");
}
[NgnNotificationCenter postNotificationOnMainThreadWithName:kNgnInviteEventArgs_Name object:eargs];
}
3.找到事件状态: tsip_event_code_dialog_terminated 表明结束
同样在Audio/Video/MSRP(Chat, FileTransfer) 下面做处理:
else if (((ngnSipSession = [NgnAVSession getSessionWithId:_sessionId]) != nil) || ((ngnSipSession = [NgnMsrpSession getSessionWithId: _sessionId]) != nil)){
eargs = [[NgnInviteEventArgs alloc]
initWithSessionId:_sessionId
andEvenType:INVITE_EVENT_TERMINATED
andMediaType:((NgnInviteSession*)ngnSipSession).mediaType
andSipPhrase:phrase
andSipCode:_sipCode];
[ngnSipSession setConnectionState:CONN_STATE_TERMINATED];
[((NgnInviteSession*)ngnSipSession) setState:INVITE_STATE_TERMINATED];
NSLog(@"挂断");
isInComing = false;
if (inCallTimeStart!=0) {
inCallTimeEnd = [[NSDate date] timeIntervalSince1970];
NSLog(@"结束时间 %ld",inCallTimeEnd);
NSLog(@"inCallTimeEnd - inCallTimeStart === %ld",inCallTimeEnd - inCallTimeStart);
if (inCallTimeEnd - inCallTimeStart < 2.8) {
NSLog(@"对方拒绝");
eargs.otherInCallstate = OTHER_REJECT;
inCallTimeEnd = 0;
inCallTimeStart = 0;
}
else{
NSLog(@"挂断");
}
}
[NgnNotificationCenter postNotificationOnMainThreadWithName:kNgnInviteEventArgs_Name object:eargs];
if([ngnSipSession isKindOfClass:[NgnAVSession class]]){
[NgnAVSession releaseSession:(NgnAVSession**)&ngnSipSession];
}
else if([ngnSipSession isKindOfClass:[NgnMsrpSession class]]){
[NgnMsrpSession releaseSession:(NgnMsrpSession**)&ngnSipSession];
}
}
4.在tsip_m_early_media下 记录开始时间:
case tsip_m_early_media:
{
if (((ngnSipSession = [NgnAVSession getSessionWithId:_sessionId]) != nil) || ((ngnSipSession = [NgnMsrpSession getSessionWithId: _sessionId]) != nil)){
eargs = [[NgnInviteEventArgs alloc] initWithSessionId:ngnSipSession.id
andEvenType:INVITE_EVENT_EARLY_MEDIA
andMediaType:((NgnInviteSession*)ngnSipSession).mediaType
andSipPhrase:phrase];
timeStart = [[NSDate date] timeIntervalSince1970];
NSLog(@"开始时间记录 ===== ");
[NgnNotificationCenter postNotificationOnMainThreadWithName:kNgnInviteEventArgs_Name object:eargs];
}
break;
}
5.最后使用阶段
在通话或者视频界面 , 通过注册通知中心事件改变状态:
-(void) onInviteEvent:(NSNotification*)notification {
NgnInviteEventArgs* eargs = [notification object];
if(!audioSession || audioSession.id != eargs.sessionId){
return;
}
if (!eargs.otherIsOnLine) {
self.labelStatus.text = @"对方不在线...";
// releases session
[NgnAVSession releaseSession: &audioSession];
// starts timer suicide
[NSTimer scheduledTimerWithTimeInterval: kCallTimerSuicide
target: self
selector: @selector(timerSuicideTick:)
userInfo: nil
repeats: NO];
return;
}
if (eargs.otherNotAnswer) {
self.labelStatus.text = @"无人接听...";
NSLog(@"!!!!对方没有接听");
[NgnAVSession releaseSession: &audioSession];
// starts timer suicide
[NSTimer scheduledTimerWithTimeInterval: kCallTimerSuicide
target: self
selector: @selector(timerSuicideTick:)
userInfo: nil
repeats: NO];
return;
}
switch (eargs.otherInCallstate) {
case OTHER_DEFAULT:{
break;
}
case OTHER_ANSWER_NOT:{
self.labelStatus.text = @"无人接听...";
NSLog(@"~~~~~对方没有接听");
break;
}
case OTHER_ANSWER_OR_REJECT:{
self.labelStatus.text = @"对方接听或拒绝...";
NSLog(@"~~~~~对方接听或拒绝");
break;
}
case OTHER_REJECT:{
self.labelStatus.text = @"对方已挂断...";
NSLog(@"~~~~~对方拒接");
// releases session
[NgnAVSession releaseSession: &audioSession];
// starts timer suicide
[NSTimer scheduledTimerWithTimeInterval: kCallTimerSuicide
target: self
selector: @selector(timerSuicideTick:)
userInfo: nil
repeats: NO];
return;
}
}
switch (eargs.eventType) {
case INVITE_EVENT_INPROGRESS:
case INVITE_EVENT_INCOMING:
case INVITE_EVENT_RINGING:
case INVITE_EVENT_LOCAL_HOLD_OK:
case INVITE_EVENT_REMOTE_HOLD:
default:
{
// updates view and state
[self updateViewAndState];
break;
}
// transilient events
case INVITE_EVENT_MEDIA_UPDATING:
{
self.labelStatus.text = @"语音来电..";
break;
}
case INVITE_EVENT_MEDIA_UPDATED:
{
self.labelStatus.text = @"语音结束中..";
break;
}
case INVITE_EVENT_TERMINATED:
case INVITE_EVENT_TERMWAIT:
{
// updates view and state
[self updateViewAndState];
// releases session
[NgnAVSession releaseSession: &audioSession];
// starts timer suicide
[NSTimer scheduledTimerWithTimeInterval: kCallTimerSuicide
target: self
selector: @selector(timerSuicideTick:)
userInfo: nil
repeats: NO];
// [self performSelectorOnMainThread:@selector(closeView) withObject:nil waitUntilDone:NO];
break;
}
}
}
谢谢啊 如有不对 还请指正!
最近在重整一个app 秉着开源精神 放在github上(目前还在开发阶段 不过每天会更新的)
ZYDoubs