javascript - How to display remote video with webRTC and socket.io -


i'm following tutorial create private videochat app between 2 peers https://codelabs.developers.google.com/codelabs/webrtc-web/#0

it works try add improvements closer of https://appr.tc/

my main issue can't display 1 camera share same page. want know if it's possible use 2 differents pages each camera in same room , if it's possible, how proceed?

thanks advance differents advices.

the code use:

index.js

'use strict';  var os = require('os'); var nodestatic = require('node-static'); var http = require('http'); var socketio = require('socket.io');  var fileserver = new(nodestatic.server)(); var app = http.createserver(function(req, res) {   fileserver.serve(req, res); }).listen(8080);  var io = socketio.listen(app); io.sockets.on('connection', function(socket) {    // convenience function log server messages on client   function log() {     var array = ['message server:'];     array.push.apply(array, arguments);     socket.emit('log', array);   }    socket.on('message', function(message) {     log('client said: ', message);     // real app, room-only (not broadcast)     socket.broadcast.emit('message', message);   });    socket.on('create or join', function(room) {     log('received request create or join room ' + room);      var numclients = io.sockets.sockets.length;     log('room ' + room + ' has ' + numclients + ' client(s)');      if (numclients === 1) {       socket.join(room);       log('client id ' + socket.id + ' created room ' + room);       socket.emit('created', room, socket.id);      } else if (numclients === 2) {       log('client id ' + socket.id + ' joined room ' + room);       io.sockets.in(room).emit('join', room);       socket.join(room);       socket.emit('joined', room, socket.id);       io.sockets.in(room).emit('ready');     } else { // max 2 clients       socket.emit('full', room);     }   });    socket.on('ipaddr', function() {     var ifaces = os.networkinterfaces();     (var dev in ifaces) {       ifaces[dev].foreach(function(details) {         if (details.family === 'ipv4' && details.address !== '127.0.0.1') {           socket.emit('ipaddr', details.address);         }       });     }   });    socket.on('bye', function(){     console.log('received bye');   });  }); 

app.js

'use strict';  var ischannelready = false; var isinitiator = false; var isstarted = false; var localstream; var pc; var remotestream; var turnready;  var pcconfig = {   'iceservers': [{     'urls': 'stun:stun.l.google.com:19302'   }] };  // set audio , video regardless of devices present. var sdpconstraints = {   offertoreceiveaudio: true,   offertoreceivevideo: true };  /////////////////////////////////////////////  var room = 'foo'; // prompt room name: // room = prompt('enter room name:');  var socket = io.connect();  if (room !== '') {   socket.emit('create or join', room);   console.log('attempted create or  join room', room); }  socket.on('created', function(room) {   console.log('created room ' + room);   isinitiator = true; });  socket.on('full', function(room) {   console.log('room ' + room + ' full'); });  socket.on('join', function (room){   console.log('another peer made request join room ' + room);   console.log('this peer initiator of room ' + room + '!');   ischannelready = true; });  socket.on('joined', function(room) {   console.log('joined: ' + room);   ischannelready = true; });  socket.on('log', function(array) {   console.log.apply(console, array); });  ////////////////////////////////////////////////  function sendmessage(message) {   console.log('client sending message: ', message);   socket.emit('message', message); }  // client receives message socket.on('message', function(message) {   console.log('client received message:', message);   if (message === 'got user media') {     maybestart();   } else if (message.type === 'offer') {     if (!isinitiator && !isstarted) {       maybestart();     }     pc.setremotedescription(new rtcsessiondescription(message));     doanswer();   } else if (message.type === 'answer' && isstarted) {     pc.setremotedescription(new rtcsessiondescription(message));   } else if (message.type === 'candidate' && isstarted) {     var candidate = new rtcicecandidate({       sdpmlineindex: message.label,       candidate: message.candidate     });     pc.addicecandidate(candidate);   } else if (message === 'bye' && isstarted) {     handleremotehangup();   } });  ////////////////////////////////////////////////////  var localvideo = document.queryselector('#localvideo'); var remotevideo = document.queryselector('#remotevideo');  navigator.mediadevices.getusermedia({   audio: false,   video: true }) .then(gotstream) .catch(function(e) {   alert('getusermedia() error: ' + e.name); });  function gotstream(stream) {   console.log('adding local stream.');   localvideo.src = window.url.createobjecturl(stream);   localstream = stream;   sendmessage('got user media');   if (isinitiator) {     maybestart();   } }  var constraints = {   video: true };  console.log('getting user media constraints', constraints);  if (location.hostname !== 'localhost') {   requestturn(     'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'   ); }  function maybestart() {   console.log('>>>>>>> maybestart() ', isstarted, localstream, ischannelready);   if (!isstarted && typeof localstream !== 'undefined' && ischannelready) {     console.log('>>>>>> creating peer connection');     createpeerconnection();     pc.addstream(localstream);     isstarted = true;     console.log('isinitiator', isinitiator);     if (isinitiator) {       docall();     }   } }  window.onbeforeunload = function() {   sendmessage('bye'); };  /////////////////////////////////////////////////////////  function createpeerconnection() {   try {     pc = new rtcpeerconnection(null);     pc.onicecandidate = handleicecandidate;     pc.onaddstream = handleremotestreamadded;     pc.onremovestream = handleremotestreamremoved;     console.log('created rtcpeerconnnection');   } catch (e) {     console.log('failed create peerconnection, exception: ' + e.message);     alert('cannot create rtcpeerconnection object.');     return;   } }  function handleicecandidate(event) {   console.log('icecandidate event: ', event);   if (event.candidate) {     sendmessage({       type: 'candidate',       label: event.candidate.sdpmlineindex,       id: event.candidate.sdpmid,       candidate: event.candidate.candidate     });   } else {     console.log('end of candidates.');   } }  function handleremotestreamadded(event) {   console.log('remote stream added.');   remotevideo.src = window.url.createobjecturl(event.stream);   remotestream = event.stream; }  function handlecreateoffererror(event) {   console.log('createoffer() error: ', event); }  function docall() {   console.log('sending offer peer');   pc.createoffer(setlocalandsendmessage, handlecreateoffererror); }  function doanswer() {   console.log('sending answer peer.');   pc.createanswer().then(     setlocalandsendmessage,     oncreatesessiondescriptionerror   ); }  function setlocalandsendmessage(sessiondescription) {   // set opus preferred codec in sdp if opus present.   //  sessiondescription.sdp = preferopus(sessiondescription.sdp);   pc.setlocaldescription(sessiondescription);   console.log('setlocalandsendmessage sending message', sessiondescription);   sendmessage(sessiondescription); }  function oncreatesessiondescriptionerror(error) {   trace('failed create session description: ' + error.tostring()); }  function requestturn(turnurl) {   var turnexists = false;   (var in pcconfig.iceservers) {     if (pcconfig.iceservers[i].url.substr(0, 5) === 'turn:') {       turnexists = true;       turnready = true;       break;     }   }   if (!turnexists) {     console.log('getting turn server ', turnurl);     // no turn server. 1 computeengineondemand.appspot.com:     var xhr = new xmlhttprequest();     xhr.onreadystatechange = function() {       if (xhr.readystate === 4 && xhr.status === 200) {         var turnserver = json.parse(xhr.responsetext);         console.log('got turn server: ', turnserver);         pcconfig.iceservers.push({           'url': 'turn:' + turnserver.username + '@' + turnserver.turn,           'credential': turnserver.password         });         turnready = true;       }     };     xhr.open('get', turnurl, true);     xhr.send();   } }  function handleremotestreamadded(event) {   console.log('remote stream added.');   remotevideo.src = window.url.createobjecturl(event.stream);   remotestream = event.stream; }  function handleremotestreamremoved(event) {   console.log('remote stream removed. event: ', event); }  function hangup() {   console.log('hanging up.');   stop();   sendmessage('bye'); }  function handleremotehangup() {   console.log('session terminated.');   stop();   isinitiator = false; }  function stop() {   isstarted = false;   // isaudiomuted = false;   // isvideomuted = false;   pc.close();   pc = null; }  ///////////////////////////////////////////  // set opus default audio codec if it's present. function preferopus(sdp) {   var sdplines = sdp.split('\r\n');   var mlineindex;   // search m line.   (var = 0; < sdplines.length; i++) {     if (sdplines[i].search('m=audio') !== -1) {       mlineindex = i;       break;     }   }   if (mlineindex === null) {     return sdp;   }    // if opus available, set default in m line.   (i = 0; < sdplines.length; i++) {     if (sdplines[i].search('opus/48000') !== -1) {       var opuspayload = extractsdp(sdplines[i], /:(\d+) opus\/48000/i);       if (opuspayload) {         sdplines[mlineindex] = setdefaultcodec(sdplines[mlineindex],           opuspayload);       }       break;     }   }    // remove cn in m line , sdp.   sdplines = removecn(sdplines, mlineindex);    sdp = sdplines.join('\r\n');   return sdp; }  function extractsdp(sdpline, pattern) {   var result = sdpline.match(pattern);   return result && result.length === 2 ? result[1] : null; }  // set selected codec first in m line. function setdefaultcodec(mline, payload) {   var elements = mline.split(' ');   var newline = [];   var index = 0;   (var = 0; < elements.length; i++) {     if (index === 3) { // format of media starts fourth.       newline[index++] = payload; // put target payload first.     }     if (elements[i] !== payload) {       newline[index++] = elements[i];     }   }   return newline.join(' '); }  // strip cn sdp before cn constraints ready. function removecn(sdplines, mlineindex) {   var mlineelements = sdplines[mlineindex].split(' ');   // scan end convenience of removing item.   (var = sdplines.length - 1; >= 0; i--) {     var payload = extractsdp(sdplines[i], /a=rtpmap:(\d+) cn\/\d+/i);     if (payload) {       var cnpos = mlineelements.indexof(payload);       if (cnpos !== -1) {         // remove cn payload m line.         mlineelements.splice(cnpos, 1);       }       // remove cn line in sdp       sdplines.splice(i, 1);     }   }    sdplines[mlineindex] = mlineelements.join(' ');   return sdplines; } 


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -