文档反馈
文档反馈

跑通呼叫组件(iOS)

重要通知

网易云信新版文档中心现已正式上线!

音视频通话2.0互动直播2.0多人语音聊天室PK 直播等产品和场景方案已迁移至新版文档中心维护,欢迎体验!

为了方便开发者快速接入音视频通话 2.0,提升应用的研发效率,音视频通话 2.0 和信令产品携手为您打造应用层呼叫组件 NERTCCallkit,组件中集成了音视频通话 2.0 和信令的多项基础功能,全方位提升接入效率。

NERTCCallkit 呼叫组件的 API 接口概览请查看组件概述

准备工作

注意事项

组件结构

NERtcCallKit 文件夹为音视频管理类,其中包含初始化、登录、呼叫、邀请等逻辑的相关操作管理。详细组件结构如下:

文件夹 说明
NERtcCallKit.h 封装层实现 protocal NERtcCallKitDelegate 封装实例方法。
NERtcCallKitDelegateProxy.h 代理proxy的头文件。Demo业务层,可不关注。
NERtcCallOptions.h 组件推送配置。
NERtcCallKitContext.h 存储用户相关信息。Demo业务层,可不关注。
NERtcCallKit+Private.h 组件封装私有的实例方法。
NERtcCallKitConsts.h 定义类型的枚举。
Consts 文件夹 定义 NERtcCallKitErrors 的头文件。
Utils 文件夹 生成信令唯一标识 requestID 。Demo业务层,可不关注。
Status 文件夹 INERtcCallStatus.h 组件的接口。
NERtcCallStatusIdleImpl.h 底层 NERTC 封装的实例方法。
NERtcCallStatusCallingImpl.h 底层 NERTC 封装的实例方法。
NERtcCallStatusCalledImpl.h 底层 NERTC 封装的实例方法。
NERtcCallStatusInCallImpl.h 底层 NERTC 封装的实例方法。

集成组件

Demo 中 以 CocoaPods形式导入音视频 2.0 SDK。

实现 UI 界面

如需快速接入 NERTCCallkit 呼叫组件,您可以直接基于我们提供的组件 Demo 进行修改适配,也可以自行实现自定义的 UI 界面。

NERTCCallkit 呼叫组件源码中,UI 模块路径为:NIMDemo/Classes/Sections/Session/ViewController/RTCVideoChat

实现组件基本功能

步骤一 初始化组件

通过以下代码初始化 NERTCCallkit 组件:

// 在AppDelegate中初始化
- (void)setupRTCKit {
    // 读取配置的appkey信息
    NSString *appKey = [[NTESDemoConfig sharedConfig] appKey];
    // 配置 NERtcCallOptions
    NERtcCallOptions *option = [NERtcCallOptions new];
    option.APNSCerName = [[NTESDemoConfig sharedConfig] apnsCername];
    // 初始化 组件
    [[NERtcCallKit sharedInstance] setupAppKey:appKey options:option];
}

步骤二 登录

调用 login 函数完成组件的登录。

呼叫组件与 IM 的 login 方法可共用,如果 IM 登录成功,组件可以不再调用 login 函数。

// userID为云信的accid,token为云信的token
[[NERtcCallKit sharedInstance] login:userID token:token completion:^(NSError * _Nullable error) {
    //  根据登录回调处理业务
}];

设置 Token

组件默认使用安全模式。如果 tokenHandler 为 nil 表示非安全模式,请联系商务经理开通安全模式。

安全模式下需要获取并传入 Token。详细操作请参考获取 Token。在线上环境中,Token 的获取需要放到您的应用服务端完成,然后由服务器通过安全通道把 Token 传递给客户端。

注意:Demo 中使用的 URL 仅仅是 demoserver,复用相关内容时请替换URL。

// 安全模式音视频房间token获取,nil表示非安全模式. Block中一定要调用complete
@property (nonatomic, copy, nullable) NERtcCallKitTokenHandler tokenHandler;
可参考 NTESAppDelegate.m 中的 setupRTCKit 方法实现。
//注册获取token的服务
 NERtcCallKit.sharedInstance.tokenHandler = ^(uint64_t uid, void (^complete)(NSString *token, NSError *error)) {
    [NTESRtcTokenUtils requestTokenWithUid:uid appKey:appKey completion:^(NSError * _Nullable error, NSString * _Nullable token) {
        complete(token, error);
    }];
 };

步骤四 发起呼叫

调用 call 方法发起一对一呼叫;或调用 groupcall方法,发起多人呼叫。

Demo中的实现方式为:

  1. 通过 onTapMediaItemVideoChat 方法初始化 NECallViewController 类,获取该对象的方法。
  2. 通过 initWithOtherMember 传入 userID 和当前通话类型。

    您可以根据业务需求实现该 NECallViewController,获取 userID 及通话类型。

    • 一对一呼叫:

        // 组件封装的点对点呼叫方式
        // self.otherUserID 为对方accid,type为NERtcCallType的枚举类型
        //
        [[NERtcCallKit sharedInstance] call:self.otherUserID type:self.type completion:^(NSError * _Nullable error) {
                if (!error) {
                //  根据登录回调处理业务
                }
        }];
    • 多人通话:
        /// 多人呼叫
        /// @param userIDs  呼叫的用户ID数组
        /// @param type 通话类型
        /// @param completion 回调
        [[NERtcCallKit sharedInstance] groupCall:self.otherMembers type:NERtcCallTypeVideo completion:^(NSError * _Nullable error) {
                    if (!error) {
                //  根据登录回调处理业务
                    }
                }];

步骤五 配置监听

调用 onInvited 方法配置监听。实现详情请参考组件中的 NERtcCallKit.h 文件。

