0

我已经在节点 js 中实现了信号服务器并使用 googles stun 服务器

var http = require("http");
var fs = require("fs");
var websocket = require("websocket").server;

// general variables
var port = 1234;
var webrtc_clients = [];
var webrtc_discussions = {};

// web server functions
var http_server = http.createServer(function(request, response) {
  /*var matches = undefined;
  if (matches = request.url.match("^/images/(.*)")) {
    var path = process.cwd()+"/images/"+matches[1];
    fs.readFile(path, function(error, data) {
      if (error) {
        log_error(error);
      } else {
        response.end(data);
      }
    });
  } else {
    response.end(page);
  }
  */
  response.write(page);
  response.end();
});
http_server.listen(port, function() {
  log_comment("server listening (port "+port+")");
});
var page = undefined;
fs.readFile("index.html", function(error, data) {
  if (error) {
    log_error(error);
  } else {
    page = data;
  }
});

// web socket functions
var websocket_server = new websocket({
  httpServer: http_server
});

websocket_server.on("request", function(request) {
    log_comment("new request ("+request.origin+")");
  
    var connection = request.accept(null, request.origin);
    log_comment("new connection ("+connection.remoteAddress+")");
  
    webrtc_clients.push(connection);
    connection.id = webrtc_clients.length-1;
    
    connection.on("message", function(message) {
      if (message.type === "utf8") {
        log_comment("got message "+message.utf8Data);
  
        var signal = undefined;
        try { signal = JSON.parse(message.utf8Data); } catch(e) { };
        if (signal) {
          if (signal.type === "join" && signal.token !== undefined) {
            try {
              if (webrtc_discussions[signal.token] === undefined) {
                webrtc_discussions[signal.token] = {};
              }
            } catch(e) { };
            try {
              webrtc_discussions[signal.token][connection.id] = true;
            } catch(e) { };
          } else if (signal.type !== undefined) {
            try {
              Object.keys(webrtc_discussions[signal.token]).forEach(function(id) {
                if (id != connection.id) {
                  webrtc_clients[id].send(message.utf8Data, log_error);
                }
              });
            } catch(e) { };
          } else {
            log_comment("invalid signal: "+message.utf8Data);
          }
        } else {
          log_comment("invalid signal: "+message.utf8Data);
        }
      }
    });
    
    connection.on("close", function(connection) {
      log_comment("connection closed ("+connection.remoteAddress+")");    
      Object.keys(webrtc_discussions).forEach(function(token) {
        Object.keys(webrtc_discussions[token]).forEach(function(id) {
          if (id === connection.id) {
            delete webrtc_discussions[token][id];
          }
        });
      });
    });
});
  
// utility functions
function log_error(error) {
    if (error !== "Connection closed" && error !== undefined) {
      log_comment("ERROR: "+error);
    }
}
function log_comment(comment) {
  console.log((new Date())+" "+comment);
}

上面是 server.js 文件,下面是 index.html

