WebRTC:如何将客户端A的视频流式传输到客户端B?

时间:2016-11-23 04:25:43

标签: webrtc

我正在研究WebRTC,但我觉得我不了解全貌。我特别关注这个演示项目:https://github.com/oney/RCTWebRTCDemo/blob/master/main.js

我无法理解如何匹配2个客户端,以便客户A可以看到客户B的视频流,反之亦然。

这是在演示中:

function getLocalStream(isFront, callback) {
  MediaStreamTrack.getSources(sourceInfos => {
    console.log(sourceInfos);
    let videoSourceId;
    for (const i = 0; i < sourceInfos.length; i++) {
      const sourceInfo = sourceInfos[i];
      if(sourceInfo.kind == "video" && sourceInfo.facing == (isFront ? "front" : "back")) {
        videoSourceId = sourceInfo.id;
      }
    }
    getUserMedia({
      audio: true,
      video: {
        mandatory: {
          minWidth: 500, // Provide your own width, height and frame rate here
          minHeight: 300,
          minFrameRate: 30
        },
        facingMode: (isFront ? "user" : "environment"),
        optional: [{ sourceId: sourceInfos.id }]
      }
    }, function (stream) {
      console.log('dddd', stream);
      callback(stream);
    }, logError);
  });
}

然后就像这样使用:

socket.on('connect', function(data) {
  console.log('connect');
  getLocalStream(true, function(stream) {
    localStream = stream;
    container.setState({selfViewSrc: stream.toURL()});
    container.setState({status: 'ready', info: 'Please enter or create room ID'});
  });
});

问题:

  1. MediaStreamTrack.getSources到底在做什么?这是因为设备可以有多个视频源(例如3个网络摄像头)?

  2. getUserMedia是不是只打开客户端的相机?在上面的代码中,客户只是观看他自己的视频吗?

  3. 我想知道如何将客户端A的某种URL传递给客户端B,以便客户端B流式传输来自客户端A的视频。我该怎么做?我想象的是这样的事情:

    1. 客户A进入,加入房间“abc123”。等待其他客户加入
    2. 客户B进入,也加入了房间“abc123”。
    3. 客户A发出信号,表明客户B已进入房间,因此他与客户B
    4. 建立了联系
    5. 客户端A和客户端B从其网络摄像头开始流式传输。客户A可以看到客户端B,客户B可以看到客户端A.
    6. 我如何使用WebRTC库(您可以假设创建了用于房间匹配的后端服务器)

2 个答案:

答案 0 :(得分:3)

您正在寻找的流程称为 JSEP (JavaScript会话建立协议),它可以分为我在下面描述的3个步骤。一旦两个客户端都在房间内并且可以通过WebSockets进行通信,这些步骤就开始了,我将使用ws作为虚拟的WebSocket API,用于客户端与服务器和其他客户端之间的通信:

<强> 1。邀请

在此步骤中,一个desinged调用者创建并提供并通过服务器将其发送给另一个客户端(被调用者):

// This is only in Chrome
var pc = new webkitRTCPeerConnection({iceServers:[{url:"stun:stun.l.google.com:19302"}]}, {optional: [{RtpDataChannels: true}]});

// Someone must be chosen to be the caller
// (it can be either latest person who joins the room or the people in it)
ws.on('joined', function() {
  var offer = pc.createOffer(function (offer) {
    pc.setLocalDescription(offer);
    ws.send('offer', offer);
  });
});

// The callee receives offer and returns an answer
ws.on('offer', function (offer) {
  pc.setRemoteDescription(new RTCSessionDescription(offer));
  pc.createAnswer(function(answer) {
    pc.setLocalDescription(answer);
    ws.send('answer', answer);
  }, err => console.log('error'), {});
});

// The caller receives the answer
ws.on('answer', function (answer) {
  pc.setRemoteDescription(new RTCSessionDescription(answer));
});

现在双方已经交换了SDP数据包,并准备相互连接。

<强> 2。谈判(ICE)

ICE候选人由各方创建以找到相互连接的方式,它们几乎是可以找到它们的IP地址:localhost,局域网地址(192.168.xx)和外部公共IP地址(ISP )。它们由PC对象自动生成。

// Both processing them on each end:
ws.on('ICE', candidate => pc.addIceCandidate(new RTCIceCandidate(data)));
// Both sending them:
pc.onicecandidate = candidate => ws.send('ICE', candidate);

在ICE协商之后,除非您尝试通过连接两端的防火墙连接客户端,否则conexion将建立​​,p2p通信是NAT遍历,但在某些情况下无法工作。

第3。数据流

// Once the connection is established we can start to transfer video,
// audio or data

navigator.getUserMedia(function (stream) {
  pc.addStream(stream);
}, err => console.log('Error getting User Media'));

在为呼叫者创建优惠之前以及在收到被呼叫者的呼叫之后立即拨打电话并在之前的步骤中添加流是一个很好的选择,因此您不必处理与重新谈判。这是几年前的痛苦,但现在可能更好地在WebRTC中实施。

随意在GitHub中检查我的WebRTC项目,我在那里为许多参与者创建了p2p连接,它位于GitHub并且有一个live demo

答案 1 :(得分:2)

MediaStreamTrack.getSources用于连接视频设备。现在似乎已被弃用了。请参阅此stack-overflow问题和documentation。另请参阅MediaStreamTrack.getSources demo and code

是。 getUserMedia只是打开相机。您可以看到演示和代码here

请参阅此对等连接示例&amp;代码here,用于在用户之间传输音频和视频。

另请参阅this与WebRTC的实时通信。