Android SDK集成

本文介绍一对一音视频通话Android SDK集成的代码示例及集成说明。

功能时序图

1701691290552-26e4dbe1-4458-47b1-88ed-131a021adbae.png

功能实现

初始化ARTC引擎及回调注册

说明

SDK出现异常时内部会优先进行重试恢复,需要业务处理的异常SDK会通过明确的回调API通知。

异常发生原因

回调及参数

解决方案

备注

鉴权失败

onJoinChannelResult回调result返回AliRtcErrJoinBadToken

发生错误时需要App检查token是否正确。

出现鉴权失败发生在用户主动调用API时发生,所以在API对应的回调中返回。

鉴权过期

onWillAuthInfoExpire

发生该异常时App需要重新获取最新的鉴权信息后,再调用refreshAuthInfo刷新鉴权信息。

出现鉴权过期的情况分为用户主动调用API、程序运行阶段时发生,所以会在API对应的回调及独立的错误回调时发生。

鉴权过期

onAuthInfoExpired

发生该异常时App需要重新入会。

出现鉴权过期的情况分为用户主动调用API、程序运行阶段时发生,所以会在API对应的回调及独立的错误回调时发生。

网络链接异常

onConnectionStatusChange回调返回AliRtcConnectionStatusFailed

发生该异常时需要重新入会。

SDK具备一定时间断网自动恢复能力,超过限定的时间后会超时断开;此时需要App检查当前的状态后再次入会。

被踢下线

onBye

  • AliRtcOnByeUserReplaced 时排查是否userid相同。

  • AliRtcOnByeBeKickedOut 发生该异常时被业务踢下线,需要重新入会。

  • AliRtcOnByeChannelTerminated 房间被销毁,需要重新入会。

ARTC服务具备踢人的能力。

本地设备异常

onLocalDeviceException

本地设备异常,需要App检测权限、设备硬件是否正常。

ARTC服务具备设备检测、异常诊断的能力;在本地设备异常时那么会通过回调的方式通知客户本地设备异常,此时SDK内部无法恢复,需要App方介入查看设备是否正常。

private void createEngine() {
    mAliRtcEngine = AliRtcEngine.getInstance(getApplicationContext());
    mAliRtcEngine.setRtcEngineEventListener(new AliRtcEngineEventListener() {

        /* SDK与服务器的链接状态通知,务必处理链接失败的情况 */
        @Override
        public void onConnectionStatusChange(AliRtcEngine.AliRtcConnectionStatus aliRtcConnectionStatus, AliRtcEngine.AliRtcConnectionStatusChangeReason aliRtcConnectionStatusChangeReason) {
            super.onConnectionStatusChange(aliRtcConnectionStatus, aliRtcConnectionStatusChangeReason);
            if (aliRtcConnectionStatus == AliRtcEngine.AliRtcConnectionStatus.AliRtcConnectionStatusFailed) {
                /* TODO: 务必处理;建议业务提示客户,此时SDK内部已经尝试了各种恢复策略已经无法继续使用时才会上报 */
            } else {
                /* TODO: 可选处理;增加业务代码,一般用于数据统计、UI变化 */
            }
        }

        /* SDK尝试控制本地设备异常 */
        @Override
        public void OnLocalDeviceException(AliRtcEngine.AliRtcEngineLocalDeviceType aliRtcEngineLocalDeviceType, AliRtcEngine.AliRtcEngineLocalDeviceExceptionType aliRtcEngineLocalDeviceExceptionType, String s) {
            super.OnLocalDeviceException(aliRtcEngineLocalDeviceType, aliRtcEngineLocalDeviceExceptionType, s);
            /* TODO: 务必处理;建议业务提示客户错误,此时SDK内部已经尝试了各种恢复策略已经无法继续使用时才会上报 */
        }

        @Override
        public void onJoinChannelResult(int result, String channel, String userId, int elapsed) {
            super.onJoinChannelResult(result, channel, userId, elapsed);
            /* TODO: 可选处理;增加业务代码,一般用于数据统计、UI变化 */
            Log.i(TAG, "onJoinChannelResult result=" + result + ",channel=" + channel + ",userId=" + userId + ",elapsed=" + elapsed);
        }

        @Override
        public void onLeaveChannelResult(int result, AliRtcEngine.AliRtcStats stats) {
            super.onLeaveChannelResult(result, stats);
            Log.i(TAG, "onLeaveChannelResult result=" + result);
        }
    });
    mAliRtcEngine.setRtcEngineNotify(new AliRtcEngineNotify() {

        /* 鉴权距离过期还有30s时会回调,务必进行鉴权时间刷新 */
        @Override
        public void onAuthInfoWillExpire() {
            super.onAuthInfoWillExpire();
            /* TODO: 务必处理;业务触发重新获取当前channel,user的鉴权信息,然后设置refreshAuthInfo即可 */
        }

        /* 业务可能会触发踢人的动作,所以这个地方也需要处理 */
        @Override
        public void onBye(int code) {
            super.onBye(code);
            /* TODO: 建议业务根据自己的场景,进行对应的处理 */
        }

        @Override
        public void onRemoteUserOnLineNotify(String uid, int elapsed) {
            super.onRemoteUserOnLineNotify(uid, elapsed);
            Log.i(TAG, "onRemoteUserOnLineNotify uid=" + uid + ",elapsed=" + elapsed);
        }

        @Override
        public void onRemoteUserOffLineNotify(String uid, AliRtcEngine.AliRtcUserOfflineReason aliRtcUserOfflineReason) {
            super.onRemoteUserOffLineNotify(uid, aliRtcUserOfflineReason);
            Log.i(TAG, "onRemoteUserOnLineNotify uid=" + uid + ",aliRtcUserOfflineReason=" + aliRtcUserOfflineReason);
        }

        @Override
        public void onRemoteTrackAvailableNotify(String uid, AliRtcEngine.AliRtcAudioTrack aliRtcAudioTrack, AliRtcEngine.AliRtcVideoTrack aliRtcVideoTrack) {
            super.onRemoteTrackAvailableNotify(uid, aliRtcAudioTrack, aliRtcVideoTrack);
            Log.i(TAG, "onRemoteUserOnLineNotify uid=" + uid + ",aliRtcAudioTrack=" + aliRtcAudioTrack + ",aliRtcVideoTrack=" + aliRtcVideoTrack);
            mMainHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (aliRtcVideoTrack == AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera
                            || aliRtcVideoTrack == AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackBoth) {
                        AliRtcEngine.AliRtcVideoCanvas remote_canvas = new AliRtcEngine.AliRtcVideoCanvas();
                        SurfaceView remoteView = mAliRtcEngine.createRenderSurfaceView(mContext);
                        if (remoteView != null) {
                            remoteView.setZOrderOnTop(true);
                            remoteView.setZOrderMediaOverlay(true);
                        }
                        remote_canvas.view = remoteView;
                        mLocalSurfaceContainer.addView(remote_canvas.view, new FrameLayout.LayoutParams(
                                findViewById(R.id.local_surface_container).getWidth()/4,
                                findViewById(R.id.local_surface_container).getHeight()/4));
                        mAliRtcEngine.setRemoteViewConfig(remote_canvas,uid,AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);
                    } else {
                        mAliRtcEngine.setRemoteViewConfig(null, uid, AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);
                    }
                }
            });
        }
    });
}

