Angular p2p视频聊天 - 远程流是黑色视频

时间:2015-04-07 19:37:34

标签: javascript angularjs video stream webrtc

我正在尝试在来电者和被叫者之间建立一个简单的p2p视频聊天。

这是代码:

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);
    }
  }
});

一切似乎都有效,但是当我将远程视频附加到<video id="remoteVideo"></video>时,我只看到一个黑色视频,我正在同一个网址和相同的wifi上测试:

来电者:localhost:8000

callee:localhost:8000?stranger = true

有人可以解释一下我的问题是什么吗?

1 个答案:

答案 0 :(得分:0)

我们应该注意,在设置remoteDescription之前,我们不会将ICECandidate添加到PeerConnection,假设这不是您当前的问题,可能是:

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);
  }
};

我不确定为什么被叫方正在发回远程流,因为它的本地流,除了使用此代码时,调用方在接收到被叫方的流时,什么都不做。 peerConnection.addStream用于与远程用户共享本地流。通常被叫者不必等待来电者的流来回应它的流。所以将上面的代码改为......

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) {
...

除此之外,我希望您编写的代码只是测试WebRTC工作的原型,它有一些设计问题,其中很少可能是:

  • 冰候选人处理可以是棍棒,呼叫者或被叫者iceCandidate之间没有区别。
  • 不喜欢显式指定调用者和被调用者的方式。
  • 当前系统不支持每个房间的多个同伴。