WebRTC Peer to Peer only display local stream twice

689 Views Asked by At

I'm trying to learn how to use this new cool WebRTC API.

I'm following this tutorial, https://simpl.info/rtcpeerconnection/ but I don't understand how to get the second stream from my Raspberry Pi 3 running UV4L server https://www.linux-projects.org/webrtc-signalling/

I have tested it the functionality with UV4L built-in WebRTC page using websockets and it works.

Here is my code so far, but it only displays my local stream twice in the local and remote video tags.

HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1" name="viewport">
    <title>Peer connection</title>
</head>
<body>
    <div id="container">
        <video autoplay="" id="localVideo"></video> <video autoplay="" id="remoteVideo"></video>
        <div>
      <button id="startButton">Start</button> <button id="callButton">Call</button> 
      <button id="hangupButton">Hang Up</button>
        </div>
    </div>
    <script src="js/main.js">
    </script>
</body>
</html>

JavaScript:

var startButton = document.getElementById('startButton');
var callButton = document.getElementById('callButton');
var hangupButton = document.getElementById('hangupButton');
callButton.disabled = true;
hangupButton.disabled = true;
startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;

var startTime;
var localVideo = document.getElementById('localVideo');
var remoteVideo = document.getElementById('remoteVideo');

var localStream;
var pc1;
var pc2;
var offerOptions = {
  offerToReceiveAudio: 1,
  offerToReceiveVideo: 1,
};

function getName(pc) {
  return pc === pc1 ? 'pc1' : 'pc2';
}

function getOtherPc(pc) {
  return pc === pc1 ? pc2 : pc1;
}

function gotStream(stream) {
  localVideo.srcObject = stream;
  localStream = stream;
  callButton.disabled = false;
}

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

function call() {
  callButton.disabled = true;
  hangupButton.disabled = false;
  startTime = window.performance.now();
  var videoTracks = localStream.getVideoTracks();
  var audioTracks = localStream.getAudioTracks();

  // MY UV4L stun server
  var servers = {
    iceServers: [ { urls: [ 'stun:' + '192.84.178.59' + ':3478' ] } ],
  };

  pc1 = new RTCPeerConnection(servers);
  pc1.onicecandidate = function(e) {
    onIceCandidate(pc1, e);
  };
  console.log(servers);
  pc2 = new RTCPeerConnection(servers);
  pc2.onicecandidate = function(e) {
    onIceCandidate(pc2, e);
  };
  pc1.oniceconnectionstatechange = function(e) {
    onIceStateChange(pc1, e);
  };
  pc2.oniceconnectionstatechange = function(e) {
    onIceStateChange(pc2, e);
  };
  pc2.ontrack = gotRemoteStream;

  localStream.getTracks().forEach(function(track) {
    pc1.addTrack(track, localStream);
  });

  pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}

function onCreateSessionDescriptionError(error) {
  console.log(error.toString());
}

function onCreateOfferSuccess(desc) {
  pc1.setLocalDescription(desc).then(function() {
    onSetLocalSuccess(pc1);
  }, onSetSessionDescriptionError);
  pc2.setRemoteDescription(desc).then(function() {
    onSetRemoteSuccess(pc2);
  }, onSetSessionDescriptionError);
  pc2.createAnswer().then(onCreateAnswerSuccess, onCreateSessionDescriptionError);
}

function onSetLocalSuccess(pc) {
  console.log(getName(pc) + ' setLocalDescription complete');
}

function onSetRemoteSuccess(pc) {
  console.log(getName(pc) + ' setRemoteDescription complete');
}

function onSetSessionDescriptionError(error) {
  console.log('Failed to set session description: ' + error.toString());
}

function gotRemoteStream(e) {
  if (remoteVideo.srcObject !== e.streams[0]) {
    console.log(e.streams[0]);
    remoteVideo.srcObject = e.streams[0];
  }
}

function onCreateAnswerSuccess(desc) {
  pc2.setLocalDescription(desc).then(function() {
    onSetLocalSuccess(pc2);
  }, onSetSessionDescriptionError);
  pc1.setRemoteDescription(desc).then(function() {
    onSetRemoteSuccess(pc1);
  }, onSetSessionDescriptionError);
}

function onIceCandidate(pc, event) {
  getOtherPc(pc).addIceCandidate(event.candidate).then(
    function() {
      onAddIceCandidateSuccess(pc);
    },
    function(err) {
      onAddIceCandidateError(pc, err);
    },
  );
}

function onAddIceCandidateSuccess(pc) {
  console.log(getName(pc) + ' addIceCandidate success');
}

function onAddIceCandidateError(pc, error) {
  console.log(getName(pc) + ' failed to add ICE Candidate: ' + error.toString());
}

function onIceStateChange(pc, event) {
  if (pc) {
    console.log(getName(pc) + ' ICE state: ' + pc.iceConnectionState);
    console.log('ICE state change event: ', event);
  }
}

function hangup() {
  pc1.close();
  pc2.close();
  pc1 = null;
  pc2 = null;
  hangupButton.disabled = true;
  callButton.disabled = false;
}
0

There are 0 best solutions below