iOS CallLib 开发指南

    开通方式

    音视频服务开通,请参考音视频开通方式说明。

    使用说明

    由于底层引擎技术不同,2.9.0 及之后的音视频 SDK 与 2.9.0 之前的 SDK 中的实时音视频不能互通。

    网络环境要求

    实时音视频对于网络的要求如下:

    1、带宽

    为了获得比较好的视频画质与流畅度,每一路视频的分辨率与带宽的对应关系如下:

    288P: 350kbps
    480P: 500kbps
    720P: 1000kbps
    

    2、延时

    为了保证音视频的实时性,推荐客户端到媒体服务器的 RTT 小于 150ms

    3、丢包

    在媒体层面能够抵抗 30% 的随机丢包

    集成说明

    导入 SDK

    有两种方式可以将 SDK 导入您的项目中:

    • 通过 CocoaPods 管理依赖
    • 手动导入 SDK 并管理依赖

    使用 CocoaPods 导入 SDK

    1、 Cocoapods 的安装、使用,可以参考IM SDK - 下载与导入SDK文档。

    2、 使用 CocoaPods 导入融云 SDK

    在您的工程根目录下新建一个 Podfile 文件,在文件中输入以下内容。(在此以 2.9.0 版本为例,其中 “MyApp” 为自己工程名)

      target 'MyApp' do
        pod 'RongCloudRTC/RongCallLib', '2.9.0'
        pod 'RongCloudRTC/RongCallKit', '2.9.0'
      end
    

    然后在终端中运行以下命令:

      pod install
    

    完成后,CocoaPods 会在您的工程根目录下生成一个 .xcworkspace 文件。您需要通过此文件打开您的工程,而不是之前的 .xcodeproj

    手动导入 SDK

    1、 下载 SDK 您可以到融云官方网站下载SDK。

    2、 融云 IM SDKCall SDK 的基础。使用 CallLib,必须同时集成使用融云 IM SDK。 手动导入 IM SDK,可以参考 IM SDK - 下载与导入 SDK文档。

    SDK 文件说明

    文件 说明 注意事项
    RongCallLib.framework CallLibframework 必须导入
    Blink.framework 通话引擎 必须导入,否则通话功能将无法使用
    Bailingquic.framework quic连接引擎 必须导入,否则通话连接将无法建立

    3、 手动集成了融云 SDK 之后,您需要在您的工程中导入

    • RongCallLib.framewrok
    • Bailingquic.framework
    • Blink.framework
    • CoreGraphics.framework
    • Foundation.framework
    • AudioToolbox.framework
    • UIKit.framework
    • GLKit.framework
    • CoreMedia.framework
    • CFNetwork.framework
    • AVFoundation.framework
    • SystemConfiguration.framework
    • Security.framework
    • CoreFoundation.framework
    • CoreMotion.framework
    • libz.tbd
    • libbz2.tbd
    • libiconv.tbd
    • libstdc++.tbd
    • libresolv.tbd
    • CoreVideo.framework
    • VideoToolbox.framework

    4、 在 Xcode 项目 Build Settings -> Other Linker Flags 中,增加"-ObjC"。

    5、 在 Xcode 项目 Build Settings 中,搜索 Enable Bitcode 将此设置为 NO。

    快速集成

    使用融云通话之前,必须先初始化 SDK 和连接服务器,详细内容可以参考 IMLib 快速集成文档。

    1、发起通话

    您可以调用 RCCallClient 以下接口,发起通话。

    // RCCallCleint Class
    
    /*!
     发起一个通话
    
     @param conversationType 会话类型
     @param targetId         目标会话ID
     @param userIdList       邀请的用户ID列表
     @param type             发起的通话媒体类型
     @param delegate         通话监听
     @param extra            附件信息
    
     @return 呼出的通话实体
     */
    - (RCCallSession *)startCall:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                              to:(NSArray *)userIdList
                       mediaType:(RCCallMediaType)type
                 sessionDelegate:(id<RCCallSessionDelegate>)delegate
                           extra:(NSString *)extra;
    

    其中,您可以通过返回的通话实体,操控通话和获取通话相关信息,通话状态发生变化时会通过您传入的 delegate 进行回调。

    2、接收呼入的通话

    您需要设置 RCCallClient 的全局通话监听,来监听通话呼入。

    // RCCallCleint Class
    
    /*!
     设置全局通话呼入的监听器
    
     @param delegate CallLib全局通话呼入的监听器
     */
    - (void)setDelegate:(id<RCCallReceiveDelegate>)delegate;
    

    3、会话是否支持发起通话

    目前,SDK 支持在单聊发起单人通话,在群聊中发起多人通话。

    您可以通过 RCCallClient 类的以下接口查询当前会话的通话能力。

    // RCCallClient Class
    
    /*!
     当前会话类型是否支持音频通话
    
     @param conversationType 会话类型
    
     @return 是否支持音频通话
     */
    - (BOOL)isAudioCallEnabled:(RCConversationType)conversationType;
    
    /*!
     当前会话类型是否支持视频通话
    
     @param conversationType 会话类型
    
     @return 是否支持视频通话
     */
    - (BOOL)isVideoCallEnabled:(RCConversationType)conversationType;
    

    4、获取当前的通话实体

    您可以通过 RCCallClient 的以下接口,查询当前的通话实体。

    // RCCallClient Class
    
    /*!
    当前的通话会话实体
    */
    @property (nonatomic, strong, readonly) RCCallSession *currentCallSession;
    

    5、设置本地视频属性

    您可以通过 RCCallClient 的以下接口,设置本地视频分辨率。

    // RCCallClient Class
    
    /**
    * 设置本地视频属性,可用此接口设置本地视频分辨率。
    *
    * @param profile profile
    */
    - (void)setVideoProfile:(RCVideoProfile)profile;
    

    您也可以通过 RCCallClient 的以下接口,设置本地视频属性,设置宽和高替换。

    // RCCallClient Class
    
    /**
    设置本地视频属性,可用此接口设置本地视频分辨率,设置宽和高替换
    
    @param profile profile
    @param swapWidthAndHeight 是否交换宽和高  (默认不交换)
    */
    - (void)setVideoProfile:(RCVideoProfile)profile swapWidthAndHeight:(BOOL)swapWidthAndHeight;
    

    6、设置外部信令服务器代理

    您可以通过 RCCallClient 的以下接口,设置外部信令服务器代理。

    // RCCallClient Class
    
    /*!
    设置外部信令服务器代理
    
    @param signalServerDelegate 外部信令服务器代理
    
    @discussion
    默认情况下 app 使用融云消息作为信令即可,不需要设置此代理,此时有个限制就是所有的通话必须在某一个会话中进行,比如群组。如果您需要摆脱会话的限制,请使用 server api 服务实现本代理,然后 startCall 时 conversationType 传 0,targetId 传 nil,calllib 会调用您设置的代理来发送消息。
    请务必使用一个全局代理,确保在拨打和接听 VoIP 的时候代理对象都存活,这样才能确保正常通话。
    */
    - (void)setSignalServerDelegate:(id<RCCallSignalServerDelegate>)signalServerDelegate;
    

    7、通过通话实体操控通话

    通话实体 RCCallSession 包含当前通话的所有信息,您可以通过其中的接口,操控当前通话和获取相关信息,在发起通话和接收到呼入的通话时会获取到相应的通话实体。

    如:接听当前来电。

    // RCCallSession Class
    
    /*!
     接听来电
    
     @param type 接听使用的媒体类型
     */
    - (void)accept:(RCCallMediaType)type;
    

    挂断当前通话。

    // RCCallSession Class
    
    /*!
     挂断通话
     */
    - (void)hangup;
    

    邀请用户加入当前通话(仅限邀请群组中的成员加入)。

    // RCCallSession Class
    
    /*!
     邀请用户加入通话
    
     @param userIdList 用户ID列表
     @param type       建议被邀请者使用的媒体类型
     */
    - (void)inviteRemoteUsers:(NSArray *)userIdList
                   mediaType:(RCCallMediaType)type;
    

    设置视频通话中某个用户的 View 。

    // RCCallSession Class
    
    /*!
     设置用户所在的视频View
    
     @param userId 用户ID(自己或他人)
     @param view   视频的View
     */
    - (void)setVideoView:(UIView *)view
                  userId:(NSString *)userId;
    

    切换自己使用的媒体类型。

    // RCCallSession Class
    
    /*!
     更换自己使用的媒体类型
    
     @param type 媒体类型
     */
    - (BOOL)changeMediaType:(RCCallMediaType)type;
    

    一个通话中,允许每个用户的媒体类型不一致,也就是说可以有些人以视频接入,有些人以音频接入。

    设置静音。

    // RCCallSession Class
    
    /*!
     设置静音状态
    
     @param muted 是否静音
    
     @return 是否设置成功
    
     @discussion 默认值为NO。
     */
    - (BOOL)setMuted:(BOOL)muted;
    

    设置扬声器状态。

    // RCCallSession Class
    
    /*!
     设置扬声器状态
    
     @param speakerEnabled  是否开启扬声器
     @return                是否设置成功
     */
    - (BOOL)setSpeakerEnabled:(BOOL)speakerEnabled;
    

    开启或关闭摄像头。

    // RCCallSession Class
    
    /*!
     设置摄像头状态
    
     @param cameraEnabled  是否开启摄像头
     @return               是否设置成功
    
     @discussion 音频通话的默认值为NO,视频通话的默认值为YES。
     */
    - (BOOL)setCameraEnabled:(BOOL)cameraEnabled;
    

    切换前后摄像头。

    // RCCallSession Class
    
    /*!
     切换前后摄像头
    
     @return 是否切换成功
     */
    - (BOOL)switchCameraMode;
    

    8、获取通话相关信息

    您可以通过通话实体 RCCallSession 中获取当前通话的相关信息。

    当前的通话状态。

    // RCCallSession Class
    
    /*!
     通话的当前状态
     */
    @property (nonatomic, assign, readonly) RCCallStatus callStatus;
    

    通话的发起人和邀请者。

    // RCCallSession Class
    
    /*!
     通话的最初发起人
     */
    @property (nonatomic, strong, readonly) NSString *caller;
    
    /*!
     邀请当前用户加入通话的邀请者
     */
    @property (nonatomic, strong, readonly) NSString *inviter;
    

    通话的开始时间和接通时间。

    // RCCallSession Class
    
    /*!
     通话开始的时间
    
     @discussion 如果是用户呼出的通话,则 startTime 为通话呼出时间;如果是呼入的通话,则 startTime 为通话呼入时间。
     */
    @property (nonatomic, assign, readonly) long long startTime;
    
    /*!
     通话接通时间
     */
    @property (nonatomic, assign, readonly) long long connectedTime;
    

    通话挂断的原因。

    // RCCallSession Class
    
    /*!
     通话挂断原因
     */
    @property (nonatomic, assign) RCCallDisconnectReason disconnectReason;
    

    9、通话状态的回调

    如果您实现并设置了 RCCallSessionDelegate,当通话状态发生变化的时候,会回调相关接口。

    您可以在 startCall 的时候传入或者手动设置通话状态监听。

        // RCCallClient Class
    
        /*!
         发起一个通话
    
         @param conversationType 会话类型
         @param targetId         目标会话ID
         @param userIdList       邀请的用户ID列表
         @param type             发起的通话媒体类型
         @param delegate         通话监听
         @param extra            附件信息
    
         @return 呼出的通话实体
         */
        - (RCCallSession *)startCall:(RCConversationType)conversationType
                            targetId:(NSString *)targetId
                                  to:(NSArray *)userIdList
                           mediaType:(RCCallMediaType)type
                     sessionDelegate:(id<RCCallSessionDelegate>)delegate
                               extra:(NSString *)extra;
    
    
        // RCCallSession Class
    
        /*!
         设置通话状态变化的监听器
    
         @param delegate 通话状态变化的监听器
         */
        - (void)setDelegate:(id<RCCallSessionDelegate>)delegate;
    

    当通话状态发生变化的时候,如接通、结束、对方振铃、有人加入通话、有人挂断、发生警告等都会进行回调。

    // RCCallSession Class
    
    /*!
     通话状态变化的监听器
     */
    @protocol RCCallSessionDelegate <NSObject>
    
    @optional
    
    /*!
     通话已接通
     */
    - (void)callDidConnect;
    
    /*!
     通话已结束
     */
    - (void)callDidDisconnect;
    
    /*!
     对端用户正在振铃
    
     @param userId 用户ID
     */
    - (void)remoteUserDidRing:(NSString *)userId;
    
    /*!
     有用户被邀请加入通话
    
     @param userId    被邀请的用户ID
     @param mediaType 希望被邀请者使用的媒体类型
     */
    - (void)remoteUserDidInvite:(NSString *)userId
                      mediaType:(RCCallMediaType)mediaType;
    
    /*!
     对端用户加入了通话
    
     @param userId    用户ID
     @param mediaType 用户的媒体类型
     */
    - (void)remoteUserDidJoin:(NSString *)userId
                    mediaType:(RCCallMediaType)mediaType;
    
    /*!
     对端用户切换了媒体类型
    
     @param userId    用户ID
     @param mediaType 切换至的媒体类型
     */
    - (void)remoteUserDidChangeMediaType:(NSString *)userId
                               mediaType:(RCCallMediaType)mediaType;
    
    /*!
     对端用户开启或管理了摄像头的状态
    
     @param userId    用户ID
     @param muted     是否关闭摄像头
     */
    - (void)remoteUserDidDisableCamera:(BOOL)disabled
                                byUser:(NSString *)userId;
    
    /*!
     对端用户挂断
    
     @param userId 用户ID
     @param reason 挂断的原因
     */
    - (void)remoteUserDidLeft:(NSString *)userId
                       reason:(RCCallDisconnectReason)reason;
    
    /*!
     通话过程中的错误回调
    
     @param error 错误码
    
     @warning 这个接口回调的错误码主要是为了提供必要的log以及提示用户,如果是不可恢复的错误,SDK会挂断电话并回调callDidDisconnect,App可以在callDidDisconnect中统一处理通话结束的逻辑。
     */
    - (void)errorDidOccur:(RCCallErrorCode)error;
    
    @end
    
    /*!
    白板地址回调
    
    @param url 白板地址
    */
    - (void)onWhiteBoard:(NSString *)url;
    
    /*!
    主持人操作用户设备
    
    @param userId 用户ID
    @param hostId 主持人ID
    @param dType 设备类型
    @param isOpen 设备开启状态
    */
    - (void)onNotifyHostControlUserDevice:(NSString *)userId host:(NSString *)hostId deviceType:(NSInteger)dType open:(BOOL)isOpen;
    
    /*!
    主持人升级用户
    
    @param userId 用户ID
    */
    - (void)onNotifyUpgradeObserverToNormalUser:(NSString *)userId;
    
    /*!
    观察者用户请求成为正常用户
    
    @param userId 用户ID
    */
    -(void)onNotifyAnswerObserverRequestBecomeNormalUser:(NSString *)userId;
    

    10、生成通话信息的记录

    设置是否生成通话记录消息。

    // RCCallClient Class
    
    /*!
    是否生成通话记录消息,默认为YES
    */
    @property(nonatomic, assign) BOOL enableCallSummary;
    

    实时音视频推送设置

    详细请参考 VoIP 推送设置文档

    更多说明

    CallLib 通话不限制最大人数。如果需要限制的话,您可以在调用 startCallinviteRemoteUsers 的时候加判断人数的逻辑。