0

大约一周以来,我一直在尝试通过 WebRTC 在两个客户端之间共享视频流,但我不知道如何进一步进行。我很沮丧,真的可以从更有经验的人那里得到一些帮助。请帮我把它运行起来。

我正在使用 Websockets 和 NodeJS。我将在下面发布我的所有代码:

服务器代码(在 NodeJS 上)

"use strict";

/** Requires **/
var  webSocketServer = require('websocket').server,
        expr = require("express"),
        xpress = expr(),
        server = require('http').createServer(xpress);
// Configure express
xpress.configure(function() {
     xpress.use(expr.static(__dirname + "/public"));
     xpress.set("view options", {layout: false});
});
// Handle GET requests to root directory
xpress.get('/', function(req, res) {
    res.sendfile(__dirname + '/public/index.html');
});
// WebSocket Server
var wsServer = new webSocketServer({
    httpServer: server
});
// Set up the http server
server.listen(8000, function(err) {
    if(!err) { console.log("Listening on port 8000"); }
});

var clients = [ ]; 

/** On connection established */
wsServer.on('request', function(request) { 
    // Accept connection - you should check 'request.origin' to make sure that client is connecting from your website
    var connection = request.accept(null, request.origin); 
    var self = this;    
    // We need to know client index to remove them on 'close' event
    var index = clients.push(connection) - 1;

    // Event Listener for when Clients send a message to the Server
    connection.on('message', function(message) {
        var parsedMessage = JSON.parse(message.utf8Data);
        if ( parsedMessage.kind == 'senderDescription' ) {
            wsServer.broadcastUTF(JSON.stringify({ kind:'callersDescription', callerData: parsedMessage }));
        }
    }); 
});

Index.html 加载并立即运行 VideoChatApp.js

function VideoChatApp() {
    this.connection = null;
    this.runConnection();
}

_p = VideoChatApp.prototype;


/** Initialize the connection and sets up the event listeners **/
_p.runConnection = function(){
    // To allow event listeners to have access to the correct scope
    var self = this;
    // if user is running mozilla then use it's built-in WebSocket
    window.WebSocket = window.WebSocket || window.MozWebSocket;
    // if browser doesn't support WebSocket, just show some notification and exit
    if (!window.WebSocket) { return;  }
    /** Where to make the connection **/     
    var host = location.origin.replace(/^http/, 'ws');
    console.log(host);
    this.connection = new WebSocket(host);
    /** Once the connection is established **/
    this.connection.onopen = function () {
        console.log("Web Socket Connection Established");
        self.onConnectionEstablished();        
    };
    /** If there was a problem with the connection */
    this.connection.onerror = function (error) {
        console.log("ERROR with the connection *sadface*");
    };
}; // end runConnection

_p.onConnectionEstablished = function() {  
    // My connection to the nodejs server
    var websocketConnection = this.connection;

    // Some local variables for use later
    var mediaConstraints = {
        optional: [],
        mandatory: {
            OfferToReceiveVideo: true
        }
    };
    var offerer, answerer;
    this.theLocalStream = null;
    var amITheCaller = false;
    var localVideoTag = document.getElementById('localVideoTag');
    var remoteVideoTag = document.getElementById('remoteVideoTag');
    window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
    window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
    window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
    navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
    window.URL = window.webkitURL || window.URL;
    window.iceServers = {
       iceServers: [{
           url: 'stun:23.21.150.121'
       }]
    };
    var callButton = document.getElementById("callButton");
    callButton.onclick = callClicked;
    function callClicked() {
      amITheCaller = true;
      setUpOffer();
    }
    offerer = new RTCPeerConnection(window.iceServers);
    answerer = new RTCPeerConnection(window.iceServers);


    /** Start Here - Set up my local stream **/
     getUserMedia(function (stream) {
         hookUpLocalStream(stream);
     });
     function getUserMedia(callback) {
         navigator.getUserMedia({
             video: true
         }, callback, onerror);

         function onerror(e) {
             console.error(e);
         }
     }
     function hookUpLocalStream(localStream) {
        this.theLocalStream = localStream;
        callButton.disabled = false;
        localVideoTag.src = URL.createObjectURL(localStream);
        localVideoTag.play();
     };


    /* When you click call, then we come here. Here I want to set up the offer and send it. */
    function setUpOffer() {
      var stream = theLocalStream;      
      offerer.addStream(stream);    

      offerer.onaddstream = function (event) {
        console.log("onaddstream callback was called");
      };

      offerer.onicecandidate = function (event) {
         if (!event || !event.candidate) return;
         answerer.addIceCandidate(event.candidate);
      };

      offerer.createOffer(function (offer) {
        offerer.setLocalDescription(offer);
            console.log("------------------- What I am sending: -------------------------");
            console.log(offer);
            console.log(stream);
            console.log("-----------------------------------------------------------------\n");
            var jsonMsg = JSON.stringify( {kind:'senderDescription', streamInfo: offer, theStream: stream} );
            websocketConnection.send( jsonMsg );  
            //answererPeer(offer, stream);            
      }, onSdpError, mediaConstraints);
    }

     /* Respond to a call */
    function answererPeer(offer, stream) {      
      answerer.addStream(stream);

      answerer.onaddstream = function (event) {         
         remoteVideoTag.src = URL.createObjectURL(event.stream);
         remoteVideoTag.play();
      };

      answerer.onicecandidate = function (event) {
         if (!event || !event.candidate) return;
         offerer.addIceCandidate(event.candidate);
      };

      answerer.setRemoteDescription(offer, onSdpSucces, onSdpError);
      answerer.createAnswer(function (answer) {
         answerer.setLocalDescription(answer);
         offerer.setRemoteDescription(answer, onSdpSucces, onSdpError);
      }, onSdpError, mediaConstraints);
    }

     function onSdpError(e) {
         console.error('onSdpError', e);
     }

     function onSdpSucces() {
         console.log('onSdpSucces');
     }

     websocketConnection.onmessage = function (messageFromServer) {
        console.log(" ------------------------ Message from server: -------------------- ");
        var parsedMessage = JSON.parse(messageFromServer.data);
        if(parsedMessage.callerData.kind = "senderDescription") {
            console.log("Received a senderDescription");
            console.log(parsedMessage.callerData.streamInfo);
            console.log(parsedMessage.callerData.theStream);
            console.log("-------------------------------------------------------------------\n");
            answererPeer(parsedMessage.callerData.streamInfo, parsedMessage.callerData.theStream);            
        }        
    }; 
};// end onConnectionEstablished()

最后,这是我的错误: 在此处输入图像描述

4

2 回答 2

0

我不确定这对您是否仍然感兴趣,但我在使用 PeerJS 作为其包装器的 WebRTC 方面有一些非常好的经验。它会处理您不想做的所有事情(http://peerjs.com/)。有客户端库以及一个非常好的 nodejs 信号服务器(https://github.com/peers/peerjs-server)。您可以在自己的节点服务器中轻松扩展此服务器。这可能无法解释您的方法失败的原因,但可以让 WebRTC 轻松运行。

于 2014-10-16T22:03:38.500 回答
-1

您可以从已经运行且完全开放的代码开始。查看easyrtc.com,我们有一个客户端api、信令服务器和工作代码。如果您对该代码有疑问,请在 Google Groups for easyrtc 上向我们寻求帮助。

于 2013-11-12T07:12:27.603 回答