文档反馈
文档反馈

跑通呼叫组件(Android)

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

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

注意事项

准备工作

组件结构

Demo调用组件入口:

文件夹/类 说明
nertcvideocall 文件夹 bean 文件夹 ControlInfo 类 自定义控制消息类。
CustomInfo 类 记录一些类型、人员及id的信息。
model 文件夹 - 组件的接口封装类。
impl/NERTCVideoCallImpl 类 实现相关呼叫,接听等接口。
VideoCallOptions 类 封装组件初始化需要的参数。
push 文件夹 定义相关的厂商推送接入等。
service 文件夹 callService 类 组件的基础服务类。
NotificationBroadcastReceiver 类 组件的基础广播类。
utils 文件夹 CallParams 接口 定义组件相关的枚举等参数。
NrtcCallStatus 接口 定义当前组件中通话状态。
Utils 接口 区分多人通话还是一对一通话。
ui 文件夹 model 文件夹 Demo业务层封装的业务用户数据。
recylclerview 文件夹 针对 Demo 的一些优化 recylclerview。
ui 文件夹 team 文件夹 多人音视频相关。
NERTCVideoCallActivity 视频 Activity,组件视频页面,组件方法入口。

集成组件

Demo 中以 Maven 形式导入音视频通话 2.0 SDK。

  1. 下载 NERTCCallkit 组件 并解压缩。
  2. 通过 Android Studio 打开文件夹 nim-dev_G2_jar
  3. 在 Android Studio 中依次单击 File > New > Import Module... ,将 nim-dev_G2_jar 中的 G2 作为 module 导入。

实现 UI 界面

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

您可以参考 Demo 中 的 UI 模块:

实现组件基本功能

步骤一 初始化组件

通过以下示例代码初始化 NERTCCallkit 组件。

Demo 中初始化注册位置为:在 MainActivity 类中的 onCreate() 方法中初始化 initG2()

/**
 * 初始化,需要且仅能调用一次
 *
 * @param context
 * @param appKey
 * @param option
 */

NERTCVideoCall.sharedInstance().setupAppKey(getApplicationContext(), appKey, new VideoCallOptions(null, new UIService() {
    // 点对点音频页面
    @Override
    public Class getOneToOneAudioChat() {
        return NERTCVideoCallActivity.class;
    }

    // 点对点视频视频
    @Override
    public Class getOneToOneVideoChat() {
        return NERTCVideoCallActivity.class;
    }

    // 群聊页面
    @Override
    public Class getGroupVideoChat() {
        return TeamG2Activity.class;
    }

    @Override
    public int getNotificationIcon() {
        return R.drawable.ic_logo;
    }

    @Override
    public int getNotificationSmallIcon() {
        return R.drawable.ic_logo;
    }
}, ProfileManager.getInstance()));

步骤二 登录

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

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

/**
 * IM 登录,使用前需要登录,最好在初始化后登录
 *
 * @param imAccount im账号
 * @param imToken   im 密码
 * @param callback  登录回调
 */
NERTCVideoCall.sharedInstance().login(imAccount, imToken, new RequestCallback<LoginInfo>() {
    @Override
    public void onSuccess(LoginInfo param) {

    }

    @Override
    public void onFailed(int code) {

    }

    @Override
    public void onException(Throwable exception) {

    }
});

步骤三 设置 Token

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

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

setTokenService 为抽象方法,主要在 NERTCVideoCallImpl 类实现,再通过 loadToken() 的callback,在 joinchannel 时设置 Token。