设置入会前的参数

说明
  • SDK在互动模式下、主播角色,默认会推本地的音视频,同时拉其他主播的音视频流。

  • SDK在互动模式下、观众角色,不会推本地的音视频流,但是会拉取其他主播的音视频流。

  • SDK默认是按照自动推拉流模式,用户也可以关闭自动推拉流模式。

    private void initEngineBeforeJoin() {
        /* 可选:入会前的参数设置 */
        mAliRtcEngine.setChannelProfile(AliRtcEngine.AliRTCSdkChannelProfile.AliRTCSdkInteractiveLive);
        mAliRtcEngine.setClientRole(AliRtcEngine.AliRTCSdkClientRole.AliRTCSdkInteractive);
        /* 设置音频的属性 */
        mAliRtcEngine.setAudioProfile(AliRtcEngine.AliRtcAudioProfile.AliRtcEngineStereoHighQualityMode, AliRtcEngine.AliRtcAudioScenario.AliRtcSceneMusicMode);

        /* 可选:摄像头预览,不设置也会进行推流 */
        AliRtcEngine.AliRtcVideoCanvas canvas = new AliRtcEngine.AliRtcVideoCanvas();
        canvas.view = mAliRtcEngine.createRenderSurfaceView(mContext);
        mLocalSurfaceContainer.removeAllViews();
        if (canvas.view != null) {
            mLocalSurfaceContainer.addView(canvas.view, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
        }
        mAliRtcEngine.setLocalViewConfig(canvas, AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);
    }

入会

说明
  • 入会后会按照入会前的参数进行对应的推流和拉流。

  • 默认SDK会自动推拉流,减少客户需要调用的API。

initEngineBeforeJoin();
mAliRtcEngine.joinChannel("您的鉴权信息", null, null, "testUserName");

离会

mAliRtcEngine.leaveChannel();

销毁引擎

mAliRtcEngine.destroy();
mAliRtcEngine = null;

效果展示

按照上面的代码集成完毕后,可以得到下面的结果,您可以根据自身业务需求进行调整。image.png

其他API

更多API说明请参见AliRtcEngine接口