WebRTC con conexión de 3 usuarios

Ahora estoy implementando el código fuente deMuestras de WebRTC para convertirse en una conexión de 3 usuarios mediante el uso de topología de malla.

Sin embargo, mi código no funciona como pensé que sería. Creo que estoy atrapado en la función de llamadaiceCallBack# (# se refiere al número 1, 2, 3) porque el resultado de salida es el mismo que el original. Solo puede conectar 2 usuarios.

No sé cómo solucionarlo de manera adecuada.

Aquí hay algunos de mis códigos JavaScript en los que he estado trabajando:

    var audio2 = document.querySelector('audio#audio2');
    var audio3 = document.querySelector('audio#audio3');
    var pc1;
    var pc2;
    var pc3;

    function call() {
      callButton.disabled = true;
      codecSelector.disabled = true;
      trace('Starting call');
      var servers = null;
      var pcConstraints = {
        'optional': []
      };
      pc1 = new RTCPeerConnection(servers, pcConstraints);
      trace('Created local peer connection object pc1');
      pc1.onicecandidate = iceCallback1;

      pc2 = new RTCPeerConnection(servers, pcConstraints);
      trace('Created remote peer connection object pc2');
      pc2.onicecandidate = iceCallback2;
      pc2.onaddstream = gotRemoteStream;
      trace('Requesting local stream');

      pc3 = new RTCPeerConnection(servers, pcConstraints);
      trace('Created remote peer connection object pc2');
      pc3.onicecandidate = iceCallback3; 
      pc3.onaddstream = gotRemoteStream2;
      trace('Requesting local stream');

      navigator.mediaDevices.getUserMedia({
        audio: true,
        video: false
      })
      .then(gotStream)
      .catch(function(e) {
        alert('getUserMedia() error: ' + e.name);
      });
    }


    //Description of pc1 creating offer to pc2
    function gotDescription1(desc) {
      desc.sdp = forceChosenAudioCodec(desc.sdp);
      trace('Offer from pc1 \n' + desc.sdp);
      pc1.setLocalDescription(desc, function() {
        pc2.setRemoteDescription(desc, function() {
          pc2.createAnswer(gotDescription2, onCreateSessionDescriptionError);
        }, onSetSessionDescriptionError);
      }, onSetSessionDescriptionError);
    }

    //Description of pc1 creating offer to pc3
    function gotDescription3(desc) {
      desc.sdp = forceChosenAudioCodec(desc.sdp);
      trace('Offer from pc1 \n' + desc.sdp);
      pc1.setLocalDescription(desc, function() {
        pc3.setRemoteDescription(desc, function() {
          pc3.createAnswer(gotDescription4, onCreateSessionDescriptionError); //Must edit gotDescription4
        }, onSetSessionDescriptionError);
      }, onSetSessionDescriptionError);
    }

    //Creating answer from pc2
    function gotDescription2(desc) {
      desc.sdp = forceChosenAudioCodec(desc.sdp);
      pc2.setLocalDescription(desc, function() {
        trace('Answer from pc2 \n' + desc.sdp);
        pc1.setRemoteDescription(desc, function() {
        }, onSetSessionDescriptionError);
      }, onSetSessionDescriptionError);
    }

    //Creating answer from pc3
    function gotDescription4(desc) {
      desc.sdp = forceChosenAudioCodec(desc.sdp);
      pc3.setLocalDescription(desc, function() {
        trace('Answer from pc2 \n' + desc.sdp);
        pc1.setRemoteDescription(desc, function() {
        }, onSetSessionDescriptionError);
      }, onSetSessionDescriptionError);
    }

    function iceCallback1(event) {
      if (event.candidate) {
        pc2.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        pc3.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        trace('Local ICE candidate: \n' + event.candidate.candidate);
      }
    }

    function iceCallback2(event) {
      if (event.candidate) {
        pc1.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        pc3.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        trace('Remote ICE candidate: \n ' + event.candidate.candidate);
      }
    }

    function iceCallback3(event) {
      if (event.candidate) {
        pc1.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        pc2.addIceCandidate(new RTCIceCandidate(event.candidate),
            onAddIceCandidateSuccess, onAddIceCandidateError);
        trace('Remote ICE candidate: \n ' + event.candidate.candidate);
      }
    }
<div id="audio">
      <div>
        <div class="label">Local audio:</div><audio id="audio1" autoplay controls muted></audio>
      </div>
      <div>
        <div class="label">Remote audio2:</div><audio id="audio2" autoplay controls></audio>
      </div>
      <div>
        <div class="label">Remote audio3:</div><audio id="audio3" autoplay controls></audio>
      </div>
</div>

Nota: Soy nuevo con webRTC. Podría ser tonto de alguna manera, por favor perdóname.

Muchas gracias.

Respuestas a la pregunta(1)

Su respuesta a la pregunta