Android CallLib 开发指南

    开通方式

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

    使用说明

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

    CallLib SDK 支持 Android 4.3 及以上系统。

    网络环境要求

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

    1、带宽

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

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

    2、延时

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

    3、丢包

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

    集成说明

    1、 首先请参考官网文档集成 CallLib SDK 。

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

    快速集成

    1、设置音视频引擎服务地址信息

    /**
     * 设置音视频引擎服务器地址信息,请在 Application onCreate 方法中 SDK 初始化前调用。
     * 注意:此设置只对私有部署的音视频有效,如果设置的参数无效,会有 {@link IllegalArgumentException} 异常。
     *
     * @param cmpUrl     cmp 地址
     * @param snifferUrl sniffer 地址
     */
     void setEngineServerInfo(String cmpUrl, String snifferUrl);
    

    2、发起通话

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

    /**
      * 发起音视频听话
      * @param conversationType 会话类型, 如果实现的是不基于群组的voip,那次参数必须传 {@linkConversation.ConversationType#NONE}
      * @param targetId  目标会话id, 如果实现的是不基于群组的voip,那此参数无意义,传null
      * @param userIds   邀请参与通话的用户ID列表
      * @param observerUserIds   观察者列表,无观察者可传 null;
      * @param mediaType 发起的通话媒体类型
      * @param extra 附加信息
      * @return  呼叫id
      */
     public String startCall(Conversation.ConversationType conversationType, String targetId, List<String> userIds, List<String> observerUserIds, RongCallCommon.CallMediaType mediaType, String extra);
    

    3、设置通话来电监听

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

    RongCallClient.setReceivedCallListener(new IRongReceivedCallListener() {
        /**
         * 来电回调
         * @param callSession 通话实体
         */
        @Override
        public void onReceivedCall(RongCallSession callSession) {
            //accept or hangup the call
        }
    
        /**
         * targetSDKVersion>=23时检查权限的回调。当targetSDKVersion<23的时候不需要实现。
         * 在这个回调里用户需要使用Android6.0新增的动态权限分配接口requestCallPermissions通知用户授权,
         * 然后在onRequestPermissionResult回调里根据用户授权或者不授权分别回调
         * RongCallClient.getInstance().onPermissionGranted()和
         * RongCallClient.getInstance().onPermissionDenied()来通知CallLib。
         * 其中audio call需要获取Manifest.permission.RECORD_AUDIO权限;
         * video call需要获取Manifest.permission.RECORD_AUDIO和Manifest.permission.CAMERA两项权限。
         * @param callSession 通话实体
         */
        @Override
        public void onCheckPermission(RongCallSession callSession) {
    
        }
    });
    

    4、接听和挂断呼入的通话

    您可以调用 RongCallClient 下面接口接听和挂断通话。

    /**
     * 接听通话
     * @param callId 呼叫id,可以从来电监听的{@link RongCallSession#getCallId()}中获取
     */
    public void acceptCall(String callId);
    
    /**
     * 挂断通话
     * @param callId 呼叫id,可以从来电监听的{@link RongCallSession#getCallId()}中获取
     */
    public void hangUpCall(String callId);
    

    5、获取当前的通话实体

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

    /**
     * 获取当前通话实体,通话实体中维护着当前通话的所有信息。
     * @return 当前通话实体
     */
    public RongCallSession getCallSession();
    
    /**
     * 挂断通话
     * @param callId 呼叫id,可以从来电监听的{@link RongCallSession#getCallId()}中获取
     */
    public void hangUpCall(String callId);
    

    6、获取当前的通话实体

    您可以通过 RongCallClient 的下面接口获取当前的通话实体,通话实体中维护着当前通话的所有信息。

    /**
     * 获取当前通话实体,通话实体中维护着当前通话的所有信息。
     * @return 当前通话实体
     */
    public RongCallSession getCallSession();
    

    7、邀请用户加入当前通话

    您可以通过 RongCallClient 的下面接口邀请用户加入当前通话(仅限群组)。

    /**
      * 邀请用户加入当前通话(仅限讨论组和群组)
      *
      * @param callId  通话id
      * @param userIds 邀请的用户id列表
      * @param observerUserIds 邀请的观察者列表,没有观察者可以传 null
      */
    public void addParticipants(String callId, ArrayList<String> userIds,ArrayList<String> observerUserIds);
    

    8、通话过程中的媒体接口

    您可以通过 RongCallClient 的下面接口进行媒体类的操作。

    /**
     * 切换 audio,video 通话
     * @param mediaType 要切换的媒体类型:audio、video
     */
    public void changeCallMediaType(RongCallCommon.CallMediaType mediaType);
    
    /**
     * 前后摄像头切换
     */
    public void switchCamera();
    
    /**
     * 观察者请求变为正常用户
     */
    public void requestNormalUser();
    
    /**
     * 设置是否打开本地摄像头
     * @param enabled true:打开摄像头;false:关闭摄像头。
     */
    public void setEnableLocalVideo(boolean enabled);
    
    
    /**
     * 设置是否打开本地音频
     * @param enabled true:打开本地音频 false:关闭本地音频
     */
    public void setEnableLocalAudio(boolean enabled);
    
    /**
     * 设置是否打开免提
     * @param enabled true:打开免提 false:关闭免提
     */
    public void setEnableSpeakerphone(boolean enabled);
    
    /**
     * 该方法设定外放(扬声器)音量。(已废弃)
     * @param level 设定音量,最小为 0,最大为 255
     */
    public void setSpeakerPhoneVolume(int level);
    
    /**
      * 设置本地视频属性,可用此接口设置本地视频分辨率。请在connect成功之后设置。
      *
      * @param profile see {@link io.rong.calllib.RongCallCommon.CallVideoProfile}
      */
    public void setVideoProfile(RongCallCommon.CallVideoProfile profile);
    
    /**
      * 设置是否打开美颜
      *
      * @param enable true 打开,false 关闭
      */
    public void setEnableBeauty(boolean enable);
    
    /**
      * 设置是否打开外部加密
      *
      * @param enable true 打开,false 关闭
      */
    public void setEnableExternalEncrypt(boolean enable);
    
    /**
     * 设置外部加密文件路径
     *
     * @param filePath 文件路径
     */
    public void setEncryptFilePath(String filePath);
    
    /**
      * 设置是否打印日志开关
      * 日志文件保留在/sdcard/Android/data/<package name>/cache/ronglog/rcvoip.log
      *
      * @param enable true 打开,false 关闭
      */
    public void setEnablePrintLog(boolean enable);
    
    /**
     * 设置本地视频显示模式。(已废弃)
     * @param mode see {@link io.agora.rtc.video.VideoCanvas}
     */
    public void setLocalRenderMode(int mode);
    
    /**
     * 设置远端视频显示模式,在onRemoteUserJoined回调回来后调用;(已废弃)
     * @param uid  用户id
     * @param mode see {@link io.agora.rtc.video.VideoCanvas}
     */
    public void setRemoteRenderMode(String uid, int mode);
    
    /*
     *关闭录音,在结束音视频通话时候调用 onCallDisconnected。
     */
    public void stopAudioRecording();
    
    /**
      * 开启录音,SDK支持在通话中进行录音,录音文件的格式为wav。应用程序必须保证指定的目录存在而且可写;
      * 需要在成功加入房间之后调用{@link IRongCallListener#onCallConnected}
      *
      * @param filePath 录音文件的完整路径(如:/storage/emulated/0/RongCloud/rong.wav,需要保证存放录音文件的目录在录音开始之前就已经创建完毕)。该录音文件为UTF-8编码
      */
    public void startAudioRecording(String filePath);
    
    /**
      * 检查音视频引擎是否可用
      * @param context
      * @return
      */
    public boolean isVoIPEnabled(Context context);
    
    /**
     * 请求白板
     * 请求之后会通过 {@link IRongCallListener#onWhiteBoardURL(String) 返回白板的地址}
     */
    public void requestWhiteBoard();
    
    /**
      * 主持人邀请观察者升级成正常用户时, 观察者的应答调用
      * @param userID
      * @param isOK 是否接受升级成正常用户
      */
    public void answerUpgradeObserverToNormalUser(String userID, boolean isOK);
    
    /**
      * 麦克风/摄像头被主持人打开时, 被打开人的应答调用
      *
      * @param userID   用户标识唯一ID
      * @param dType    设备类型
      * @param isOpen   打开/关闭
      * @param isAccept 是否接受
      */
    public void answerHostControlUserDevice(String userID, int dType, boolean isOpen, boolean isAccept);
    
    /**
     * 当前页面被系统回收后,尝试恢复所有视频视图
     */
    public void reCreateVideoViews();
    

    9、设置通话状态的回调

    您需要设置通话状态的回调,来监听通话状态的变化。

    RongCallClient.getInstance().setVoIPCallListener(new IRongCallListener() {
        /**
         * 电话已拨出。
         * 主叫端拨出电话后,通过回调 onCallOutgoing 通知当前 call 的详细信息。
         *
         * @param callSession 通话实体。
         * @param localVideo  本地 camera 信息。
         */
        @Override
        public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) {
    
        }
    
        /**
         * 已建立通话。
         * 通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息。
         *
         * @param callSession 通话实体。
         * @param localVideo  本地 camera 信息。
         */
        @Override
        public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) {
    
        }
    
        /**
         * 通话结束。
         * 通话中,对方挂断,己方挂断,或者通话过程网络异常造成的通话中断,都会回调 onCallDisconnected。
         *
         * @param callSession 通话实体。
         * @param reason      通话中断原因。
         */
        @Override
        public void onCallDisconnected(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) {
    
        }
    
        /**
         * 被叫端正在振铃。
         * 主叫端拨出电话,被叫端收到请求,发出振铃响应时,回调 onRemoteUserRinging。
         *
         * @param userId 振铃端用户 id。
         */
        @Override
        public void onRemoteUserRinging(String userId) {
    
        }
    
        /**
         * 被叫端加入通话。
         * 主叫端拨出电话,被叫端收到请求后,加入通话,回调 onRemoteUserJoined。
         *
         * @param userId      加入用户的 id。
         * @param mediaType   加入用户的媒体类型,audio or video。
         * @param userType    加入用户的类型,正常用户或者观察者  
         * @param remoteVideo 加入用户者的 camera 信息。
         */
        @Override
        public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
    
        }
    
        /**
         * 通话中的某一个参与者,邀请好友加入通话,发出邀请请求后,回调 onRemoteUserInvited。
         *
         * @param userId    被邀请者的 id。
         * @param mediaType 被邀请者的 id。
         */
        @Override
        public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) {
    
        }
    
        /**
         * 通话中的远端参与者离开。
         * 回调 onRemoteUserLeft 通知状态更新。
         *
         * @param userId 远端参与者的 id。
         * @param reason 远端参与者离开原因。
         */
        @Override
        public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) {
    
        }
    
        /**
         * 当通话中的某一个参与者切换通话类型,例如由 audio 切换至 video,回调 onMediaTypeChanged。
         *
         * @param userId    切换者的 userId。
         * @param mediaType 切换者,切换后的媒体类型。
         * @param video     切换着,切换后的 camera 信息,如果由 video 切换至 audio,则为 null。
         */
        @Override
        public void onMediaTypeChanged(String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) {
    
        }
    
        /**
         * 通话过程中,发生异常。
         *
         * @param errorCode 异常原因。
         */
        @Override
        public void onError(RongCallCommon.CallErrorCode errorCode) {
    
        }
    
        /**
         * 远端参与者 camera 状态发生变化时,回调 onRemoteCameraDisabled 通知状态变化。
         *
         * @param userId   远端参与者 id。
         * @param disabled 远端参与者 camera 是否可用。
         */
        @Override
        public void onRemoteCameraDisabled(String userId, boolean disabled) {
    
        }
    
        /**
         * 请求白板页面之后的回调
         * @param url   白板页面的url
         */
        @Override
        public void onWhiteBoardURL(String url){}
    
        /**
         * 返回本地发送数据流的丢包率,每秒刷新一次。
         *
         * @param lossRate 取值范围0~100, 代表丢包率0%~100%
         */
        @Override
        public void onNetWorkLossRate(int lossRate){}
    
        /**
         * 当有与会人打开/关闭屏幕共享时,其他与会人员会收到回调
         *
         * @param userId 操作屏幕共享的用户Id
         * @param isSharing true:打开 / false:关闭
         */
        @Override
        public void onNotifySharingScreen(String userId, boolean isSharing){}
    
        /**
         * 正常用户被降级为观察者
         *
         * @param userId  被降级的用户ID
         */
        @Override
        public void onNotifyDegradeNormalUserToObserver(String userId){}
    
        /**
         * 自己是观察者且已在聊天室中, 主持人邀请自己升级成为正常用户时的通知, 在此回调中需要给出应答,
         */
        @Override
        public void onNotifyUpgradeObserverToNormalUser(){}
    
        /**
         * 主持人邀请用户打开或者关闭摄像头、麦克风。
         *
         * @param userId 用户ID
         * @param dType  操作的设备类型
         * @param isOpen 是否打开
         */
        @Override
        public void onNotifyHostControlUserDevice(String userId, int dType, int isOpen){}
    });
    

    10、处理通话中的视频数据

    /**
         * 注册监听,用于处理视频通话中的视频数据。请在connect成功之后设置。
         *
         * @param listener 视频数据监听
         */
        public void registerVideoFrameListener(IVideoFrameListener listener) {
            RongCallManager.getInstance().registerVideoFrameListener(listener);
        }
    
        /**
         * 解除注册 处理视频通话中视频数据的 监听
         */
        public void unregisterVideoFrameObserver() {
            RongCallManager.getInstance().unregisterVideoFrameListener();
        }
    

    11、音视频相关混淆

    -keep class com.blink.**  { *; }
    -keep class com.bailingcloud.bailingvideo.engine.binstack.json.**  { *; }
    -keep class bailingquic.**{*;}
    -keep class go.**{*;}