diff --git a/demos/video-conferencing.html b/demos/video-conferencing.html index 1c2103e5..a8008336 100644 --- a/demos/video-conferencing.html +++ b/demos/video-conferencing.html @@ -144,6 +144,80 @@

OfferToReceiveVideo: true }; +// STAR_FIX_VIDEO_AUTO_PAUSE_ISSUES +// via: https://github.com/muaz-khan/RTCMultiConnection/issues/778#issuecomment-524853468 +var bitrates = 512; +var resolutions = 'Ultra-HD'; +var videoConstraints = {}; + +if (resolutions == 'HD') { + videoConstraints = { + width: { + ideal: 1280 + }, + height: { + ideal: 720 + }, + frameRate: 30 + }; +} + +if (resolutions == 'Ultra-HD') { + videoConstraints = { + width: { + ideal: 1920 + }, + height: { + ideal: 1080 + }, + frameRate: 30 + }; +} + +connection.mediaConstraints = { + video: videoConstraints, + audio: true +}; + +var CodecsHandler = connection.CodecsHandler; + +connection.processSdp = function(sdp) { + var codecs = 'vp8'; + + if (codecs.length) { + sdp = CodecsHandler.preferCodec(sdp, codecs.toLowerCase()); + } + + if (resolutions == 'HD') { + sdp = CodecsHandler.setApplicationSpecificBandwidth(sdp, { + audio: 128, + video: bitrates, + screen: bitrates + }); + + sdp = CodecsHandler.setVideoBitrates(sdp, { + min: bitrates * 8 * 1024, + max: bitrates * 8 * 1024, + }); + } + + if (resolutions == 'Ultra-HD') { + sdp = CodecsHandler.setApplicationSpecificBandwidth(sdp, { + audio: 128, + video: bitrates, + screen: bitrates + }); + + sdp = CodecsHandler.setVideoBitrates(sdp, { + min: bitrates * 8 * 1024, + max: bitrates * 8 * 1024, + }); + } + + return sdp; +}; +// END_FIX_VIDEO_AUTO_PAUSE_ISSUES + // https://www.rtcmulticonnection.org/docs/iceServers/ // use your own TURN-server here! connection.iceServers = [{ diff --git a/index.html b/index.html deleted file mode 100644 index 4df2c47a..00000000 --- a/index.html +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - Video Conferencing using RTCMultiConnection - - - - - - -
- - MenuMenu - -
- -

- Video Conferencing using RTCMultiConnection -

- Multi-user (many-to-many) video chat using mesh networking model. -

-

- - Star - Issue - Fork - Follow @muaz-khan - -

-

- -
-
- - - -

- - - - - -
- -
- - -
- - - - - - - - - - - - -
-

RTCMultiConnection is a WebRTC JavaScript library for peer-to-peer streaming (e.g. screen sharing, audio/video conferencing, file sharing, media streaming etc.)

