WebRTC學習總結(4):多人視頻通話的實現思路

在1v1視頻通話中,雖然有發起人和接收人的概念,但是消息的發送和接受是“沒有對象”的,也就是,通過服務器轉發的message中沒有指明接受消息的對象,這在房間裏最多容納兩個人的前提下不會產生問題,但是在多人通話的過程中,就失效了。

對於我來說,我採取的措施是在offer、answer和candidate消息中加入新的屬性,也就是“callee”, 即呼叫人,舉個例子:

function handleIceCandidate(event) {
    //將本地的candidate發送給對方
    console.log('icecandidate event: ', event);
    if (event.candidate) {
        sendMessage({
            type: 'candidate',
            label: event.candidate.sdpMLineIndex,
            id: event.candidate.sdpMid,
            candidate: event.candidate.candidate,
            callee: id_list[i] //新加入的屬性,表示這個信息接收的對象
        });
    } else {
        console.log('candidates end');

    }
}

在信息的接收端,相應的,就多了一個判斷條件:

socket.on('message', function (message){
    //各種判斷條件
    else if (message.type === 'candidate' && isStarted && message.callee === socket.id) {
      console.log("收到對方發來的candidate");
      pc[i].addIceCandidate(candidate);
    }
    //其他代碼
}

這樣就避免了多個對象均接收到message卻搞不清應該是在呼叫哪個的困境。

在這個前提下,我就簡單講一講我多人視頻實現的思路。

  • 設置一個“isNew”變量,用來表示新進入房間的用戶。也就是對於新用戶isNew = true,對於已經在房間裏的用戶,isNew = false,對於第一個進入房間的人,,isNew = false;

  • 當新用戶進入房間時,已有用戶會受到“join”信號,此時,已有用戶向新用戶發送“ready”信號,同時發送自己的id;新用戶每受到一個“ready”信號,就將信號中的id保存在一個列表中;

  • 新用戶按照列表(id_list),以此與已有用戶建立連接。在與每個已有用戶建立連接之前,新用戶會發送一個帶有目標id的message(我取名叫“call”),對於已有用戶,只有id相符的isCallee = ture,只有在這個條件下,才能接受後續的來自新用戶的offer信息和candidate信息,否則不予響應,連接建立結束後,令isCallee = false,開始建立新的連接;

  • 對於每一個已有的用戶,只需要實例化pc[n]和新用戶建立連接即可,(n = pc.length);

  • 當新用戶與每個已有用戶都建立連接後,isNew = false,等待其他新用戶的來臨。

按照這種方式,新進入房間的用戶能與每一個已經在房間的用戶建立連接,這樣邏輯關係也比較清楚。

當然,還有很多其他的方式可以實現,在這裏就不贅述了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章