/// 收到邀请的回调
/// @param invitor 邀请方
/// @param userIDs 房间中的被邀请的所有人(不包含邀请者)
/// @param isFromGroup 是否是群组
/// @param groupID 群组ID
/// @param type 通话类型
- (void)onInvited:(NSString *)invitor
          userIDs:(NSArray<NSString *> *)userIDs
      isFromGroup:(BOOL)isFromGroup
          groupID:(nullable NSString *)groupID
             type:(NERtcCallType)type;

/// 接受邀请的回调
/// @param userID 接受者
- (void)onUserEnter:(NSString *)userID;

/// 拒绝邀请的回调
/// @param userID 拒绝者
- (void)onUserReject:(NSString *)userID;

/// 取消邀请的回调
/// @param userID 邀请方
- (void)onUserCancel:(NSString *)userID;

/// 用户离开的回调
/// @param userID 用户userID
- (void)onUserLeave:(NSString *)userID;

/// 用户异常离开的回调
/// @param userID 用户userID
- (void)onUserDisconnect:(NSString *)userID;

/// 用户接受邀请的回调
/// @param userID 用户userID
- (void)onUserAccept:(NSString *)userID;

/// 忙线
/// @param userID 忙线的用户ID
- (void)onUserBusy:(NSString *)userID;

/// 通话结束
- (void)onCallEnd;

/// 呼叫超时
- (void)onCallingTimeOut;

/// 连接断开
/// @param reason 断开原因
- (void)onDisconnect:(NSError *)reason;

/// 发生错误
- (void)onError:(NSError *)error;

/// 启用/禁用相机
/// @param available 是否可用
/// @param userID 用户ID
- (void)onCameraAvailable:(BOOL)available userID:(NSString *)userID;

/// 启用/紧用麦克风
/// @param available 是否可用
/// @param userID 用户userID
- (void)onAudioAvailable:(BOOL)available userID:(NSString *)userID;

/// 网络状态监测回调
/// @param stats key为用户ID, value为对应网络状态
- (void)onUserNetworkQuality:(NSDictionary<NSString *, NERtcNetworkQualityStats *> *)stats;

/// 呼叫请求已被其他端接收的回调
- (void)onOtherClientAccept;

/// 呼叫请求已被其他端拒绝的回调
- (void)onOtherClientReject;

步骤六 配置接听方式

调用 accept 方法配置接听方式。实现详情请参考组件中的 NERtcCallKit.h 文件。

// 组件封装的接听方式
[[NERtcCallKit sharedInstance] accept:^(NSError * _Nullable error, NSArray<NSString *> * _Nullable joinedMembers) {
        //  根据登录回调处理业务
}];

步骤七 挂断

调用 hangup 方法挂断通话。

// 组件封装的挂断方式
[[NERtcCallKit sharedInstance] hangup:^(NSError * _Nullable error) {
        [self destroy];
}];

步骤六 获取话单

呼叫组件提供通话话单功能,在一通通话结束后,您会收到对应的通话话单。通话话单是一条事件通知消息,以 IM 会话类型消息抄送的形式发送,收到话单后,您可以解析消息体,获得通话时间等通话详情。

说明

正常挂断

通话正常挂断时,Demo 中的实现流程为:

  1. NIMRtcCallStatus 状态变更为 NIMRtcCallStatusComplete
  2. 调用组件封装的 hangup 方法挂断之后,服务器会正常下发正常结束的话单。
  3. 客户端会通过接收消息的回调 onRecvMessages 方法,收到一条类型为 NIMMessageTypeRtcCallRecord 的消息。
  4. 对消息进行解析并上报到业务层进行展示。

在正常挂断的情况下,您可以通过以下头文件实现话单功能解析及展示:

非正常挂断

异常挂断的情况下,业务层需要主动调用 cancel 方法。

// 取消通话
[[NERtcCallKit sharedInstance] cancel:^(NSError * _Nullable error) {}];

组件话单由组件内部发送,直接提供给对方,其中包含超时、忙线、拒绝的消息。

组件底层通过调用 NERtcCallKit.m 文件中的 send1to1CallRecord 方法实现话单。您也可以自行实现相关逻辑。

实现流程如下:

  1. 调用 SDK 发送点对点消息 sendMessage。
  2. 通过封装信息之后,发送给对方。
  3. 对方收到消息解析。

话单消息结构

话单以 IM 消息抄送的形式发送,抄送类型为会话类型,即 eventType 为 1。会话类型的消息体中一般包含 eventType、convType、to、fromAccount、msgTimestamp、msgType、msgidClient、msgidServer、attach 等字段,其中:

attach 字段说明:

字段 类型 示例 说明
type 1 通话类型。
  • 1:音频通话
  • 2:视频通话
channelId Number 123 房间 ID。
status Number 1 呼叫状态。
  • 1:通话正常结束。
  • 2:主叫取消呼叫。
  • 3:被叫拒绝通话。
  • 4:被叫未接听呼叫,呼叫因超时被取消。
  • 5:被叫忙线,通话未接通。
durations JsonArray - 通话过程详情,JSON 数组格式,其中包括:
  • accid:通话成员的 accid。
  • duration:对应成员的通话时长。

完整话单的 JSON 示例:

{
  "msgTimestamp": "1611904620759",
  "msgType": "NRTC_NETCALL",
  "msgidServer": "11111",
  "fromAccount": "22222",
  "to": "33333",
  "attach": "{\"durations\":[{\"duration\":68,\"accid\":\"22222\"},{\"duration\":68,\"accid\":\"11111\"}],\"type\":2,\"channelId\":1111111,\"status\":1}",
  "eventType": "1",
  "convType": "PERSON",
  "msgidClient": "33333",
  "resendFlag": "0"
}
×

反馈成功

非常感谢您的反馈,我们会继续努力做得更好。