//注册获取token的服务
NERTCVideoCall.sharedInstance().setTokenService((uid, callback) -> {
    String demoServer = "业务服务器URL";
    new Thread(() -> {
        try {
            // 请求业务服务器,由业务服务器,调用云信HTTPS接口,获取到Token回传
        } catch (Exception e) {
            e.printStackTrace();
        }

步骤四 发起呼叫

在 Demo 中,发起呼叫的实现流程如下:

  1. 主叫人在 AVChatAction 类中 调用 startAudioVideoCall 方法,传入当前的通话类型和用户信息,启动相应的通话。
  2. 通过 NERTCVideoCallActivityNERTCAudioCallActivity 调用 callOut 方法。

    • 一对一通话:

        /**
        * C2C邀请通话,被邀请方会收到 {@link NERTCCallingDelegate#onInvited } 的回调
        *
        * @param userId              被邀请方
        * @param selfUserId          自己的用户Id
        * @param type                1-语音通话,2-视频通话
        * @param joinChannelCallBack channel 回调
        */
      
        NERTCVideoCall.sharedInstance().call(userId,selfUserId, ChannelType.VIDEO,new JoinChannelCallBack() {
            @Override
            public void onJoinChannel(ChannelFullInfo channelFullInfo) {
            // ChannelFullInfo 为信令的对象,音视频的为NERtcCallback的onJoinChannel
            }
      
            @Override
            public void onJoinFail(String msg, int code) {
      
            }
        });
    • 多人通话:

        /**
        * 多人邀请通话,被邀请方会收到 {@link NERTCCallingDelegate#onInvited } 的回调
        *
        * @param ArrayList<String> callUserIds         被邀请方
        * @param String selfUserId         自己的用户Id
        * @param ChannelType type     1-语音通话,2-视频通话
        * @param joinChannelCallBack channel 回调
        */
        NERTCVideoCall.sharedInstance().groupCall(accounts, ProfileManager.getInstance().getUserModel().imAccid, ChannelType.VIDEO, new JoinChannelCallBack() {
            @Override
            public void onJoinChannel(ChannelFullInfo channelFullInfo) {   }
      
            @Override
            public void onJoinFail(String msg, int code) {   }
        });

步骤五 配置监听

Demo 中,在 NERTCVideoCallImpl 类实现 new Observer<ArrayList<ChannelCommonEvent>>(),配置监听信令事件。并在 handleNIMEvent() 中处理 invite。

// 接口 NERTCCallingDelegate

/**
 * 被邀请通话回调
 *
 * @param invitedEvent 邀请参数
 */
void onInvited(InvitedEvent invitedEvent);

InvitedEvent invitedEvent = (InvitedEvent) event;
if (delegateManager != null) {
    if (currentState.getStatus() != CallState.STATE_IDLE) { //占线,直接拒绝
        Log.d(LOG_TAG, "user is busy status =  " + currentState.getStatus());
        InviteParamBuilder paramBuilder = new InviteParamBuilder(invitedEvent.getChannelBaseInfo().getChannelId(),
                invitedEvent.getFromAccountId(), invitedEvent.getRequestId());
        paramBuilder.customInfo(BUSY_LINE);
        reject(paramBuilder, false, null);
        break;
    } else {
        startCount();
        delegateManager.onInvited(invitedEvent);
    }
}
setCallType(invitedEvent);
currentState.onInvited();

/**
 * 返回操作
 *
 * @param errorCode  错误码
 * @param errorMsg   错误信息
 * @param needFinish UI层是否需要退出(如果是致命错误,这里为true)
 */
void onError(int errorCode, String errorMsg, boolean needFinish);

/**
 * 被邀请通话回调
 *
 * @param invitedEvent 邀请参数
 */
void onInvited(InvitedEvent invitedEvent);

/**
 * 如果有用户同意进入通话频道,那么会收到此回调
 *
 * @param uid 进入通话的用户
 */
void onUserEnter(long uid,String accId);


/**
 * 如果有用户同意离开通话,那么会收到此回调
 *
 * @param accountId 离开通话的用户
 */
void onCallEnd(String accountId);

/**
 * 用户离开时回调
 * @param accountId
 */
void onUserLeave(String accountId);

/**
 * 用户断开连接
 * @param userId
 */
void onUserDisconnect(String userId);

/**
 * 拒绝通话
 *
 * @param userId 拒绝通话的用户
 */
void onRejectByUserId(String userId);


/**
 * 邀请方忙线
 *
 * @param userId 忙线用户
 */
void onUserBusy(String userId);

/**
 * 作为被邀请方会收到,收到该回调说明本次通话被取消了
 */
void onCancelByUserId(String userId);


/**
 * 远端用户开启/关闭了摄像头
 *
 * @param userId           远端用户ID
 * @param isVideoAvailable true:远端用户打开摄像头  false:远端用户关闭摄像头
 */
void onCameraAvailable(long userId, boolean isVideoAvailable);

/**
 * 远端用户开启/关闭了麦克风
 *
 * @param userId           远端用户ID
 * @param isAudioAvailable true:远端用户打开麦克风  false:远端用户关闭麦克风
 */
void onAudioAvailable(long userId, boolean isAudioAvailable);

/**
 * 网络状态回调
 *
 * @param stats
 */
void onUserNetworkQuality(NERtcNetworkQualityInfo[] stats);

/**
 * 通话状态改变
 *
 * @param type
 */
void onCallTypeChange(ChannelType type);

/**
 * 呼叫超时
 */
void timeOut();
void timeOut();

步骤六 接听来电

被叫方调用 accept 方法接听来电。

/**
 * 当您作为被邀请方收到 {@link NERTCCallingDelegate#onInvited } 的回调时,可以调用该函数接听来电
 *
 * @param invitedParam 邀请信息
 * @param selfAccId 自己的accid
 * @param joinChannelCallBack  加入channel的回调
 */

nertcVideoCall.accept(invitedParam, selfUserId, new JoinChannelCallBack() {
    @Override
    public void onJoinChannel(ChannelFullInfo channelFullInfo) {

    }

    @Override
    public void onJoinFail(String msg, int code) {

    }
});

步骤六 挂断通话

主叫方和被叫方处于通话中时,调用 hangup 结束通话。

/**
 * 当您处于通话中,可以调用该函数结束通话(离开房间并关闭房间)
 * 通话发起者拥有此权限,并可以授权给接受者是否拥有此权限
 */
nertcVideoCall.hangup(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid) { }

    @Override
    public void onFailed(int i) { }

    @Override
    public void onException(Throwable throwable) { }
});

步骤七 获取话单

说明

正常挂断

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

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

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

非正常挂断

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

// 取消通话
nertcVideoCall.cancel(new RequestCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid) { }

    @Override
    public void onFailed(int i) { }

    @Override
    public void onException(Throwable throwable) { }
});

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

组件底层通过在 NERTCVideoCallImpl 中调用 makeCallOrder 的方法实现话单,构建一条 createNrtcNetcallMessage 消息进行发送。您也可以自行实现该逻辑。

底层实现方式为:

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

反馈成功

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