# 通话管理

本文将介绍用于坐席通话中的功能。

# 通话属性变化

通话属性变化通过实现 JCAgentCallback 中的 onCallPropertyChange (opens new window) 接口上报

/**
 * 通话属性改变,重点关注屏幕共享
 * @param changeParam 通话改变的属性
 */
- (void)onCallPropertyChange:(JCMediaChannelPropChangeParam *)changeParam;

propChangeParam (opens new window) 中有对应通话属性的 boolean 值,有变化的为 true,没有变化为 false

# 成员属性变化

成员属性变化通过实现 JCAgentCallback 中的 onMemberUpdate (opens new window) 接口上报

/**
 * 成员变化
 * @param part 变化的成员
 * @param changeParam 变化的属性
 */
- (void)onMemberUpdate:(JCMediaChannelParticipant *)part changeParam:(JCMediaChannelParticipantChangeParam *)changeParam {
    if (changeParam.video) {
        if (part.video) {
        	// 视频流打开
        } else {
        	// 视频流关闭
        }
    }
    if (changeParam.audio) {
        if (part.audio) {
        	// 视频流打开
        } else {
        	// 视频流关闭
        }
    }
}

changeParam 中有对应会议成员属性的 boolean 值,有变化的为 true,没有变化为 false

# 获取所有通话成员

通过 JCAgent.getParticipants (opens new window) 获取所有参会者成员,JCMediaChannelParticipant (opens new window) 类见API文档。

/// 获取当前通话中的所有成员
@property (nonatomic, readonly, strong) NSArray <JCMediaChannelParticipant *> *participants;

# 通话保持/取回

通话中坐席可发起保持通话的操作,保持通话之后坐席和访客皆停发音视频数据,双方将互相听不到声音看不到视频画面。

接口原型:

/// 保持取回
/// @note
/// - 可以通过 {@link getHoldState} 获取当前通话是否保持
/// - 保持通话后双方互相停止音视频流收发
/// - 其他通话中的成员将会收到{@link  JCGuestCallback#onHeldNotify: onHeldNotify} 事件
/// @param hold true:保持;false:取回
/// @return 调用是否成功
- (bool)setHoldState:(bool)hold;
/// 当前通话是否保持
/// @return 当前通话是否保持
/// - true:当前通话状态为保持
/// - false:当前通话状态为正常
- (bool)getHoldState;

通话保持之后,参加通话的所有成员都将收到被保持的通知

/// 收到保持取回的通知
/// @param held true:被保持; false:取回
- (void)onHeldNotify:(bool)held;

onHeldNotify (opens new window) 调用示例:

// 保持
[_agent setHoldState:true];

// 取回
[_agent setHoldState:false];

- (void)onHeldNotify:(bool)held {
    if (held) {
        // 通话保持
    } else {
        // 通话取回
    }
}

# 音视频通话切换

通话中坐席与访客皆可发起音视频通话切换的操作。

视频通话状态下坐席访客互相可听到对方声音看到视频画面,语音通话状态下坐席访客只能听到对方声音,看不到对方视频画面。

接口原型:

/// 音视频通话切换
/// @note
/// - 可以通过{@link getCallType: getCallType}接口获取到当前的通话类型
/// - 通话中所有成员都将收到{@link JCGuestCallback#onCallTypeTurnedNotify: onCallTypeTurnedNotify}事件
/// @param calltype
/// - @ref JCAgentCallTypeVideo :转化为视频通话;
/// - @ref JCAgentCallTypeAudio :转化为语音通话
/// @see JCAgentCallType
- (void)turnCallType:(JCAgentCallType)calltype;
/// 获取当前通话类型
/// @return 当前通话类型
/// - @ref JCAgentCallTypeAudio :语音通话
/// - @ref JCAgentCallTypeVideo :视频通话
/// @see JCAgentCallType
- (JCAgentCallType)getCallType;

通话类型切换之后,参加通话的所有成员都将收到通话类型切换的通知。

/// 音视频通话切换通知
/// @param callType 1:视频通话; 0:语音通话
/// @see JCAgentCallType
- (void)onCallTypeTurnedNotify:(JCAgentCallType)callType;

onCallTypeTurnedNotify (opens new window) 调用示例:

// 切换到语音通话
[_agent turnCallType:JCAgentCallTypeAudio];

// 切换到视频通话
[_agent turnCallType:JCAgentCallTypeVideo];

- (void)onCallTypeTurnedNotify:(JCAgentCallType)callType {
    if (callType == JCAgentCallTypeAudio) {
        // 切换为语音通话
    } else if (callType == JCAgentCallTypeVideo) {
        // 切换为视频通话
    }
}

# 控制音频流上传

开启关闭发送本地音频流。

/**
 * 开启关闭发送本地音频流,结果通过回调OnParticipantUpdate通知
 * @param enable 是否开启本地音频流
 * @return 接口调用成功返回 true,失败返回 false
 */
- (bool)enableAudio:(bool)enable;

会议内成员音频流变化通过实现 JCAgentCallback 中的 onMemberUpdate (opens new window) 接口上报。

/**
 * 成员变化
 * @param part 变化的成员
 * @param changeParam 变化的属性
 */
- (void)onMemberUpdate:(JCMediaChannelParticipant *)part changeParam:(JCMediaChannelParticipantChangeParam *)changeParam {
    if (changeParam.audio) {
        //音频流打开
    } else {
        //音频流关闭
    }
}

# 控制视频流上传

开启关闭发送本地视频流。

/**
 * 开启关闭发送本地视频流,结果通过回调OnParticipantUpdate通知
 * @param enable 是否开启本地视频流
 * @return 接口调用成功返回 true,失败返回 false
 */
- (bool)enableVideo:(bool)enable;

会议内成员视频流变化通过实现 JCAgentCallback 中的 onMemberUpdate (opens new window) 接口上报。

/**
 * 成员变化
 * @param part 变化的成员
 * @param changeParam 变化的属性
 */
- (void)onMemberUpdate:(JCMediaChannelParticipant *)part changeParam:(JCMediaChannelParticipantChangeParam *)changeParam {
    if (changeParam.video) {
        //视频流打开
    } else {
        //视频流关闭
    }
}

# 网络状态监听

视频通话过程中,与会者的网络状态发生变化导致视频通话出现质量波动的时候,SDK会通过回调事件进行上报。

/**
 成员变化
 
 @param part 变化的成员
 @param changeParam 变化的属性
 */
- (void)onMemberUpdate:(JCMediaChannelParticipant *)part changeParam:(JCMediaChannelParticipantChangeParam *)changeParam;

示例代码:

- (void)onMemberUpdate:(JCMediaChannelParticipant *)part changeParam:(JCMediaChannelParticipantChangeParam *)changeParam {
    if (changeParam.netStatus) {
        switch (part.netStatus) {
            case JCMediaChannelnetStatusDisconnected:
                // 断开
                break;
            case JCMediaChannelnetStatusVeryBad:
                // 非常差
                break;
            case JCMediaChannelnetStatusBad:
                // 差
                break;
            case JCMediaChannelnetStatusNormal:
                // 一般
                break;
            case JCMediaChannelnetStatusGood:
                // 好
                break;
            case JCMediaChannelnetStatusVeryGood:
                // 很好
                break;
                
            default:
                break;
        }
    }
}