# 实现一对一通话
本章将介绍如何实现一对一语音通话,一对一语音通话的 API 调用时序见下图:
# 初始化
调用 JCMediaDevice create (opens new window) 和 JCCall create (opens new window) 以初始化实现一对一通话需要的模块。
//初始化
-(bool)initialize {
//1. 媒体类
JCMediaDevice *mediaDevice = [JCMediaDevice create:client callback:self];
//2. 通话类
JCCall *call = [JCCall create:client mediaDevice:mediaDevice callback:self];
...
}
其中:
- JCMediaDevice create 方法中的 callback 为 JCMediaDeviceCallback (opens new window) 协议的代理对象,该协议用于将媒体设备相关的事件通知给上层。因此需要先指定 callback 的代理对象,然后在该代理对象中实现 JCMediaDeviceCallback 的方法。
JCMediaDeviceCallback 中的主要方法如下。
//摄像头变化
-(void)onCameraUpdate;
//音频输出变化
-(void)onAudioOutputTypeChange:(NSString*)audioOutputType;
//声音中断恢复
-(void)onAudioInerruptAndResume:(BOOL)interrupt;
- JCCall create 方法中的 callback 为 JCCallCallback (opens new window) 协议的代理对象,该协议用于将通话相关的事件通知给上层。因此需要先指定 callback 的代理对象,然后在该代理对象中实现 JCCallCallback 的方法。
JCCallCallback 中的主要方法如下。
//新增通话回调
-(void)onCallItemAdd:(JCCallItem* __nonnull)item;
//移除通话
-(void)onCallItemRemove:(JCCallItem* __nonnull)item reason:(JCCallReason)reason description:(NSString * __nullable)description;
//通话状态更新回调(当上层收到此回调时,可以根据 JCCallItem 对象获得该通话的所有信息及状态,从而更新该通话相关UI)
-(void)onCallItemUpdate:(JCCallItem* __nonnull)item changeParam:(JCCallChangeParam * __nullable)changeParam;
# 拨打通话
调用 call (opens new window)发起语音通话,需要填写的参数有:
userID
填写对方的用户ID。video
选择是否为视频通话, true 表示拨打视频通话, false 表示拨打语音通话。callParam
通话参数对象,此参数可为空,详细定义见:JCCallParam (opens new window)。
// 发起语音呼叫
JCCallParam *param = [[JCCallParam alloc] init];
[call call:@"userID" video:false callParam:param];
拨打通话后,主叫和被叫均会收到新增通话的回调 onCallItemAdd (opens new window) ,此时通话状态变为 JCCallStatePending 。您可以在上层实现 onCallItemAdd (opens new window) 方法并处理相关的逻辑。
示例代码
// 收到新增通话回调
-(void)onCallItemAdd:(JCCallItem* __nonnull)item {
// 业务逻辑
if (item.direction == JCCallDirectionIn) {
// 如果是呼入
...
} else {
// 如果是呼出
...
}
}
TIP
如果主叫想取消通话,可以直接转到挂断通话部分。调用挂断接口后,通话状态变为 JCCallStateCancel。
# 应答通话
主叫发起呼叫成功后,被叫会收到 onCallItemAdd (opens new window) 回调,此时可以通过回调中的 JCCallItem (opens new window) 对象的 video 以及 direction 属性判断是视频呼入还是语音呼入,从而做出相应的处理。
-(void)onCallItemAdd:(JCCallItem* __nonnull)item { // 1. 如果是语音呼入且在振铃中 if (item && item.direction == JCCallDirectionIn && !item.video) { // 2. 做出相应的处理,如在界面上显示“振铃中” ... } }
调用 answer (opens new window) 接听通话,语音通话只能进行语音应答 。
// 应答通话 [call answer:item video:false];
通话应答后,通话状态变为 JCCallStateConnecting。
TIP
如果被叫要在此时拒绝通话,可以直接转到挂断通话部分。调用挂断接口后,通话状态变为 JCCallStateCanceled。
# 挂断通话
主叫或者被叫均可以挂断通话。
首先调用 getActiveCallItem (opens new window) 获取当前活跃的通话对象;
当前活跃通话对象获取后,调用 term (opens new window) 挂断当前活跃通话:
// 1. 获取当前活跃通话 JCCallItem *item = [call getActiveCallItem]; // 2. 挂断当前活跃通话 [call term:item reason:JCCallReasonNone description:@"主叫挂断"];
通话挂断后,会触发 JCCallCallback 中的 onCallItemRemove(通话移除回调),通话状态变为 JCCallStateOk。