2016-04-04 10 views
0

Ich versuche, einen Web-basierte Live-Webcam-Streaming-Dienst einrichten, wo ein Benutzer live via Webcam (nur Web-basierte) übertragen kann, dh:Kann RTCPeerConnection für Live-Cam-Dienste verwendet werden oder brauche ich einen Medienserver?

Benutzer A Starten eine Live-Übertragung bei

http://www.example.com/user-a 

Benutzern B , C, D, E und Zählung geht auf Besuche, dh uRL:

http://www.example.com/user-a 

und wird die Live-Sendung/Stream sehen können. Ich spielte mit RTCPeerConnection um Peer zu Peer zu erstellen, um Strom zu teilen, um Bandbreite und Serverlast zu sparen, und ich bin in der Lage, den folgenden Code zu verwenden, und OfferToReceiveAudio: true, OfferToReceiveVideo: true Bedingungen zu gehen. Es funktioniert ganz gut.

Jetzt habe ich es geschafft, neue Peer-Verbindung für jeden verbundenen Peer (Viewer) zu erstellen. Auf diese Weise kann jeder von der Webcam und andere (Peers) in der Lage sein, Broadcast zu sehen. Ich bin verwirrt, wenn dies ein skalierbarer Prozess ist, was bedeutet, wenn Benutzer-A sendet und Zuschauer sind 500+, und Benutzer-b sendet und Zuschauer sind 1000. Ist dies zuverlässig für Live-Übertragungen. Ich möchte einen Medienserver nicht einrichten, deshalb verwende ich webrtc Sache.

Kunde

var 
    ws = new WebSocket('wss://www.example.com:443'), 
    isRemote = false, 
    iStream = null, 
    iDescription = null, 
    iAnswer = null, 
    video = document.querySelector('video'), 
    peerConnCfg = {'iceServers': 
    [{'url': 'stun:stun.services.mozilla.com'}, {'url': 'stun:stun.l.google.com:19302'}] 
    }, 
    mediaConstraints = { 
     OfferToReceiveAudio: true, 
     OfferToReceiveVideo: true 
    }, 
    peer; 

    ws.onmessage = function(message){ 
     var json = JSON.parse(message.data); 
     if(isRemote==true){ 
      if(json.result=="ok"){ 
       StartWatch(json.sdp, json.ice); 
      }else{ 
       console.log("Watch start failed..."); 
      } 
     }else{ 
      if(json.result=="ok" && json.action=="rsdp"){ 
       peer.setRemoteDescription(new RTCSessionDescription(json.sdp), function() { 

        peer.addIceCandidate(new RTCIceCandidate(json.ice)).then(function(){ 
         console.log("added remote ice"); 
        }).catch(function(e){ 
         console.log(e); 
        }); 


       }, function(error){ 
        console.log("Offer remote failed error : " + error); 
       }); 
      } 
      console.log("Remote is false..."); 
     } 
    }; 

function golive(){ 
    peer = new RTCPeerConnection(peerConnCfg); 
    peer.onicecandidate = function(event){ 
      console.log("Got candidate..."); 
     if(event.candidate != null) { 
      ws.send(JSON.stringify({'mod' : 'golive', 'channel': 'channel-xyz', 'sdp' : iDescription, 'ice' : event.candidate})); 
     } 
    }; 

    navigator.getUserMedia({ audio: true, video: { width: 1280, height: 720 } }, 
      function(stream) { 
      iVideoStream = stream; 
      video.src = window.URL.createObjectURL(stream); 
      video.onloadedmetadata = function(e){ 
       video.play(); 
      }; 
      peer.addStream(stream); 
      peer.createOffer(function(description){ 
       //success 
       console.log("Got description..."); 
       peer.setLocalDescription(description, function() { 
        iDescription = description; 
       }, function() {console.log('set description error')}); 
      }, function(){ 
       //error 
      }); 
      }, 
      function(err) { 
      console.log("The following error occurred: " + err.name); 
      } 
    ); 

} 

function watch(){ 
    ws.send(JSON.stringify({'mod' : 'watch', 'channel': 'channel-xyz'})); 
} 

function StartWatch(sdp, ice){ 
    peer = new RTCPeerConnection(peerConnCfg); 
    peer.onicecandidate = function(event){ 
      console.log("Got candidate..."); 
      if(event.candidate != null) { 
       ws.send(JSON.stringify({'mod' : 'goliveupdate', 'channel': 'channel-xyz', 'sdp' : iAnswer, 'ice' : event.candidate})); 
      } 
    }; 
    peer.onaddstream = function(event){ 
     peer.addStream(event.stream); 
     video.src = window.URL.createObjectURL(event.stream); 
     video.onloadedmetadata = function(e){ 
      video.play(); 
     }; 
    }; 

    peer.setRemoteDescription(new RTCSessionDescription(sdp), function() { 
       peer.createAnswer(function(answer){ 
        peer.setLocalDescription(answer, function() { 
         iAnswer = answer; 
         peer.addIceCandidate(new RTCIceCandidate(ice)).then(function(){ 
          console.log("added"); 
         }).catch(function(e){ 
          console.log(e); 
         }); 


        }, function (error) { 
         console.log("Local desc error: " + error); 
        }); 
       }, function(error){ 
        console.log("Answer Error: " + error); 
       }); 

    }, function(error) { console.log('set description error: ' + error)}); 

} 