<html>
    <head>
        <script>
                        
            var webrtc_capable = true;
            var rtc_peer_connection = null;
            var rtc_session_description = null;
            var get_user_media = null;
            var connect_stream_to_src = null;
            var stun_server = "stun.l.google.com:19302";
            
            // initializing variables
            if (navigator.getUserMedia) { // WebRTC 1.0 standard compliant browser
              rtc_peer_connection = RTCPeerConnection;
              rtc_session_description = RTCSessionDescription;
              get_user_media = navigator.getUserMedia.bind(navigator);
              connect_stream_to_src = function(media_stream, media_element) {
                // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21606
                media_element.srcObject = media_stream;
                media_element.play();
              };
            } else if (navigator.mozGetUserMedia) { // early firefox webrtc implementation
              rtc_peer_connection = mozRTCPeerConnection;
              rtc_session_description = mozRTCSessionDescription;
              get_user_media = navigator.mozGetUserMedia.bind(navigator);
              connect_stream_to_src = function(media_stream, media_element) {
                media_element.mozSrcObject = media_stream;
                media_element.play();
              };
              stun_server = "74.125.31.127:19302";
            } else if (navigator.webkitGetUserMedia) { // early webkit webrtc implementation
              rtc_peer_connection = webkitRTCPeerConnection;
              rtc_session_description = RTCSessionDescription;
              get_user_media = navigator.webkitGetUserMedia.bind(navigator);
              connect_stream_to_src = function(media_stream, media_element) {
                media_element.src = webkitURL.createObjectURL(media_stream);
              };
            } else {
              alert("This browser does not support WebRTC - visit WebRTC.org for more info");
              webrtc_capable = false;
            }
            
            var call_token;
            var signaling_server;
            var peer_conn;
            
            function start() {
                peer_conn = new rtc_peer_connection({ "iceServers": [ { "url": "stun:"+stun_server },]});
                
                signaling_server = new WebSocket("ws://192.168.1.5:1234");
                
                peer_conn.onicecandidate = function(ice_event){
                    if (ice_event.candidate) {
                        signaling_server.send(JSON.stringify({type:"new_ice_candidate",candidate:ice_event.candidate}));
                    }
                };
                
                peer_conn.onaddstream = function (event){
                    connect_stream_to_src(event.stream,document.getElementById("remotevideo"));
                };
                
                get_user_media(
                               {"audio":true,
                               "video":true},function (stream){
                    connect_stream_to_src(stream,document.getElementById("localvideo"));
                    peer_conn.addStream(stream);
                    },log_error);
                
                function new_description_created(description){
                    peer_conn.setLocalDescription(description,function (){
                        signaling_server.send(JSON.stringify({token:call_token,type:"new_description",sdp:description}));},log_error);
                }
                
                function caller_signal_handler(event){
                    var signal = JSON.parse(event.data);
                    
                    if (signal.type === "callee_arrived") {
                        peer_conn.createOffer(new_description_created,log_error);
                    }else if (signal.type === "new_ice_candidate") {
                        peer_conn.addIceCandidate(new RTCIceCandidate(signal.candidate));
                    }else if (signal.type === "new_description") {
                        peer_conn.setRemoteDescription(new rtc_session_description(signal.sdp,function (){
                            if (peer_conn.remoteDescription.type === "answer") {
                                //code
                            }},log_error));
                    }
                }
                
                function callee_signal_handler(event) {
                    var signal = JSON.parse(event.data);
                    if (signal.type === "new_ice_candidate") {
                        peer_conn.addIceCandidate(new RTCIceCandidate(signal.candidate));
                    }else if (signal.type === "new_description") {
                        peer_conn.setRemoteDescription(new rtc_session_description(signal.sdp), function (){
                            if (peer_conn.remoteDescription.type == "offer") {
                                peer_conn.createAnswer(new_description_created,log_error);
                            }},log_error);
                    }
                }
                
                if (document.location.hash === "" || document.location.hash === undefined) {
                    var token = Date.now()+"-"+Math.random(Math.random * 10000);
                    call_token = "#"+token;
                    
                    document.location.hash = token;
                    
                    signaling_server.onopen = function (){
                        signaling_server.onmessage = caller_signal_handler;
                        signaling_server.send(JSON.stringify({token:call_token,type:"join"}));
                    };
                    document.title = "you are the caller";
                }else {
                    call_token = document.location.hash;
                    
                    signaling_server.onopen = function (){
                        signaling_server.onmessage = callee_signal_handler;
                        signaling_server.send(JSON.stringify({token:call_token,type:"join"}));
                        signaling_server.send(JSON.stringify({token:call_token,type:"callee_arrived"}));
                    };
                    document.title = "you are the callee";
                }
                function log_error(error) {
                    console.log(error);
                }
            };
        </script>
        <style>
            #remotevideo{
                height: 100%;
                width: 100%;
            }
            #localvideo{
                height: 25%;
                width: 25%;
                position: absolute;
                left: 60%;
                top: 60%;
            }
        </style>
    </head>
    <body onload="start()">
        <video autoplay="true" id="remotevideo"></video>
        <video autoplay="true" id="localvideo"></video>
    </body>
</html>

我不明白,当被叫方连接时,远程视频不显示,但是当第三个被叫方连接到其他浏览器时,它甚至没有连接到呼叫

4

0 回答 0