Android技術分享| 影片通話開發流程(一)

語言: CN / TW / HK

此文件基於 Android RTM、RTC SDK,其他平臺API 基本一致,可供參考。

​ RTM:用於搭建呼叫的一整套流程、信令互動

​ RTC:用於呼叫流程通了之後的音影片互動

由於呼叫和音影片是完全分開的兩個 sdk,所以在開發的時候需要注意的情況很多。

點對點呼叫

點對點呼叫就是2個人的通話,基本的通話場景中包含 發起呼叫拒絕呼叫同意呼叫影片呼叫轉語音接聽呼叫正忙 等。

下面我將一一介紹這幾個功能的實現以及需要注意的地方。

以下功能預設你已基本閱讀過 RTM RTC 文件且登入成功了 RTM SDK,RTC SDK 也已經準備好。

主叫-發起呼叫

  1. 建立 LocalInvitation 物件
val localInvitation = rtmCallManager.createLocalInvitation(userId)

​ 上述方法用於建立一個呼叫物件,:alarm_clock: 其中引數 userId 為對方的登入 RTM sdk 的 userId

  1. 新增自定義資訊

​ 發起呼叫的時候,通常我們都需要告訴對方本次是影片呼叫還是音訊呼叫,是否多人呼叫,或者其他跟業務相關的資訊。這時候就可以在上面建立的 localInvitation 物件中新增自定義資訊。

localInvitation.setContent("自定義的訊息體")

//通常我們都會選擇傳送json格式字串,例如
"mediaType":0 //0影片 1 音訊
"isMeeting":1 //0 多人模式 1 p2p
"rtcChannelId":"10000"//:warning:這個引數尤為重要,這個引數通常都由主叫生成,在呼叫的時候帶給被叫。該引數的作用是告訴對方我們這次呼叫將進入哪個 RTC 的頻道,兩個人進入同一個 RTC 頻道時,音影片才會通。
  1. 傳送呼叫
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 引數,在通話中我們也可以用到。稍後在轉語音接聽/通話正忙章節介紹。

同意呼叫

在對方發起呼叫後,被叫會收到以下相關回調。

//收到呼叫
void onRemoteInvitationReceived(RemoteInvitation var1);

//你同意了呼叫
void onRemoteInvitationAccepted(RemoteInvitation var1);

//你拒絕了呼叫
void onRemoteInvitationRefused(RemoteInvitation var1);

//對方取消了呼叫
void onRemoteInvitationCanceled(RemoteInvitation var1);

//呼叫邀請失敗,可能是長時間未接聽等情況,可檢視文件
void onRemoteInvitationFailure(RemoteInvitation var1, int var2);

流程圖(同意呼叫後)

<img src="https://docs.anyrtc.io/imgs/rtm/rtm_invite_andoid_image4.png" style="zoom:55%;" />

請注意被叫回調中的 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,是否和本地發起時候的一致,不一致就是對方轉語音接聽了。

拒絕呼叫/呼叫正忙

流程圖(拒絕呼叫)

<img src="https://docs.anyrtc.io/imgs/rtm/rtm_invite_andoid_image5.png" style="zoom:55%;" />

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程序了,這種異常情況,可以考慮訂閱對方線上狀態處理,或者自己定義一套異常的處理措施。

總結

  1. RTM 和 RTC 是兩個完全分開的SDK,RTM 負責通話邀請的信令互動,RTC負責音影片
  2. LocalInvitation物件可以設定自定義的資訊,並且會在被叫回調RemoteInvitation物件出現
  3. RemoteInvitation 物件可以設定回執資訊,且返回給主叫

以上就是基於 RTM RTC SDK實現點對點影片通話的基本流程,基於以上流程,我們也有相應的參考DEMO,

下一篇將介紹如何實現多人呼叫,中途邀請其他人蔘與呼叫等例子。