Android开发

接入声网视频通话SDK-初步接通视频通话教程

2022-05-05  本文已影响0人  你的益达233

一、前言

视频通话接通不难,难的是各种情况处理,且有点功能声网SDK是不提供的,如果要完整的视频通话,这代码量有点大,这篇文章仅以接通为目标

二、看下效果图(设计图)

video_calling.png video_call.png

二、跟着我开始步骤

1、配置部分

在app下的build.gradle中配置

implementation 'io.agora.rtc:full-sdk:3.6.2'
2、拨打前或者加入频道前先询问权限
private fun checkPermission(isClickAcceptCallBack:(() -> Unit)?= null){
    if (PermissionCheckUtil.checkPermissions(mContext,if (startCallBean.type == AUDIO_TYPE) PermissionAppUtils.Group.MICROPHONE else PermissionAppUtils.Group.CAMERA_RECORD)){
        if (startCallBean.type == AUDIO_TYPE) isClickAcceptCallBack?.invoke()?:initAudioEngine() else isClickAcceptCallBack?.invoke()?:initVideoEngine()
    } else {
        DialogUtils.okAndCancel(
            mContext,
            if (startCallBean.type == AUDIO_TYPE) getString(R.string.audio_call_permission_tip) else getString(R.string.video_call_permission_tip),
            ok = getString(R.string.go_open),
            okListener = {
                PermissionAppUtils.requestCombinedPermission(mContext,if (startCallBean.type == AUDIO_TYPE) PermissionAppUtils.Group.MICROPHONE else PermissionAppUtils.Group.CAMERA_RECORD) {
                    if (it.granted){
                        if (isClickAcceptCallBack != null){
                            if (startCallBean.type == AUDIO_TYPE) {
                                initAudioEngine()
                                isClickAcceptCallBack.invoke()
                            } else {
                                initVideoEngine()
                                isClickAcceptCallBack.invoke()
                            }
                        } else {
                            if (startCallBean.type == AUDIO_TYPE) initAudioEngine() else initVideoEngine()
                        }

                    } else  {
                        if (it.shouldShowRequestPermissionRationale){
                            //禁止,不做操作,拨打方直接关闭界面,接听方在点接听时再询问一次
                            if (isCallOutGoing || isClickAcceptCallBack != null){
                                show(R.string.call_permission_empty_tip)
                                finish()
                            }

                        } else {
                            //永久禁止,需求说只弹前面的弹框,永久禁止就直接跳设置
                            //点接听时跳到设置,返回不处理,让它再点一次接听按钮
                            if (isClickAcceptCallBack == null){
                                isJumpAppSetting = true
                                CUtils.startAppSettings(mContext)
                            }

                        }
                    }

                }

            })
    }
}

override fun onResume() {
    super.onResume()
    if (isJumpAppSetting){
        isJumpAppSetting = false
        when(startCallBean.type){
            AUDIO_TYPE -> {
                if (PermissionCheckUtil.checkPermissions(mContext,PermissionAppUtils.Group.MICROPHONE)){
                    initAudioEngine()
                }
            }
            VIDEO_TYPE -> {
                if (PermissionCheckUtil.checkPermissions(mContext,PermissionAppUtils.Group.CAMERA_RECORD)){
                    initVideoEngine()
                }
            }
            else ->{
                show(R.string.call_permission_empty_tip)
                finish()
            }
        }
    }

}
3、有了权限初始化声网引擎和加入频道(显示自己的视频画面)

initVideoEngine()代码如下:

private fun initVideoEngine(){
    initializeAgoraEngine()
    setupVideoProfile()
    initVideoModule()
    setupLocalVideo(startCallBean.closeCamera)
    rtcEngine?.setVideoSource(RtcVideoConsumer())
    if (isCallOutGoing && !startCallBean.isFloatBackCall){
        joinChannel(startCallBean.token,startCallBean.channelName,SPUtil.getUserId())
    }
}

