Android技术分享| 一对一音视频呼叫邀请开发流程(一)
此文档基于 Android RTM、RTC SDK,其他平台API 基本一致,可供参考。
RTM:用于搭建呼叫的一整套流程、信令交互
RTC:用于呼叫流程通了之后的音视频交互
由于呼叫和音视频是完全分开的两个 sdk,所以在开发的时候需要注意的情况很多。
点对点呼叫
点对点呼叫就是2个人的通话,基本的通话场景中包含发起呼叫、拒绝呼叫、同意呼叫、视频呼叫转语音接听、呼叫正忙等。
下面我将一一介绍这几个功能的实现以及需要注意的地方。
以下功能默认你已基本阅读过 RTM RTC 文档且登录成功了 RTM SDK,RTC SDK 也已经准备好。
主叫
发起呼叫
- 创建 LocalInvitation 对象
val localInvitation = rtmCallManager.createLocalInvitation(userId)
上述方法用于创建一个呼叫对象,⏰ 其中参数 userId 为对方的登录 RTM sdk 的 userId
- 添加自定义信息
发起呼叫的时候,通常我们都需要告诉对方本次是视频呼叫还是音频呼叫,是否多人呼叫,或者其他跟业务相关的信息。这时候就可以在上面创建的 localInvitation 对象中添加自定义信息。
localInvitation.setContent("自定义的消息体")
//通常我们都会选择发送json格式字符串,例如
"mediaType":0 //0视频 1 音频
"isMeeting":1 //0 多人模式 1 p2p
"rtcChannelId":"10000"//⚠️这个参数尤为重要,这个参数通常都由主叫生成,在呼叫的时候带给被叫。该参数的作用是告诉对方我们这次呼叫将进入哪个 RTC 的频道,两个人进入同一个 RTC 频道时,音视频才会通。
- 发送呼叫
rtmCallManager.sendLocalInvitation(localInvitation, null)
有了以上两步,就可以发送呼叫了。主叫发送呼叫之后会收到相关的回调如下,建议将注释copy到代码中去,方便处理业务。
//对方已收到你的呼叫
void onLocalInvitationReceivedByPeer(LocalInvitation var1);
//对方同意了你的呼叫
void onLocalInvitationAccepted(LocalInvitation var1, String response);
//对方拒绝了你的呼叫
void onLocalInvitationRefused(LocalInvitation var1, String response);
//自己取消了呼叫
void onLocalInvitationCanceled(LocalInvitation var1);
//呼叫失败,可能原因对方一直未接听等..
void onLocalInvitationFailure(LocalInvitation var1, int errorCode);
熟悉以上回调作用在开发中相当重要,其中同意和拒绝回调中的第二个 response 参数,在通话中我们也可以用到。稍后在转语音接听/通话正忙章节介绍。
取消呼叫
rtmCallManager.cancelLocalInvitation(localInvitation,null)
被叫
同意呼叫
在对方发起呼叫后,被叫会收到以下相关回调。
//收到呼叫
void onRemoteInvitationReceived(RemoteInvitation var1);
//你同意了呼叫
void onRemoteInvitationAccepted(RemoteInvitation var1);
//你拒绝了呼叫
void onRemoteInvitationRefused(RemoteInvitation var1);
//对方取消了呼叫
void onRemoteInvitationCanceled(RemoteInvitation var1);
//呼叫邀请失败,可能是长时间未接听等情况,可查看文档
void onRemoteInvitationFailure(RemoteInvitation var1, int var2);
流程图(同意呼叫后)
请注意被叫回调中的 RemoteInvitation 对象,这个对象其实就是包含了主叫的一些信息,比如
String getCallerId() //主叫的userId!!主叫的userId!!
String getContent() //主叫发送的自定义信息
通常我们会在收到呼叫的回调中,解析 Content 里的 json,就可以知道本次是音频还是视频呼叫,本次呼叫将要进入的 RTC 频道。在这里,你可以选择拒绝或者同意对方的呼叫,同意拒绝后主叫被叫将会触发哪些回调,请再阅读上面的回调注释。
另外,RemoteInvitation 还有一个特别实用的方法
void setResponse(String var1)//设置回执消息
这个方法可以用来做什么?请往下看。
视频呼叫转语音接听
视频呼叫转语音接听在视频通话中是很常见的,微信也有这个功能。实现这个功能很简单的。只需要在同意的时候,给RemoteInvitation对方设置 response ,如下所示
//收到呼叫转语音 伪代码
fun onRemoteInvitationReceived(RemoteInvitation var1){
val mediaType = var.content.get("mediaType")
if(mediaType==0){//视频呼叫
val remote = var1
remote.setResponse("mediaType:1")//语音
rtmCallManager.acceptRemoteInvitation(remote, null)
}
}
当我们给 RemoteInvitation 对象设置 response后,并且同意后,主叫会收到
//对方同意了你的呼叫
void onLocalInvitationAccepted(LocalInvitation var1, String response);
其中第二个参数就是被叫设置的 response,然后我们可以在这解析,判断对方回的 mediaType,是否和本地发起时候的一致,不一致就是对方转语音接听了。
拒绝呼叫/呼叫正忙
流程图(拒绝呼叫)
fun onRemoteInvitationReceived(RemoteInvitation var1){
if(inCalling){//如果我此时正在呼叫(isCalling为自己本地记录,SDK并无判断自己是都在通话中相关方法)
val remote = var1
remote.setResponse("Busy")//正忙
rtmCallManager.rejectRemoteInvitation(remote, null)
}
当我们给 RemoteInvitation 对象设置 response后,并且拒绝后,主叫会收到
//对方拒绝了你的呼叫
void onLocalInvitationRefused(LocalInvitation var1, String response);
其中第二个参数就是被叫设置的 response,然后我们可以在这解析,判断对方拒绝的原因并给予提示。
当然也可以不设置,不设置那就是默认正常拒绝。这些都属于业务逻辑,可以自己更改。
以上就是 RTM 点对点呼叫部分的流程,接下来就是挂断和进入 RTC 频道了。
加入RTC 频道
我们通常会在被叫同意后,双方开始加入 RTC 频道,RTC的频道ID 我们已经在主叫创建 LocalInvitation 对象时定义好了,并且通过自定义信息带给了被叫。所以我们只需要在以下回调中,分别做加入RTC 频道的逻辑即可
//主叫
void onLocalInvitationAccepted(LocalInvitation var1, String response){
//被叫同意呼叫后,主叫会收到该回调。在这里加入 rtc 频道即可
}
//被叫
void onRemoteInvitationAccepted(RemoteInvitation var1){
//被叫同意呼叫后,会收到该回调。在这里解析RemoteInvitation 对象中的content 字端,获取主叫定义的rtcChannelId,然后加入 rtc 频道即可
}
关于加入 RTC 等音视频处理,本文不做过多介绍。
挂断
需要注意的是,在被叫同意/拒绝后,RTM 的呼叫流程其实就已经结束了。我们在通话中挂断需要通过 RTM 信令通知对方。比如向主叫发送一条个人信息
rtmClient.sendMessageToPeer()
消息格式也可以自定义,只需要双方约定好即可。比如发送,"CMD:EndCall"
自己发送完和对方收到后,退出 RTC 频道即可,这样就完成了一整套的呼叫。
当然还有一些异常的情况,比如双方有个人通话中断线了,直接杀App进程了,这种异常情况,可以考虑订阅对方在线状态处理,或者自己定义一套异常的处理措施。
总结
- RTM 和 RTC 是两个完全分开的SDK,RTM 负责通话邀请的信令交互,RTC负责音视频
- LocalInvitation对象可以设置自定义的信息,并且会在被叫回调RemoteInvitation对象出现
- RemoteInvitation 对象可以设置回执信息,且返回给主叫
以上就是基于 RTM RTC SDK实现点对点视频通话的基本流程,基于以上流程,我们也有相应的参考DEMO,
下一篇将介绍如何实现多人呼叫,中途邀请其他人参与呼叫等例子。