//i.e waitForSocketConnection 
function _init(){ 
    setTimeout(function(){ 
     if (ws.readyState === 1) { 
      console.log('Connected to WS'); 
      <?php 
       if(!isset($_GET['v'])){ 
        echo 'golive();'; 
       }else{ 
        echo 'isRemote = true; watch();'; 
       } 
      ?> 
      return; 
     }else{ 
      _init(); 
     } 
    }, 5); 
} 

_init(); 

Socket-Server für

"use strict"; 
var fs = require('fs'); 
var cfg = { 
    ssl: true, 
    port: 443, 
    ssl_key: '/home/csr/example_in.key', 
    ssl_cert: '/home/csr/example_in.crt' 
}; 
var app = null; 
var httpServ = (cfg.ssl) ? require('https') : require('http'); 
var processRequest = function(req, res) { 
    res.writeHead(200); 
    res.end("All glory to WebSockets!\n"); 
}; 
if (cfg.ssl) { 
    app = httpServ.createServer({ 
      // providing server with SSL key/cert 
      key: fs.readFileSync(cfg.ssl_key), 
      cert: fs.readFileSync(cfg.ssl_cert) 

    }, processRequest).listen(cfg.port); 
} else { 
    app = httpServ.createServer(processRequest).listen(cfg.port); 
} 

var WebSocketServer = require('ws').Server, 
wss = new WebSocketServer({server: app, host:'www.example.in'}), 

example = { 
    channels: [], 
    run: function(){ 
     wss.on('connection', function(ws) { 
      //example.channels.push(ws); 
      ws.on('message', function(message) { 
       //example.respond(ws, message); 
       example.respond(ws, JSON.parse(message)); 
      }); 
     }); 

     wss.on('close', function() { 
      example.closeChannel(ws); 
     }); 
    }, 

    closeChannel(ws){ 
     for (var channel in example.channels) { 
      var _channel = example.channels[channel]; 
      if (_channel[i] == ws){ delete _channel[i]; } 
      example.channels[channel] = example.swapArray(_channel); 
      if(example.channels && example.channels[channel] && !example.channels[channel].length) 
       delete example.channels[channel]; 
     } 
    }, 

    swapArray: function(arr) { 
     var swapped = [], 
     length = arr.length; 
     for (var i = 0; i < length; i++) { 
      if (arr[i]) 
       swapped[swapped.length] = arr[i]; 
     } 
     return swapped; 
    }, 

    respond : function(ws, message){ 
     //ws.send(message.mod); return; 
     switch(message.mod){ 
      case "golive": 
       example.channels[message.channel] = { 
        name : message.channel, 
        socket : ws, 
        sdp : message.sdp, 
        rsdp: null, 
        ice: message.ice, 
        rice: null 
       }; 
       ws.send(JSON.stringify({'result' : 'ok', 'action' : 'connected', 'channel': message.channel})); 
      break; 
      case "goliveupdate": 
       example.channels[message.channel].rsdp = message.sdp; 
      example.channels[message.channel].rice = message.ice; 
       example.channels[message.channel].socket.send(JSON.stringify({'result' : 'ok', 'action' : 'rsdp', 'sdp' : message.sdp, 'ice' : message.ice, 'message': 'A peer connected'})); 
      break; 
      case "watch": 
       if(example.channels[message.channel]){ 
        example.channels[message.channel].socket.send(JSON.stringify({'result' : 'ok', 'message': 'A peer connected'})); 
        ws.send(JSON.stringify({ 
         'result' : 'ok', 
         'action' : 'connected', 
         'message': 'Connected to ' + message.channel, 
         'sdp' : example.channels[message.channel].sdp, 
         'ice' : example.channels[message.channel].ice 
        })); 
       }else{ 
        ws.send(JSON.stringify({'result' : 'ok', 'message': 'Unable to connect to ' + message.channel})); 
       } 
      break; 
     } 
    } 
}; 

example.run(); 

Antwort

0

eine Eins-zu-Eins-Peer-Verbindung Signalisierung ist von Natur aus nicht "broadcast". Wenn sich der betreffende Nutzer nicht in Google Fiber City mit einer bulligen Box befindet, wird die Portierung von mehr als 500 Video-Peer-Verbindungen vom Upload-Link eines Nutzers offensichtlich nicht skaliert. Für diesen Datenverkehr benötigen Sie einen Medienserver.

+0

Ok. Ich versuche nun, den red5 media server einzurichten und werde Sie dann updaten. – Appklony

+0

@Appklony Ich bin kein Medienserver-Experte, aber ich stelle fest, dass auf ihrer Website steht: "Derzeit wird Unterstützung für WebRTC aufgebaut" ... – jib

Verwandte Themen