我这个本地视频用了相芯美颜的,可参考它demo原来的代码。上面代码中token和channelName都是app服务器接口返回的

4、自己加入频道后通知对方
/**
     * @desc : 自己加入频道成功回调
     * @author : congge on 2022-03-24 15:07
     **/
    override fun onJoinChannelSuccess(channel: String, uid: Int, elapsed: Int) {
        runOnUiThread {
            LogUtils.i("mRtcEventHandler","onJoinChannelSuccess")
            if (!isCallOutGoing){
                dealViewShow(true)
                dealCallTime(true)
                mViewModel.postChatMediaAnswer(startCallBean.mediaId)
            } else {
                //拨打方加入频道后,邀请对方通话
                if(disposableIntervalCall == null || disposableIntervalCall!!.isDisposed){
                    disposableIntervalCall = Observable.interval(0,5, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
                        .take(55)
                        .subscribe {
                            //只有第一次邀请要通知栏
                            mViewModel.getChatMediaSendInvite(startCallBean.mediaId,it == 0L)

                        }
                }
                //自己加入频道后,给对方60s加入频道的时间
                longTimeNoResponse(timeOutNoResponse)
            }

        }
    }

注:onJoinChannelSuccess是加入频道成功后的回调,拨打方加入频道后,就通知对方。如果是接听方加入频道后就可以显示通话中界面了。声网是没有通知对方的api的,我项目是用融云IM通知对方的。

5、对方加入频道后(显示对方的视频画面)
/**
     * @desc : 对方加入频道成功回调
     * 此回调在以下任一情况下触发:
     * 1、远程用户/主机通过调用joinChannel方法加入通道。
     * 2、远程用户在加入通道后通过调用setClientRole方法将用户角色切换到主机。
     * 3、网络中断后,远程用户/主机重新加入通道。
     * 4、主机通过调用addInjectStreamUrl方法将在线媒体流注入频道。
     * @author : congge on 2022-03-24 15:08
     **/
    override fun onUserJoined(uid: Int, elapsed: Int) {
        runOnUiThread {
            LogUtils.i("mRtcEventHandler","onUserJoined")
            //stopRinging关闭声音要在dealViewShow前面,里面有关扬声器
            CallRingingUtil.getInstance().stopRinging()
            dealViewShow(false)
            dealCallTime(true)
            //10s内对方进入了频道
            cancelLongTimeNoResponse()
            if (startCallBean.type == VIDEO_TYPE){
                videoUid = uid
                setupRemoteVideo(uid)
            }
        }
    }

private fun setupRemoteVideo(uid: Int,fl: FrameLayout? = mBinding.flVideoCallRemoteVideo,surfaceViewRemote1:SurfaceView? = null) {
    if (isMBindingViewInitialised()){
        fl?.let {
            if (it.childCount >= 1) {
                return
            }
            it.removeAllViews()
            if (surfaceViewRemote1 == null){
                surfaceViewRemote = RtcEngine.CreateRendererView(mContext)
                it.addView(surfaceViewRemote)
                // Initializes the video view of a remote user.
                rtcEngine?.setupRemoteVideo(VideoCanvas(surfaceViewRemote, VideoCanvas.RENDER_MODE_HIDDEN, uid))
                surfaceViewRemote!!.tag = uid // for mark purpose
            } else {
                surfaceViewRemote = surfaceViewRemote1
                it.addView(surfaceViewRemote)
                surfaceViewRemote!!.tag = uid
            }
        }
    }
}

1、拨打方监听到接听方进入频道的回调
2、接听方进入频道后也会收到这回调

6、至此双方应该能互相看见对方了,最后就是挂断了

挂断就是退出频道

rtcEngine?.leaveChannel()

然后对方就会收到以下回调

override fun onUserOffline(uid: Int, reason: Int) 

如果需要完整的声网音视频通话的代码,可私信我

上一篇下一篇

猜你喜欢

热点阅读