Node.js WebRTC-如何在提供和回答后建立对等连接

Node.js WebRTC-如何在提供和回答后建立对等连接,node.js,webrtc,Node.js,Webrtc,我有一个node.js正在运行,用户将连接到它。报价和答复将通过node.js生成和发送 我正在尝试建立对等连接,并通过摄像头流发送。我尝试了我的代码,没有将ICE候选机用作同一子网中的计算机。后来我试着实施了ICE。我不确定我是否做得对,或者如果计算机在同一子网上,是否需要这样做 var localStream; //Connect to signaling server var signalingChannel = io.connect('http://85.134.54.193:8001'

我有一个node.js正在运行,用户将连接到它。报价和答复将通过node.js生成和发送

我正在尝试建立对等连接,并通过摄像头流发送。我尝试了我的代码,没有将ICE候选机用作同一子网中的计算机。后来我试着实施了ICE。我不确定我是否做得对,或者如果计算机在同一子网上,是否需要这样做

var localStream;
//Connect to signaling server
var signalingChannel = io.connect('http://85.134.54.193:8001');
console.log("Connect to signaling server");
var servers = null;

var video1;
var video2;
var audio1;
var audio2;

var cfg = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]};//{ "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] };
var con = { 'optional': [{'DtlsSrtpKeyAgreement': true}, {'RtpDataChannels': true }] };
var peerConnection;

//Runs after the page has been loaded
window.onload=function(){
    //Gets ID for the video element which will display the local stream
    video1 = document.getElementById("audio1");
    //Gets ID for the video element which will display the remote stream
    video2 = document.getElementById("audio2");
    audio1 = document.getElementById("audio1");
    audio2 = document.getElementById("audio2");
    }

//Start button function
function caller(){
    peerConnection = new webkitRTCPeerConnection(cfg);
    navigator.webkitGetUserMedia({'audio':true, video:true}, function (stream) {
        console.log("Got local audio", stream);
        video1.src = window.webkitURL.createObjectURL(stream)
        peerConnection.addStream(stream);
    }, 
    function ( err ) {
        console.log( 'error: ', err );
    });

    console.log("Calling");
    //Create Offer
    peerConnection.createOffer(function (offerDesc) {
        console.log("Created local offer", offerDesc.sdp);
        peerConnection.setLocalDescription(offerDesc);
    }, function () { console.warn("Couldn't create offer"); });

    //ICE Candidates Generator
    peerConnection.onicecandidate = function(evt) {
        //When The Ice Gathering is complete
        if (evt.target.iceGatheringState == "complete") {
            //Create a new offer with ICE candidates
            peerConnection.createOffer(function(offer) {
                console.log("Offer with ICE candidates: " + offer.sdp);
                signalingChannel.emit('offer', JSON.stringify(offer));
                console.log("offer sent");
                signalingChannel.on('answer', function(data){
                    console.log("Receive answer");
                    //The answer is set as the remote description for the offerer
                    peerConnection.setRemoteDescription(new RTCSessionDescription(JSON.parse(data)));
                    console.log("Set remote desc");
                    peerConnection.onaddstream = gotRemoteStream;
                    console.log("Add remote stream to peer connection");
                });
            });
        }
    }

}

function answerer(){
    peerConnection = new webkitRTCPeerConnection(cfg);
    navigator.webkitGetUserMedia({'audio':true, video:true}, function (stream) {
        console.log("Got local audio", stream);
        video1.src = window.webkitURL.createObjectURL(stream)
        peerConnection.addStream(stream);
    }, 
    function ( err ) {
        console.log( 'error: ', err );
    });
    console.log("Answering");
    //Listen for offer
    signalingChannel.on('offer', function(data){
        console.log("Offer Received");
        //Set the remote description from caller's local description
        peerConnection.setRemoteDescription(new RTCSessionDescription(JSON.parse(data)));
        //Generate answer after getting the remote description
        peerConnection.createAnswer(function(sessionDescription) {
                //Set local description
                peerConnection.setLocalDescription(sessionDescription);
                //The local desc will be the answer sent back to offerer
                signalingChannel.emit('answer', JSON.stringify(sessionDescription));
                console.log("Answer sent");
                });
    });

}

function gotRemoteStream(event){
    video2.src = window.webkitURL.createObjectURL(event.stream);
}

为什么在创建答案之前要等待ICE完成?那么同时做呢?这可能会有所帮助,因为它只是为了同时工作。如果您可以在此之后发布日志,但它仍然不起作用,我们可以尝试进一步调试它。如果您想查看仅音频的示例(它同时发送音乐音频和麦克风音频),请选中,然后单击。服务器由node.js和ws-plugin组成。音频连接与webRTC配合使用。

以下是我今天(2014年2月)在Chrome上处理的一系列事件。这是一种简化的情况,即对等方1将视频流传输给对等方2

  • 设置对等方交换消息的方式。(令人遗憾的是,人们如何实现这一点的差异使得不同的WebRTC代码样本变得如此不可通约。但在思想上,以及在您的代码组织中,请尝试将此逻辑与其他逻辑分开。)
  • 在每一侧,为重要的信令消息设置消息处理程序。你可以设置它们,然后不设置它们。有3条核心消息需要处理和发送:
    • 从另一端发送的ice候选者==>使用它调用
      addIceCandidate
    • 提供消息==>
      SetRemoteDescription
      ,然后回答并发送它
    • 应答消息==>
      SetRemoteDescription
  • 在每一侧,创建一个新的peerconnection对象,并为重要事件附加事件处理程序:onicecandidate、onremovestream、onaddstream等。
    • ice候选==>将其发送到另一端
    • 添加的流==>将其附加到视频元素,以便您可以看到它
  • 当两个对等点都存在且所有处理程序都已就位时,对等点1会收到某种触发消息以开始视频捕获(使用
    getUserMedia
    调用)
  • 一旦
    getUserMedia
    成功,我们就有了一个流。在对等1的对等连接对象上调用
    addStream
  • 然后——也只有在那时——第1位提出了一个提议
  • 由于我们在第2步中设置了处理程序,对等方2得到了这个结果并发送了一个答案
  • 与此同时(有些模糊),对等连接对象开始生成ice候选对象。它们在两个对等方之间来回发送并处理(上面的步骤2和步骤3)
  • 由于以下两种情况,流媒体自动以不透明方式启动:
    • 报价/应答交换
    • ice候选人接收、交换和添加

  • 当我想更改流时,我返回到步骤3,设置一个新的对等连接对象,然后再次执行整个提供/应答。

    你有没有想过?