1

我正在尝试学习如何使用这个新的很酷的 WebRTC API。

我正在关注本教程https://simpl.info/rtcpeerconnection/但我不明白如何从运行 UV4L 服务器的 Raspberry Pi 3 获取第二个流https://www.linux-projects.org/webrtc -信令/

我已经使用 websockets 测试了 UV4L 内置 WebRTC 页面的功能,它可以工作。

到目前为止,这是我的代码,但它只在本地和远程视频标签中显示我的本地流两次。

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

0 回答 0