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

7

我在研究WebRTC,但感觉没有完全理解整个情况。特别是我在研究这个演示项目:https://github.com/oney/RCTWebRTCDemo/blob/master/main.js

我不明白如何匹配两个客户端,以便客户端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不就是打开客户端的相机吗?在上面的代码中,客户端只是在查看自己的视频吗?

我想知道如何将客户端A的某种URL传递给客户端B,以便客户端B从客户端A接收视频流。我该怎么做?我想象一下:

  1. 客户端A进入并加入房间“abc123”。等待另一个客户端加入
  2. 客户端B进入,并且也加入了房间“abc123”。
  3. 客户端A被通知客户端B已经进入房间,所以他与客户端B建立连接
  4. 客户端A和客户端B开始从他们的网络摄像头进行流式传输。客户端A可以看到客户端B,而客户端B可以看到客户端A。

使用WebRTC库,我应该如何实现它(您可以假设用于房间匹配的后端服务器已创建)

2个回答

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

1.邀请

在此步骤中,一个被指定的呼叫者创建并提供一个邀请,并通过服务器将其发送给另一个客户端(被呼叫者):

// 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地址,可以找到它们的地方:本地主机、本地区域网络地址(192.168.x.x)和外部公共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协商之后,连接将建立,除非您尝试通过连接两侧的防火墙连接客户端,点对点通信是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中可能实现得更好了。
欢迎查看我的WebRTC项目GitHub,我在其中为许多参与者创建房间内的点对点连接,它位于GitHub,并有live demo

1
非常感谢您提供的详细解释! - bigpotato

2

MediaStreamTrack.getSources 用于获取连接的视频设备,现在似乎已经弃用。请参考此stack-overflow问答和文档。也可以参考MediaStreamTrack.getSources演示和代码

是的,getUserMedia只是打开摄像头。您可以在这里查看演示和代码。

请参考此点对点连接的示例和代码here来在用户之间流传音频和视频。

另外,请查看有关WebRTC实时通信的这个


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接