-
- - - - - - - diff --git a/old-server.js b/old-server.js deleted file mode 100644 index 926fd3a9..00000000 --- a/old-server.js +++ /dev/null @@ -1,291 +0,0 @@ -// http://127.0.0.1:9001 -// http://localhost:9001 - -const fs = require('fs'); -const path = require('path'); -const url = require('url'); -var httpServer = require('http'); - -const ioServer = require('socket.io'); -const RTCMultiConnectionServer = require('rtcmulticonnection-server'); - -var PORT = 9001; -var isUseHTTPs = false; - -const jsonPath = { - config: 'config.json', - logs: 'logs.json' -}; - -const BASH_COLORS_HELPER = RTCMultiConnectionServer.BASH_COLORS_HELPER; -const getValuesFromConfigJson = RTCMultiConnectionServer.getValuesFromConfigJson; -const getBashParameters = RTCMultiConnectionServer.getBashParameters; -const resolveURL = RTCMultiConnectionServer.resolveURL; - -var config = getValuesFromConfigJson(jsonPath); -config = getBashParameters(config, BASH_COLORS_HELPER); - -// if user didn't modifed "PORT" object -// then read value from "config.json" -if(PORT === 9001) { - PORT = config.port; -} -if(isUseHTTPs === false) { - isUseHTTPs = config.isUseHTTPs; -} - -function serverHandler(request, response) { - // to make sure we always get valid info from json file - // even if external codes are overriding it - config = getValuesFromConfigJson(jsonPath); - config = getBashParameters(config, BASH_COLORS_HELPER); - - // HTTP_GET handling code goes below - try { - var uri, filename; - - try { - if (!config.dirPath || !config.dirPath.length) { - config.dirPath = null; - } - - uri = url.parse(request.url).pathname; - filename = path.join(config.dirPath ? resolveURL(config.dirPath) : process.cwd(), uri); - } catch (e) { - pushLogs(config, 'url.parse', e); - } - - filename = (filename || '').toString(); - - if (request.method !== 'GET' || uri.indexOf('..') !== -1) { - try { - response.writeHead(401, { - 'Content-Type': 'text/plain' - }); - response.write('401 Unauthorized: ' + path.join('/', uri) + '\n'); - response.end(); - return; - } catch (e) { - pushLogs(config, '!GET or ..', e); - } - } - - if(filename.indexOf(resolveURL('/admin/')) !== -1 && config.enableAdmin !== true) { - try { - response.writeHead(401, { - 'Content-Type': 'text/plain' - }); - response.write('401 Unauthorized: ' + path.join('/', uri) + '\n'); - response.end(); - return; - } catch (e) { - pushLogs(config, '!GET or ..', e); - } - return; - } - - var matched = false; - ['/demos/', '/dev/', '/dist/', '/socket.io/', '/node_modules/canvas-designer/', '/admin/'].forEach(function(item) { - if (filename.indexOf(resolveURL(item)) !== -1) { - matched = true; - } - }); - - // files from node_modules - ['RecordRTC.js', 'FileBufferReader.js', 'getStats.js', 'getScreenId.js', 'adapter.js', 'MultiStreamsMixer.js'].forEach(function(item) { - if (filename.indexOf(resolveURL('/node_modules/')) !== -1 && filename.indexOf(resolveURL(item)) !== -1) { - matched = true; - } - }); - - if (filename.search(/.js|.json/g) !== -1 && !matched) { - try { - response.writeHead(404, { - 'Content-Type': 'text/plain' - }); - response.write('404 Not Found: ' + path.join('/', uri) + '\n'); - response.end(); - return; - } catch (e) { - pushLogs(config, '404 Not Found', e); - } - } - - ['Video-Broadcasting', 'Screen-Sharing', 'Switch-Cameras'].forEach(function(fname) { - try { - if (filename.indexOf(fname + '.html') !== -1) { - filename = filename.replace(fname + '.html', fname.toLowerCase() + '.html'); - } - } catch (e) { - pushLogs(config, 'forEach', e); - } - }); - - var stats; - - try { - stats = fs.lstatSync(filename); - - if (filename.search(/demos/g) === -1 && filename.search(/admin/g) === -1 && stats.isDirectory() && config.homePage === '/demos/index.html') { - if (response.redirect) { - response.redirect('/demos/'); - } else { - response.writeHead(301, { - 'Location': '/demos/' - }); - } - response.end(); - return; - } - } catch (e) { - response.writeHead(404, { - 'Content-Type': 'text/plain' - }); - response.write('404 Not Found: ' + path.join('/', uri) + '\n'); - response.end(); - return; - } - - try { - if (fs.statSync(filename).isDirectory()) { - response.writeHead(404, { - 'Content-Type': 'text/html' - }); - - if (filename.indexOf(resolveURL('/demos/MultiRTC/')) !== -1) { - filename = filename.replace(resolveURL('/demos/MultiRTC/'), ''); - filename += resolveURL('/demos/MultiRTC/index.html'); - } else if (filename.indexOf(resolveURL('/admin/')) !== -1) { - filename = filename.replace(resolveURL('/admin/'), ''); - filename += resolveURL('/admin/index.html'); - } else if (filename.indexOf(resolveURL('/demos/dashboard/')) !== -1) { - filename = filename.replace(resolveURL('/demos/dashboard/'), ''); - filename += resolveURL('/demos/dashboard/index.html'); - } else if (filename.indexOf(resolveURL('/demos/video-conference/')) !== -1) { - filename = filename.replace(resolveURL('/demos/video-conference/'), ''); - filename += resolveURL('/demos/video-conference/index.html'); - } else if (filename.indexOf(resolveURL('/demos')) !== -1) { - filename = filename.replace(resolveURL('/demos/'), ''); - filename = filename.replace(resolveURL('/demos'), ''); - filename += resolveURL('/demos/index.html'); - } else { - filename += resolveURL(config.homePage); - } - } - } catch (e) { - pushLogs(config, 'statSync.isDirectory', e); - } - - var contentType = 'text/plain'; - if (filename.toLowerCase().indexOf('.html') !== -1) { - contentType = 'text/html'; - } - if (filename.toLowerCase().indexOf('.css') !== -1) { - contentType = 'text/css'; - } - if (filename.toLowerCase().indexOf('.png') !== -1) { - contentType = 'image/png'; - } - - fs.readFile(filename, 'binary', function(err, file) { - if (err) { - response.writeHead(500, { - 'Content-Type': 'text/plain' - }); - response.write('404 Not Found: ' + path.join('/', uri) + '\n'); - response.end(); - return; - } - - try { - file = file.replace('connection.socketURL = \'/\';', 'connection.socketURL = \'' + config.socketURL + '\';'); - } catch (e) {} - - response.writeHead(200, { - 'Content-Type': contentType - }); - response.write(file, 'binary'); - response.end(); - }); - } catch (e) { - pushLogs(config, 'Unexpected', e); - - response.writeHead(404, { - 'Content-Type': 'text/plain' - }); - response.write('404 Not Found: Unexpected error.\n' + e.message + '\n\n' + e.stack); - response.end(); - } -} - -var httpApp; - -if (isUseHTTPs) { - httpServer = require('https'); - - // See how to use a valid certificate: - // https://github.com/muaz-khan/WebRTC-Experiment/issues/62 - var options = { - key: null, - cert: null, - ca: null - }; - - var pfx = false; - - if (!fs.existsSync(config.sslKey)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslKey:\t ' + config.sslKey + ' does not exist.'); - } else { - pfx = config.sslKey.indexOf('.pfx') !== -1; - options.key = fs.readFileSync(config.sslKey); - } - - if (!fs.existsSync(config.sslCert)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCert:\t ' + config.sslCert + ' does not exist.'); - } else { - options.cert = fs.readFileSync(config.sslCert); - } - - if (config.sslCabundle) { - if (!fs.existsSync(config.sslCabundle)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCabundle:\t ' + config.sslCabundle + ' does not exist.'); - } - - options.ca = fs.readFileSync(config.sslCabundle); - } - - if (pfx === true) { - options = { - pfx: sslKey - }; - } - - httpApp = httpServer.createServer(options, serverHandler); -} else { - httpApp = httpServer.createServer(serverHandler); -} - -RTCMultiConnectionServer.beforeHttpListen(httpApp, config); -httpApp = httpApp.listen(process.env.PORT || PORT, process.env.IP || "0.0.0.0", function() { - RTCMultiConnectionServer.afterHttpListen(httpApp, config); -}); - -// -------------------------- -// socket.io codes goes below - -ioServer(httpApp).on('connection', function(socket) { - RTCMultiConnectionServer.addSocket(socket, config); - - // ---------------------- - // below code is optional - - const params = socket.handshake.query; - - if (!params.socketCustomEvent) { - params.socketCustomEvent = 'custom-message'; - } - - socket.on(params.socketCustomEvent, function(message) { - socket.broadcast.emit(params.socketCustomEvent, message); - }); -}); diff --git a/server.js b/server.js index aa8ce0a9..926fd3a9 100755 --- a/server.js +++ b/server.js @@ -1,36 +1,190 @@ // http://127.0.0.1:9001 // http://localhost:9001 -var server = require('http'), - url = require('url'), - path = require('path'), - fs = require('fs'); +const fs = require('fs'); +const path = require('path'); +const url = require('url'); +var httpServer = require('http'); +const ioServer = require('socket.io'); +const RTCMultiConnectionServer = require('rtcmulticonnection-server'); + +var PORT = 9001; +var isUseHTTPs = false; + +const jsonPath = { + config: 'config.json', + logs: 'logs.json' +}; + +const BASH_COLORS_HELPER = RTCMultiConnectionServer.BASH_COLORS_HELPER; +const getValuesFromConfigJson = RTCMultiConnectionServer.getValuesFromConfigJson; +const getBashParameters = RTCMultiConnectionServer.getBashParameters; +const resolveURL = RTCMultiConnectionServer.resolveURL; + +var config = getValuesFromConfigJson(jsonPath); +config = getBashParameters(config, BASH_COLORS_HELPER); + +// if user didn't modifed "PORT" object +// then read value from "config.json" +if(PORT === 9001) { + PORT = config.port; +} +if(isUseHTTPs === false) { + isUseHTTPs = config.isUseHTTPs; +} function serverHandler(request, response) { - var uri = url.parse(request.url).pathname, - filename = path.join(process.cwd(), uri); + // to make sure we always get valid info from json file + // even if external codes are overriding it + config = getValuesFromConfigJson(jsonPath); + config = getBashParameters(config, BASH_COLORS_HELPER); + + // HTTP_GET handling code goes below + try { + var uri, filename; + + try { + if (!config.dirPath || !config.dirPath.length) { + config.dirPath = null; + } + + uri = url.parse(request.url).pathname; + filename = path.join(config.dirPath ? resolveURL(config.dirPath) : process.cwd(), uri); + } catch (e) { + pushLogs(config, 'url.parse', e); + } + + filename = (filename || '').toString(); + + if (request.method !== 'GET' || uri.indexOf('..') !== -1) { + try { + response.writeHead(401, { + 'Content-Type': 'text/plain' + }); + response.write('401 Unauthorized: ' + path.join('/', uri) + '\n'); + response.end(); + return; + } catch (e) { + pushLogs(config, '!GET or ..', e); + } + } + + if(filename.indexOf(resolveURL('/admin/')) !== -1 && config.enableAdmin !== true) { + try { + response.writeHead(401, { + 'Content-Type': 'text/plain' + }); + response.write('401 Unauthorized: ' + path.join('/', uri) + '\n'); + response.end(); + return; + } catch (e) { + pushLogs(config, '!GET or ..', e); + } + return; + } + + var matched = false; + ['/demos/', '/dev/', '/dist/', '/socket.io/', '/node_modules/canvas-designer/', '/admin/'].forEach(function(item) { + if (filename.indexOf(resolveURL(item)) !== -1) { + matched = true; + } + }); + + // files from node_modules + ['RecordRTC.js', 'FileBufferReader.js', 'getStats.js', 'getScreenId.js', 'adapter.js', 'MultiStreamsMixer.js'].forEach(function(item) { + if (filename.indexOf(resolveURL('/node_modules/')) !== -1 && filename.indexOf(resolveURL(item)) !== -1) { + matched = true; + } + }); + + if (filename.search(/.js|.json/g) !== -1 && !matched) { + try { + response.writeHead(404, { + 'Content-Type': 'text/plain' + }); + response.write('404 Not Found: ' + path.join('/', uri) + '\n'); + response.end(); + return; + } catch (e) { + pushLogs(config, '404 Not Found', e); + } + } - fs.exists(filename, function(exists) { - if (!exists) { + ['Video-Broadcasting', 'Screen-Sharing', 'Switch-Cameras'].forEach(function(fname) { + try { + if (filename.indexOf(fname + '.html') !== -1) { + filename = filename.replace(fname + '.html', fname.toLowerCase() + '.html'); + } + } catch (e) { + pushLogs(config, 'forEach', e); + } + }); + + var stats; + + try { + stats = fs.lstatSync(filename); + + if (filename.search(/demos/g) === -1 && filename.search(/admin/g) === -1 && stats.isDirectory() && config.homePage === '/demos/index.html') { + if (response.redirect) { + response.redirect('/demos/'); + } else { + response.writeHead(301, { + 'Location': '/demos/' + }); + } + response.end(); + return; + } + } catch (e) { response.writeHead(404, { 'Content-Type': 'text/plain' }); - response.write('404 Not Found: ' + filename + '\n'); + response.write('404 Not Found: ' + path.join('/', uri) + '\n'); response.end(); return; } - if (filename.indexOf('favicon.ico') !== -1) { - return; - } + try { + if (fs.statSync(filename).isDirectory()) { + response.writeHead(404, { + 'Content-Type': 'text/html' + }); - var isWin = !!process.platform.match(/^win/); + if (filename.indexOf(resolveURL('/demos/MultiRTC/')) !== -1) { + filename = filename.replace(resolveURL('/demos/MultiRTC/'), ''); + filename += resolveURL('/demos/MultiRTC/index.html'); + } else if (filename.indexOf(resolveURL('/admin/')) !== -1) { + filename = filename.replace(resolveURL('/admin/'), ''); + filename += resolveURL('/admin/index.html'); + } else if (filename.indexOf(resolveURL('/demos/dashboard/')) !== -1) { + filename = filename.replace(resolveURL('/demos/dashboard/'), ''); + filename += resolveURL('/demos/dashboard/index.html'); + } else if (filename.indexOf(resolveURL('/demos/video-conference/')) !== -1) { + filename = filename.replace(resolveURL('/demos/video-conference/'), ''); + filename += resolveURL('/demos/video-conference/index.html'); + } else if (filename.indexOf(resolveURL('/demos')) !== -1) { + filename = filename.replace(resolveURL('/demos/'), ''); + filename = filename.replace(resolveURL('/demos'), ''); + filename += resolveURL('/demos/index.html'); + } else { + filename += resolveURL(config.homePage); + } + } + } catch (e) { + pushLogs(config, 'statSync.isDirectory', e); + } - if (fs.statSync(filename).isDirectory() && !isWin) { - filename += '/index.html'; - } else if (fs.statSync(filename).isDirectory() && !!isWin) { - filename += '\\index.html'; + var contentType = 'text/plain'; + if (filename.toLowerCase().indexOf('.html') !== -1) { + contentType = 'text/html'; + } + if (filename.toLowerCase().indexOf('.css') !== -1) { + contentType = 'text/css'; + } + if (filename.toLowerCase().indexOf('.png') !== -1) { + contentType = 'image/png'; } fs.readFile(filename, 'binary', function(err, file) { @@ -38,58 +192,88 @@ function serverHandler(request, response) { response.writeHead(500, { 'Content-Type': 'text/plain' }); - response.write(err + '\n'); + response.write('404 Not Found: ' + path.join('/', uri) + '\n'); response.end(); return; } - var contentType; - - if (filename.indexOf('.html') !== -1) { - contentType = 'text/html'; - } - - if (filename.indexOf('.js') !== -1) { - contentType = 'application/javascript'; - } - - if (contentType) { - response.writeHead(200, { - 'Content-Type': contentType - }); - } else response.writeHead(200); + try { + file = file.replace('connection.socketURL = \'/\';', 'connection.socketURL = \'' + config.socketURL + '\';'); + } catch (e) {} + response.writeHead(200, { + 'Content-Type': contentType + }); response.write(file, 'binary'); response.end(); }); - }); + } catch (e) { + pushLogs(config, 'Unexpected', e); + + response.writeHead(404, { + 'Content-Type': 'text/plain' + }); + response.write('404 Not Found: Unexpected error.\n' + e.message + '\n\n' + e.stack); + response.end(); + } } -var config = { - "socketURL": "/", - "dirPath": "", - "homePage": "/", - "socketMessageEvent": "RTCMultiConnection-Message", - "socketCustomEvent": "RTCMultiConnection-Custom-Message", - "port": 9001, - "enableLogs": false, - "isUseHTTPs": false, - "enableAdmin": false -}; +var httpApp; + +if (isUseHTTPs) { + httpServer = require('https'); + + // See how to use a valid certificate: + // https://github.com/muaz-khan/WebRTC-Experiment/issues/62 + var options = { + key: null, + cert: null, + ca: null + }; + + var pfx = false; + + if (!fs.existsSync(config.sslKey)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslKey:\t ' + config.sslKey + ' does not exist.'); + } else { + pfx = config.sslKey.indexOf('.pfx') !== -1; + options.key = fs.readFileSync(config.sslKey); + } + + if (!fs.existsSync(config.sslCert)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCert:\t ' + config.sslCert + ' does not exist.'); + } else { + options.cert = fs.readFileSync(config.sslCert); + } + + if (config.sslCabundle) { + if (!fs.existsSync(config.sslCabundle)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCabundle:\t ' + config.sslCabundle + ' does not exist.'); + } -var RTCMultiConnectionServer = require('rtcmulticonnection-server'); -var ioServer = require('socket.io'); + options.ca = fs.readFileSync(config.sslCabundle); + } + + if (pfx === true) { + options = { + pfx: sslKey + }; + } + + httpApp = httpServer.createServer(options, serverHandler); +} else { + httpApp = httpServer.createServer(serverHandler); +} -var app = server.createServer(serverHandler); -RTCMultiConnectionServer.beforeHttpListen(app, config); -app = app.listen(process.env.PORT || 9001, process.env.IP || "0.0.0.0", function() { - RTCMultiConnectionServer.afterHttpListen(app, config); +RTCMultiConnectionServer.beforeHttpListen(httpApp, config); +httpApp = httpApp.listen(process.env.PORT || PORT, process.env.IP || "0.0.0.0", function() { + RTCMultiConnectionServer.afterHttpListen(httpApp, config); }); // -------------------------- // socket.io codes goes below -ioServer(app).on('connection', function(socket) { +ioServer(httpApp).on('connection', function(socket) { RTCMultiConnectionServer.addSocket(socket, config); // ----------------------