0

I am trying set up a simple p2p video chat between caller and callee.

This is the code:

var OnBroadcast
  , i
  , isCaller = true
  //just for testing pourpose
  , URLparams = $location.search()
  , iceServers = {
      'iceServers':[{
        'url':'stun:stun.l.google.com:19302'
      }]
    }
  , connOpt = {
      'optional':[{
        'DtlsSrtpKeyAgreement': true
      }]
    }
  , sdpConstraints = {
      'mandatory': {
        'OfferToReceiveAudio': true,
        'OfferToReceiveVideo': true
      }
    }
  , localVideo = $window.document.getElementById('localVideo')
  , remoteVideo = $window.document.getElementById('remoteVideo')
  , peerConnection = new RTCPeerConnection(iceServers, connOpt);

if (URLparams && URLparams.stranger) {

  isCaller = false;
}
peerConnection.onaddstream = function (stream) {
  if (!isCaller) {
    $log.info('Caller Stream is', stream);
    peerConnection.addStream(stream.stream);
    remoteVideo.src = $window.URL.createObjectURL(stream.stream);
  }
};

peerConnection.onicecandidate = function (ices) {
  if (isCaller) {

      ws.broadcast({
        'scope': 'callerICES',
        'message': ices
      });
  } else {

      ws.broadcast({
        'scope': 'calleeICES',
        'message': ices
      });
  }
};

navigator.getUserMedia({
    'audio': true,
    'video': true
  }, function (stream) {

  localVideo.src = $window.URL.createObjectURL(stream);

  if (isCaller) {
    /* VIDEO CHAT P2P----------
    * create CALLER Peer
    * CALLER addStream to peer
    * create CALLER Offer and CALLER setLocalDescription

    * send CALLER Offer to CALLEE and set CALLEE remoteDescription

    * create Answer from CALLEE and CALLEE setLocalDescription

    * send Answer to CALLER and set CALLER setRemoteDescription

    * CALLER icecandidate and send it to CALLEE and CALLEE  addIceCandidate

    * CALLEE icecandidate and send it to CALLER and CALLER addIceCandidate

    * CALLEE addStream
    */
    peerConnection.addStream(stream);

    peerConnection.createOffer(function (offer) {

      peerConnection.setLocalDescription(offer, function () {

          ws.broadcast({
            'scope': 'callerOFFER',
            'message': offer
          });
      });
    }, function (err) {
      $log.error('Unable to create Offer from Caller', err);
    });
  }
}, function (err) {
  $log.error('Unable to getUserMedia', err);
});

OnBroadcast = $rootScope.$on('comunicator:toAll', function (eventInfo, message) {

  if (message.what.scope === 'callerOFFER') {

    if (!isCaller) {

      peerConnection.setRemoteDescription(new RTCSessionDescription(message.what.message), function () {
        peerConnection.createAnswer(function (answer) {

          $log.info('Setup localDesc Callee');
          peerConnection.setLocalDescription(new RTCSessionDescription(answer), function () {

              ws.broadcast({
                'scope':'calleeANSWER',
                'message': answer
              });
          }, function (err) {
            $log.info('Unable to set localDesc for Callee', err);
          },
          sdpConstraints);
        }, function (err) {
          $log.error('Unable to create Answer from Callee', err);
        });
      });
    }
  }

  if (message.what.scope === 'calleeANSWER') {

    if (isCaller) {

      peerConnection.setRemoteDescription(new RTCSessionDescription(message.what.message), function () {

        $log.info('Setup remoteDesc Callee');
      });
    }
  }

  if (message.what.scope === 'callerICES') {

    if (!isCaller) {

      for (i = 0; i < message.what.length; i += 1) {

        peerConnection.addIceCandidate(new RTCIceCandidate(message.what[i]));
      }
      $log.info('Setup CALLEE ices', message.what);
    }
  }

  if (message.what.scope === 'calleeICES') {

    if (isCaller) {

      for (i = 0; i < message.what.length; i += 1) {

        peerConnection.addIceCandidate(new RTCIceCandidate(message.what[i]));
      }
      $log.info('Setup CALLER ices', message.what);
    }
  }
});

Everything seems to work, but when i attach remote video to <video id="remoteVideo"></video> i see a black video only, i am testing this on the same url and same wifi:

caller: localhost:8000

callee: localhost:8000?stranger=true

Can someone explain me which is the problem please?

1 Answers1

0

One should note that we shold not add ICECandidate to PeerConnection before it's remoteDescription is set, assuming that that is not your current problem, it might be:

peerConnection.onaddstream = function (stream) {
  if (!isCaller) {
    $log.info('Caller Stream is', stream);
    peerConnection.addStream(stream.stream);        // ---> specially this line.
    remoteVideo.src = $window.URL.createObjectURL(stream.stream);
  }
};

I am not sure why callee is sending back remote stream as it's local stream, other than that with this code, caller upon receiving callee's stream, would do nothing. peerConnection.addStream is used for sharing the your local stream with the remote user. and normally callee need not wait for caller's stream to respond with it's stream. so change the above code into...

peerConnection.onaddstream = function (event) {
    $log.info('add stream event:', event);
    remoteVideo.src = $window.URL.createObjectURL(event.stream);
};

...        // also add the retrieved stream to peerConnection for both caller and callee.

navigator.getUserMedia({
    'audio': true,
    'video': true
  }, function (stream) {

        peerConnection.addStream(stream);       // before if (isCaller) check
        localVideo.src = $window.URL.createObjectURL(stream);
        if (isCaller) {
...

other than that I hope that the code you have written is just a prototype for testing if WebRTC works, it has got some design issues, few of them may be:

  • Ice candidate handling can be clubbed, no difference between caller or callee iceCandidate.
  • do not like the way of explicitly specifying the caller and callee.
  • current system would not support multiple peers per room.
mido
  • 24,198
  • 15
  • 92
  • 117
  • thanks man for the awesome answer, now i changed the code as you described and it looks like something is happening or maybe not, the hard problem for me is to debug, cause i still seeing black video but audio SEEMS to work (the audio stream and not the video stream which is totally black) .... what you suggest to do? I really would like to understand what's happening :( – yeyhhhhhhh Apr 08 '15 at 07:20
  • but the local stream has both audio and video? – mido Apr 08 '15 at 07:30
  • also, check the answer to this http://stackoverflow.com/questions/17391750/remote-videostream-not-working-with-webrtc – mido Apr 08 '15 at 08:28
  • as you can see i specify to request both video and audio so i don't know much more about :( – yeyhhhhhhh Apr 08 '15 at 08:33
  • use a flag to check if remoteDescription is set, and do not add any ICE candidates before the flag is true. – mido Apr 08 '15 at 08:50