diff --git a/labs/kurento-html5-video/.gitignore b/labs/kurento-html5-video/.gitignore deleted file mode 100644 index 40b878db5b1c97fc77049537a71bb2e249abe5dc..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ \ No newline at end of file diff --git a/labs/kurento-html5-video/README.md b/labs/kurento-html5-video/README.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/labs/kurento-html5-video/config/default.yml b/labs/kurento-html5-video/config/default.yml deleted file mode 100644 index 7ffd7d61cbe2b71d730d578f712e4937b265b0ce..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/config/default.yml +++ /dev/null @@ -1,2 +0,0 @@ -kurentoUrl: "wss://HOST/kurento" -acceptSelfSignedCertificate: false diff --git a/labs/kurento-html5-video/keys/README.md b/labs/kurento-html5-video/keys/README.md deleted file mode 100644 index 5bc681a1c8d2ece88651b6ee63d410536eae50f6..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/keys/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This folder contains a dummy self-signed certificate only for demo purposses, -**DON'T USE IT IN PRODUCTION**. diff --git a/labs/kurento-html5-video/keys/server.crt b/labs/kurento-html5-video/keys/server.crt deleted file mode 100644 index 65e608dad5d9fb19f68ac486e6189dfc67dcd2ff..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/keys/server.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBjCCAe4CCQCuf5QfyX2oDDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMB4XDTE0MDkyOTA5NDczNVoXDTE1MDkyOTA5NDczNVowRTELMAkG -A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 -IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AMJOyOHJ+rJWJEQ7P7kKoWa31ff7hKNZxF6sYE5lFi3pBYWIY6kTN/iUaxJLROFo -FhoC/M/STY76rIryix474v/6cRoG8N+GQBEn4IAP1UitWzVO6pVvBaIt5IKlhhfm -YA1IMweCd03vLcaHTddNmFDBTks7QDwfenTaR5VjKYc3OtEhcG8dgLAnOjbbk2Hr -8wter2IeNgkhya3zyoXnTLT8m8IMg2mQaJs62Xlo9gs56urvVDWG4rhdGybj1uwU -ZiDYyP4CFCUHS6UVt12vADP8vjbwmss2ScGsIf0NjaU+MpSdEbB82z4b2NiN8Wq+ -rFA/JbvyeoWWHMoa7wkVs1MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYLRwV9fo -AOhJfeK199Tv6oXoNSSSe10pVLnYxPcczCVQ4b9SomKFJFbmwtPVGi6w3m+8mV7F -9I2WKyeBHzmzfW2utZNupVybxgzEjuFLOVytSPdsB+DcJomOi8W/Cf2Vk8Wykb/t -Ctr1gfOcI8rwEGKxm279spBs0u1snzoLyoimbMbiXbC82j1IiN3Jus08U07m/j7N -hRBCpeHjUHT3CRpvYyTRnt+AyBd8BiyJB7nWmcNI1DksXPfehd62MAFS9e1ZE+dH -Aavg/U8VpS7pcCQcPJvIJ2hehrt8L6kUk3YUYqZ0OeRZK27f2R5+wFlDF33esm3N -dCSsLJlXyqAQFg== ------END CERTIFICATE----- diff --git a/labs/kurento-html5-video/keys/server.csr b/labs/kurento-html5-video/keys/server.csr deleted file mode 100644 index 6615b130471ce23cf8d980df5a308694ed06695b..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/keys/server.csr +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx -ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAMJOyOHJ+rJWJEQ7P7kKoWa31ff7hKNZxF6sYE5l -Fi3pBYWIY6kTN/iUaxJLROFoFhoC/M/STY76rIryix474v/6cRoG8N+GQBEn4IAP -1UitWzVO6pVvBaIt5IKlhhfmYA1IMweCd03vLcaHTddNmFDBTks7QDwfenTaR5Vj -KYc3OtEhcG8dgLAnOjbbk2Hr8wter2IeNgkhya3zyoXnTLT8m8IMg2mQaJs62Xlo -9gs56urvVDWG4rhdGybj1uwUZiDYyP4CFCUHS6UVt12vADP8vjbwmss2ScGsIf0N -jaU+MpSdEbB82z4b2NiN8Wq+rFA/JbvyeoWWHMoa7wkVs1MCAwEAAaAAMA0GCSqG -SIb3DQEBCwUAA4IBAQBMszYHMpklgTF/3h1zAzKXUD9NrtZp8eWhL06nwVjQX8Ai -EaCUiW0ypstokWcH9+30chd2OD++67NbxYUEucH8HrKpOoy6gs5L/mqgQ9Npz3OT -TB1HI4kGtpVuUQ5D7L0596tKzMX/CgW/hRcHWl+PDkwGhQs1qZcJ8QN+YP6AkRrO -5sDdDB/BLrB9PtBQbPrYIQcHQ7ooYWz/G+goqRxzZ6rt0aU2uAB6l7c82ADLAqFJ -qlw+xqVzEETVfqM5TXKK/wV3hgm4oSX5Q4SHLKF94ODOkWcnV4nfIKz7y+5XcQ3p -PrGimI1br07okC5rO9cgLCR0Ks20PPFcM0FvInW/ ------END CERTIFICATE REQUEST----- diff --git a/labs/kurento-html5-video/keys/server.key b/labs/kurento-html5-video/keys/server.key deleted file mode 100644 index a69a0a279daf6a68b9eff057204cd05af1b27a5a..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/keys/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAwk7I4cn6slYkRDs/uQqhZrfV9/uEo1nEXqxgTmUWLekFhYhj -qRM3+JRrEktE4WgWGgL8z9JNjvqsivKLHjvi//pxGgbw34ZAESfggA/VSK1bNU7q -lW8Foi3kgqWGF+ZgDUgzB4J3Te8txodN102YUMFOSztAPB96dNpHlWMphzc60SFw -bx2AsCc6NtuTYevzC16vYh42CSHJrfPKhedMtPybwgyDaZBomzrZeWj2Cznq6u9U -NYbiuF0bJuPW7BRmINjI/gIUJQdLpRW3Xa8AM/y+NvCayzZJwawh/Q2NpT4ylJ0R -sHzbPhvY2I3xar6sUD8lu/J6hZYcyhrvCRWzUwIDAQABAoIBACwt56TW3MZxqZtN -8WYsUZheUispJ/ZQMcLo5JjOiSV1Jwk+gpJtyTse291z+bxagzP02/CQu4u32UVa -cmE0cp+LHO4zB8964dREwdm8P91fdS6Au/uwG5LNZniCFCQZAFvkv52Ef4XbzQen -uf4rKWerHBck6K0C5z/sZXxE6KtScE2ZLUmkhO0nkHM6MA6gFk2OMnB+oDTOWWPt -1mlreQlzuMYG/D4axviRYrOSYCE5Qu1SOw/DEOLQqqeBjQrKtAyOlFHZsIR6lBfe -KHMChPUcYIwaowt2DcqH/A+AFXRtaifa6DvH8Yul+2vAp47UEpaenVfM5bpN33XV -EzerjtECgYEA+xiXzblek67iQgRpc9eHSoqs4iRLhae8s8kpAG51Jz46Je+Dmium -XV769oiUGUxBeoUb7ryW+4MOzHJaA1BfGejQSvwLIB9e4cnikqnAArcqbcAcOCL1 -aYYDiSmSmN/AokNZlPKEBFXP9bzXrU9smQJWNTHlcRl7JXfnwF+jwNsCgYEAxhpE -SBr9vlUVHNh/S6C5i80NIYg6jCy2FgsmuzEqmcqV0pTyzegmq8bru+QmuvoUj2o4 -nVv4J9d1fLF6ECUVk9aK8UdJOOB6hAfurOdJCArgrsY/9t4uDzXfbPCdfSNQITE0 -XgeNGQX1EzvwwkBmyZKk0kLIr3syP8ZCWfXDROkCgYBR+dF1pJMv++R6UR5sZ20P -9P5ERj0xwXVl7MKqFWXCDhrFz9BTQPTrftrIKgbPy4mFCnf4FTHlov/t11dzxYWG -2+9Ey8yGDDfZ1yNVZn39ZPdBJXsRCLi+XrZAzYXCyyoEz6ArdJGNKMbgH2r6dfeq -bIzgiQ2zQvJlZSQQNiksCQKBgCgwzAmU8EXdHRttEOZXBU3HnBJhgP9PUuHGAWWY -4/uvjhXbAiekIbRX9xt3fiQQ+HrgIfxK3F246K0TlKAR5f7IWAf7Xm+bmz+OHG4X -vklTa6IJtpBvIwkS9PE1H75zm54gTW+GOKoK+12bm4zNZA0hIy9FPVHcvKUTpAJ8 -SdGBAoGAHLtJnB1NO4EgO6WtLQMXt7HrIbup8eZi8/82gC3422C+ooKIrYQ07qSw -nBOO/G0OB4yd6vCE2x5+TWSSCYGgG5A8aIv5qP76RP4hovGHxG/y2tfotw5UuOrh -nFWlTP4Urs8PeykvK9ao8r/T8BnPIC16U6ENYvAc0mRlFA2j1GA= ------END RSA PRIVATE KEY----- diff --git a/labs/kurento-html5-video/lib/video.js b/labs/kurento-html5-video/lib/video.js deleted file mode 100644 index 19ed8a0b4832f0a9b699bf8e8d3b631d0416390c..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/lib/video.js +++ /dev/null @@ -1,253 +0,0 @@ -// Global stuff -var mediaPipelines = {}; -var sharedWebcams = {}; - -// TODO Later -// var loadBalancer = require('') -const kurento = require('kurento-client'); -const config = require('config'); -const kurentoUrl = config.get('kurentoUrl'); -const EventEmitter = require('events').EventEmitter; -const inherits = require('util').inherits; - -if (config.get('acceptSelfSignedCertificate')) { - process.env.NODE_TLS_REJECT_UNAUTHORIZED=0; -} - -var kurentoClient = null; - -function getKurentoClient(callback) { - - if (kurentoClient !== null) { - return callback(null, kurentoClient); - } - - kurento(kurentoUrl, function(error, _kurentoClient) { - if (error) { - console.log("Could not find media server at address " + kurentoUrl); - return callback("Could not find media server at address" + kurentoUrl + ". Exiting with error " + error); - } - - console.log(" [server] Initiating kurento client. Connecting to: " + kurentoUrl); - - kurentoClient = _kurentoClient; - callback(null, kurentoClient); - }); -} - -function getMediaPipeline(id, callback) { - - console.log(' [media] Creating media pipeline for ' + id); - - if (mediaPipelines[id]) { - - console.log(' [media] Pipeline already exists.'); - - callback(null, mediaPipelines[id]); - - } else { - - kurentoClient.create('MediaPipeline', function(err, pipeline) { - - mediaPipelines[id] = pipeline; - - return callback(err, pipeline); - }); - - } - -} - -function Video(_ws, _id, _shared) { - - var ws = _ws; - var id = _id; - var shared = _shared; - var webRtcEndpoint = null; - var notFlowingTimeout = null; - var notFlowingTimer = 15000; - EventEmitter.call(this); - - var candidatesQueue = []; - - this.onIceCandidate = function(_candidate) { - var candidate = kurento.getComplexType('IceCandidate')(_candidate); - - if (webRtcEndpoint) { - webRtcEndpoint.addIceCandidate(candidate); - } - else { - candidatesQueue.push(candidate); - } - }; - - this.start = function(sdpOffer, callback) { - var self = this; - - getKurentoClient(function(error, kurentoClient) { - - if (error) { - return callback(error); - } - - getMediaPipeline(id, function(error, pipeline) { - - if (error) { - return callback(error); - } - - createMediaElements(pipeline, function(error, _webRtcEndpoint) { - - if (error) { - pipeline.release(); - return callback(error); - } - - while(candidatesQueue.length) { - var candidate = candidatesQueue.shift(); - _webRtcEndpoint.addIceCandidate(candidate); - } - - var flowInOut = function(event) { - console.log(' [=] ' + event.type + ' for endpoint ' + id); - - if (event.state === 'NOT_FLOWING' && event.type === 'MediaFlowInStateChange') { - console.log(" [-] Media not flowing "); - notFlowingTimeout = setTimeout(function() { - console.log(" Timeout! sending playStop for id " + id); - ws.sendMessage({ id : 'playStop', cameraId : id }); - }, notFlowingTimer); - } else if (event.state === 'FLOWING' && event.type === 'MediaFlowInStateChange') { - - console.log(" [o] Media flowing "); - self.emit("READY"); - if (notFlowingTimeout) { - clearTimeout(notFlowingTimeout); - notFlowingTimeout = null; - } else{ - ws.sendMessage({ id : 'playStart', cameraId : id }); - } - } - }; - - _webRtcEndpoint.on('MediaFlowInStateChange', flowInOut); - _webRtcEndpoint.on('MediaFlowOutStateChange', flowInOut); - - _webRtcEndpoint.on('MediaStateChanged', (e) => { self.emit("READY"); console.log(id); console.log(e)} ); - - connectMediaElements(_webRtcEndpoint, function(error) { - - if (error) { - pipeline.release(); - return callback(error); - } - - // It's a user sharing a webcam - if (shared) { - sharedWebcams[id] = _webRtcEndpoint; - } - - // Store our endpoint - webRtcEndpoint = _webRtcEndpoint; - - _webRtcEndpoint.on('OnIceCandidate', function(event) { - var candidate = kurento.getComplexType('IceCandidate')(event.candidate); - ws.sendMessage({ id : 'iceCandidate', cameraId: id, candidate : candidate }); - }); - - _webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) { - if (error) { - pipeline.release(); - return callback(error); - } - - return callback(null, sdpAnswer); - }); - - _webRtcEndpoint.gatherCandidates(function(error) { - if (error) { - return callback(error); - } - }); - }); - }); - }); - }); - }; - - var createMediaElements = function(pipeline, callback) { - - console.log(" [webrtc] Creating webrtc endpoint"); - - pipeline.create('WebRtcEndpoint', function(error, _webRtcEndpoint) { - - if (error) { - return callback(error); - } - - webRtcEndpoint = _webRtcEndpoint; - console.log(" [webrtc] Created webRtcEndpoint => " + webRtcEndpoint.id); - - return callback(null, _webRtcEndpoint); - }); - }; - - var connectMediaElements = function(webRtcEndpoint, callback) { - - // User is sharing webcam (sendOnly connection from the client) - if (shared) { - console.log(" [webrtc] User has shared the webcam, no connection needed"); - // Dont connect this, just create the webrtcEndpoint - // webRtcEndpoint.connect(webRtcEndpoint, callback); - - return callback(null); - } else { - - console.log(" [webrtc] User wants to receive webcam "); - - if (sharedWebcams[id]) { - var wRtc = sharedWebcams[id]; - wRtc.connect(webRtcEndpoint, function(error) { - console.log(" [webrtc] Connected " + wRtc.id + " => " + webRtcEndpoint.id); - if (error) { - return callback(error); - } - return callback(null); - }); - } - } - }; - - this.stop = function() { - - console.log(' [stop] Releasing webrtc endpoint for ' + id); - - if (webRtcEndpoint) { - webRtcEndpoint.release(); - webRtcEndpoint = null; - } else { - console.log(" [webRtcEndpoint] PLEASE DONT TRY STOPPING THINGS TWICE"); - } - - if (shared) { - console.log(' [stop] Webcam is shared, releasing ' + id); - - if (mediaPipelines[id]) { - console.log( '[stop] Releasing pipeline ' + id); - mediaPipelines[id].release(); - } else { - console.log(" [mediaPipeline] PLEASE DONT TRY STOPPING THINGS TWICE"); - } - - delete mediaPipelines[id]; - delete sharedWebcams[id]; - } - - delete candidatesQueue; - }; - - return this; -}; -inherits(Video, EventEmitter); - -module.exports = Video; diff --git a/labs/kurento-html5-video/lib/websocket.js b/labs/kurento-html5-video/lib/websocket.js deleted file mode 100644 index c4fe9f6f18b220e8b4c43be58ec75004a6430124..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/lib/websocket.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Simple wrapper around the ws library - * - */ - -var ws = require('ws'); - -ws.prototype.sendMessage = function(json) { - - return this.send(JSON.stringify(json), function(error) { - if(error) - console.log(' [server] Websocket error "' + error + '" on message "' + json.id + '"'); - }); - -}; - - -module.exports = ws; \ No newline at end of file diff --git a/labs/kurento-html5-video/package.json b/labs/kurento-html5-video/package.json deleted file mode 100644 index f94ec57e1dce754e04ac195148f03216f97b6e5a..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "bbb-html5-video-kurento-bridge", - "version": "1.0.0", - "private": true, - "scripts": { - "start": "nodejs server.js", - "postinstall": "npm start" - }, - "dependencies": { - "cookie-parser": "^1.3.5", - "express": "~4.12.4", - "express-session": "~1.10.3", - "ws": "~1.0.1", - "kurento-client": "6.6.0" - }, - "devDependencies": { - "config": "^1.26.1", - "js-yaml": "^3.8.3" - } -} diff --git a/labs/kurento-html5-video/server.js b/labs/kurento-html5-video/server.js deleted file mode 100755 index 07adef8bdcd8841a600a29305a3a6c01ddfaf583..0000000000000000000000000000000000000000 --- a/labs/kurento-html5-video/server.js +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Lucas Fialho Zawacki - * (C) Copyright 2017 Bigbluebutton - * - */ - -'use strict'; - -var cookieParser = require('cookie-parser') -var express = require('express'); -var session = require('express-session') -var ws = require('./lib/websocket'); -var http = require('http'); -var fs = require('fs'); - -var Video = require('./lib/video'); - -// Global variables -var app = express(); -var sessions = {}; - -/* - * Management of sessions - */ -app.use(cookieParser()); - -var sessionHandler = session({ - secret : 'Shawarma', rolling : true, resave : true, saveUninitialized : true -}); - -app.use(sessionHandler); - -/* - * Server startup - */ -var server = http.createServer(app).listen(3002, function() { - console.log(' [*] Running bbb-html5 kurento video service.'); -}); - -var wss = new ws.Server({ - server : server, - path : '/html5video' -}); - -var clientId = 0; - -wss.on('connection', function(ws) { - var sessionId; - var request = ws.upgradeReq; - var response = { - writeHead : {} - }; - - sessionHandler(request, response, function(err) { - sessionId = request.session.id + "_" + clientId++; - - if (!sessions[sessionId]) { - sessions[sessionId] = {videos: {}, iceQueue: {}}; - } - - console.log('Connection received with sessionId ' + sessionId); - }); - - ws.on('error', function(error) { - console.log('Connection ' + sessionId + ' error'); - // stop(sessionId); - }); - - ws.on('close', function() { - console.log('Connection ' + sessionId + ' closed'); - stopSession(sessionId); - }); - - ws.on('message', function(_message) { - var message = JSON.parse(_message); - - var video; - if (message.cameraId && sessions[sessionId].videos[message.cameraId]) { - video = sessions[sessionId].videos[message.cameraId]; - } - - switch (message.id) { - - case 'start': - - console.log('[' + message.id + '] connection ' + sessionId); - if (video) { - video.once('READY', function() { - console.log("Video is ready"); - startVideo(message, ws, sessionId); - }); - } - else { - startVideo(message, ws, sessionId); - } - break; - - case 'stop': - - console.log('[' + message.id + '] connection ' + sessionId); - - if (video) { - video.stop(sessionId); - delete sessions[sessionId].videos[message.cameraId]; - } else { - console.log(" [stop] Why is there no video on STOP?"); - } - break; - - case 'onIceCandidate': - onIceCandidate(sessionId, message.cameraId, message.candidate); - break; - - default: - ws.sendMessage({ id : 'error', message : 'Invalid message ' + message }); - break; - } - - }); -}); - -var stopSession = function(sessionId) { - - if(typeof sessions[sessionId] === 'undefined') { - console.log(' [>] Session ' + sessionId + ' was already terminated'); - return; - } - console.log(' [>] Stopping session ' + sessionId); - - var videoIds = Object.keys(sessions[sessionId].videos); - - for (var i = 0; i < videoIds.length; i++) { - var video = sessions[sessionId].videos[videoIds[i]]; - if (video){ - console.log(video); - console.log(videoIds[i]); - video.stop(); - } else { - console.log("Stop session but video was null"); - } - - delete sessions[sessionId].videos[videoIds[i]]; - } - - delete sessions[sessionId]; -} - -var stopAll = function() { - - console.log('\n [x] Stopping everything! '); - - var sessionIds = Object.keys(sessions); - - for (var i = 0; i < sessionIds.length; i++) { - - stopSession(sessionIds[i]); - } - - setTimeout(process.exit, 1000); -} - -function onIceCandidate(sessionId, id, candidate) { - if (sessions[sessionId][id]) { - sessions[sessionId][id].onIceCandidate(candidate); - } else { - sessions[sessionId].iceQueue = sessions[sessionId].iceQueue || {}; - sessions[sessionId].iceQueue[id] = sessions[sessionId].iceQueue[id] || []; - sessions[sessionId].iceQueue[id].push(candidate); - } -} - -function startVideo(message, ws, sessionId) { - console.log('[' + message.id + '] connection ' + sessionId); - let video = new Video(ws, message.cameraId, message.cameraShared); - sessions[sessionId].videos[message.cameraId] = video; - - video.start(message.sdpOffer, function(error, sdpAnswer) { - if (error) { - return ws.sendMessage({id : 'error', message : error }); - } - - // Get ice candidates that arrived before video was created - if (sessions[sessionId].iceQueue) { - var queue = sessions[sessionId].iceQueue[message.cameraId]; - while (queue && queue.length > 0) { - video.onIceCandidate(queue.pop()); - } - } - ws.sendMessage({id : 'startResponse', cameraId: message.cameraId, sdpAnswer : sdpAnswer}); - }); -} - -process.on('SIGTERM', stopAll); -process.on('SIGINT', stopAll); diff --git a/labs/kurento-screenshare/.gitignore b/labs/kurento-screenshare/.gitignore deleted file mode 100644 index 40b878db5b1c97fc77049537a71bb2e249abe5dc..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ \ No newline at end of file diff --git a/labs/kurento-screenshare/README.md b/labs/kurento-screenshare/README.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/labs/kurento-screenshare/config/default.yml b/labs/kurento-screenshare/config/default.yml deleted file mode 100644 index 46b6e2629ecf6e34603f5a34c1288266d0583918..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/config/default.yml +++ /dev/null @@ -1,8 +0,0 @@ -kurentoUrl: "KURENTOURL" -kurentoIp: "KURENTOIP" -localIpAddress: "HOST" -acceptSelfSignedCertificate: false -redisHost : "127.0.0.1" -redisPort : "6379" -minVideoPort: 30000 -maxVideoPort: 33000 diff --git a/labs/kurento-screenshare/debug-start.sh b/labs/kurento-screenshare/debug-start.sh deleted file mode 100644 index b7c6990b40943deef6c8529bfec832f0d929927b..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/debug-start.sh +++ /dev/null @@ -1 +0,0 @@ -node --inspect --debug-brk server.js diff --git a/labs/kurento-screenshare/keys/README.md b/labs/kurento-screenshare/keys/README.md deleted file mode 100644 index 5bc681a1c8d2ece88651b6ee63d410536eae50f6..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/keys/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This folder contains a dummy self-signed certificate only for demo purposses, -**DON'T USE IT IN PRODUCTION**. diff --git a/labs/kurento-screenshare/keys/server.crt b/labs/kurento-screenshare/keys/server.crt deleted file mode 100644 index 65e608dad5d9fb19f68ac486e6189dfc67dcd2ff..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/keys/server.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBjCCAe4CCQCuf5QfyX2oDDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMB4XDTE0MDkyOTA5NDczNVoXDTE1MDkyOTA5NDczNVowRTELMAkG -A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 -IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AMJOyOHJ+rJWJEQ7P7kKoWa31ff7hKNZxF6sYE5lFi3pBYWIY6kTN/iUaxJLROFo -FhoC/M/STY76rIryix474v/6cRoG8N+GQBEn4IAP1UitWzVO6pVvBaIt5IKlhhfm -YA1IMweCd03vLcaHTddNmFDBTks7QDwfenTaR5VjKYc3OtEhcG8dgLAnOjbbk2Hr -8wter2IeNgkhya3zyoXnTLT8m8IMg2mQaJs62Xlo9gs56urvVDWG4rhdGybj1uwU -ZiDYyP4CFCUHS6UVt12vADP8vjbwmss2ScGsIf0NjaU+MpSdEbB82z4b2NiN8Wq+ -rFA/JbvyeoWWHMoa7wkVs1MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYLRwV9fo -AOhJfeK199Tv6oXoNSSSe10pVLnYxPcczCVQ4b9SomKFJFbmwtPVGi6w3m+8mV7F -9I2WKyeBHzmzfW2utZNupVybxgzEjuFLOVytSPdsB+DcJomOi8W/Cf2Vk8Wykb/t -Ctr1gfOcI8rwEGKxm279spBs0u1snzoLyoimbMbiXbC82j1IiN3Jus08U07m/j7N -hRBCpeHjUHT3CRpvYyTRnt+AyBd8BiyJB7nWmcNI1DksXPfehd62MAFS9e1ZE+dH -Aavg/U8VpS7pcCQcPJvIJ2hehrt8L6kUk3YUYqZ0OeRZK27f2R5+wFlDF33esm3N -dCSsLJlXyqAQFg== ------END CERTIFICATE----- diff --git a/labs/kurento-screenshare/keys/server.csr b/labs/kurento-screenshare/keys/server.csr deleted file mode 100644 index 6615b130471ce23cf8d980df5a308694ed06695b..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/keys/server.csr +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx -ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAMJOyOHJ+rJWJEQ7P7kKoWa31ff7hKNZxF6sYE5l -Fi3pBYWIY6kTN/iUaxJLROFoFhoC/M/STY76rIryix474v/6cRoG8N+GQBEn4IAP -1UitWzVO6pVvBaIt5IKlhhfmYA1IMweCd03vLcaHTddNmFDBTks7QDwfenTaR5Vj -KYc3OtEhcG8dgLAnOjbbk2Hr8wter2IeNgkhya3zyoXnTLT8m8IMg2mQaJs62Xlo -9gs56urvVDWG4rhdGybj1uwUZiDYyP4CFCUHS6UVt12vADP8vjbwmss2ScGsIf0N -jaU+MpSdEbB82z4b2NiN8Wq+rFA/JbvyeoWWHMoa7wkVs1MCAwEAAaAAMA0GCSqG -SIb3DQEBCwUAA4IBAQBMszYHMpklgTF/3h1zAzKXUD9NrtZp8eWhL06nwVjQX8Ai -EaCUiW0ypstokWcH9+30chd2OD++67NbxYUEucH8HrKpOoy6gs5L/mqgQ9Npz3OT -TB1HI4kGtpVuUQ5D7L0596tKzMX/CgW/hRcHWl+PDkwGhQs1qZcJ8QN+YP6AkRrO -5sDdDB/BLrB9PtBQbPrYIQcHQ7ooYWz/G+goqRxzZ6rt0aU2uAB6l7c82ADLAqFJ -qlw+xqVzEETVfqM5TXKK/wV3hgm4oSX5Q4SHLKF94ODOkWcnV4nfIKz7y+5XcQ3p -PrGimI1br07okC5rO9cgLCR0Ks20PPFcM0FvInW/ ------END CERTIFICATE REQUEST----- diff --git a/labs/kurento-screenshare/keys/server.key b/labs/kurento-screenshare/keys/server.key deleted file mode 100644 index a69a0a279daf6a68b9eff057204cd05af1b27a5a..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/keys/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAwk7I4cn6slYkRDs/uQqhZrfV9/uEo1nEXqxgTmUWLekFhYhj -qRM3+JRrEktE4WgWGgL8z9JNjvqsivKLHjvi//pxGgbw34ZAESfggA/VSK1bNU7q -lW8Foi3kgqWGF+ZgDUgzB4J3Te8txodN102YUMFOSztAPB96dNpHlWMphzc60SFw -bx2AsCc6NtuTYevzC16vYh42CSHJrfPKhedMtPybwgyDaZBomzrZeWj2Cznq6u9U -NYbiuF0bJuPW7BRmINjI/gIUJQdLpRW3Xa8AM/y+NvCayzZJwawh/Q2NpT4ylJ0R -sHzbPhvY2I3xar6sUD8lu/J6hZYcyhrvCRWzUwIDAQABAoIBACwt56TW3MZxqZtN -8WYsUZheUispJ/ZQMcLo5JjOiSV1Jwk+gpJtyTse291z+bxagzP02/CQu4u32UVa -cmE0cp+LHO4zB8964dREwdm8P91fdS6Au/uwG5LNZniCFCQZAFvkv52Ef4XbzQen -uf4rKWerHBck6K0C5z/sZXxE6KtScE2ZLUmkhO0nkHM6MA6gFk2OMnB+oDTOWWPt -1mlreQlzuMYG/D4axviRYrOSYCE5Qu1SOw/DEOLQqqeBjQrKtAyOlFHZsIR6lBfe -KHMChPUcYIwaowt2DcqH/A+AFXRtaifa6DvH8Yul+2vAp47UEpaenVfM5bpN33XV -EzerjtECgYEA+xiXzblek67iQgRpc9eHSoqs4iRLhae8s8kpAG51Jz46Je+Dmium -XV769oiUGUxBeoUb7ryW+4MOzHJaA1BfGejQSvwLIB9e4cnikqnAArcqbcAcOCL1 -aYYDiSmSmN/AokNZlPKEBFXP9bzXrU9smQJWNTHlcRl7JXfnwF+jwNsCgYEAxhpE -SBr9vlUVHNh/S6C5i80NIYg6jCy2FgsmuzEqmcqV0pTyzegmq8bru+QmuvoUj2o4 -nVv4J9d1fLF6ECUVk9aK8UdJOOB6hAfurOdJCArgrsY/9t4uDzXfbPCdfSNQITE0 -XgeNGQX1EzvwwkBmyZKk0kLIr3syP8ZCWfXDROkCgYBR+dF1pJMv++R6UR5sZ20P -9P5ERj0xwXVl7MKqFWXCDhrFz9BTQPTrftrIKgbPy4mFCnf4FTHlov/t11dzxYWG -2+9Ey8yGDDfZ1yNVZn39ZPdBJXsRCLi+XrZAzYXCyyoEz6ArdJGNKMbgH2r6dfeq -bIzgiQ2zQvJlZSQQNiksCQKBgCgwzAmU8EXdHRttEOZXBU3HnBJhgP9PUuHGAWWY -4/uvjhXbAiekIbRX9xt3fiQQ+HrgIfxK3F246K0TlKAR5f7IWAf7Xm+bmz+OHG4X -vklTa6IJtpBvIwkS9PE1H75zm54gTW+GOKoK+12bm4zNZA0hIy9FPVHcvKUTpAJ8 -SdGBAoGAHLtJnB1NO4EgO6WtLQMXt7HrIbup8eZi8/82gC3422C+ooKIrYQ07qSw -nBOO/G0OB4yd6vCE2x5+TWSSCYGgG5A8aIv5qP76RP4hovGHxG/y2tfotw5UuOrh -nFWlTP4Urs8PeykvK9ao8r/T8BnPIC16U6ENYvAc0mRlFA2j1GA= ------END RSA PRIVATE KEY----- diff --git a/labs/kurento-screenshare/lib/ConnectionManager.js b/labs/kurento-screenshare/lib/ConnectionManager.js deleted file mode 100644 index 447fa254ef3ca5e322b358e81f029d878fa63561..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/ConnectionManager.js +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Lucas Fialho Zawacki - * Paulo Renato Lanzarin - * (C) Copyright 2017 Bigbluebutton - * - */ - -'use strict' - -const cookieParser = require('cookie-parser') -const express = require('express'); -const session = require('express-session') -const wsModule = require('./websocket'); -const http = require('http'); -const fs = require('fs'); -const BigBlueButtonGW = require('./bbb/pubsub/bbb-gw'); -const MediaController = require('./media-controller'); -var Screenshare = require('./screenshare'); -var C = require('./bbb/messages/Constants'); - -// Global variables - -module.exports = class ConnectionManager { - - constructor (settings, logger) { - this._logger = logger; - this._clientId = 0; - this._app = express(); - - this._sessions = {}; - this._screenshareSessions = {}; - - this._setupExpressSession(); - this._setupHttpServer(); - } - - _setupExpressSession() { - this._app.use(cookieParser()); - - this._sessionHandler = session({ - secret : 'Shawarma', rolling : true, resave : true, saveUninitialized : true - }); - - this._app.use(this._sessionHandler); - } - - _setupHttpServer() { - let self = this; - /* - * Server startup - */ - this._httpServer = http.createServer(this._app).listen(3008, function() { - console.log(' [*] Running node-apps connection manager.'); - }); - - /* - * Management of sessions - */ - this._wss = new wsModule.Server({ - server : this._httpServer, - path : '/kurento-screenshare' - }); - - - // TODO isolate this - this._bbbGW = new BigBlueButtonGW(); - - this._bbbGW.addSubscribeChannel(C.FROM_BBB_TRANSCODE_SYSTEM_CHAN, function(error, redisWrapper) { - if(error) { - console.log(' Could not connect to transcoder redis channel, finishing app...'); - self._stopAll(); - } - console.log(' [server] Successfully subscribed to redis channel'); - }); - - - this._wss.on('connection', self._onNewConnection.bind(self)); - } - - _onNewConnection(webSocket) { - let self = this; - let connectionId; - let request = webSocket.upgradeReq; - let sessionId; - let callerName; - let response = { - writeHead : {} - }; - - this._sessionHandler(request, response, function(err) { - connectionId = request.session.id + "_" + self._clientId++; - console.log('Connection received with connectionId ' + connectionId); - }); - - webSocket.on('error', function(error) { - console.log('Connection ' + connectionId + ' error'); - self._stopSession(sessionId); - }); - - webSocket.on('close', function() { - console.log('Connection ' + connectionId + ' closed'); - console.log(webSocket.presenter); - - if (webSocket.presenter && self._screenshareSessions[sessionId]) { // if presenter // FIXME (this conditional was added to prevent screenshare stop when an iOS user quits) - console.log(" [CM] Stopping presenter " + sessionId); - self._stopSession(sessionId); - } - if (webSocket.viewer && typeof webSocket.session !== 'undefined') { - console.log(" [CM] Stopping viewer " + webSocket.viewerId); - webSocket.session._stopViewer(webSocket.viewerId); - } - }); - - webSocket.on('message', function(_message) { - let message = JSON.parse(_message); - let session; - // The sessionId is voiceBridge for screensharing sessions - sessionId = message.voiceBridge; - if(self._screenshareSessions[sessionId]) { - session = self._screenshareSessions[sessionId]; - webSocket.session = session; - } - - switch (message.id) { - - case 'presenter': - - // Checking if there's already a Screenshare session started - // because we shouldn't overwrite it - webSocket.presenter = true; - - if (!self._screenshareSessions[message.voiceBridge]) { - self._screenshareSessions[message.voiceBridge] = {} - self._screenshareSessions[message.voiceBridge] = session; - } - - //session.on('message', self._assembleSessionMessage.bind(self)); - if(session) { - break; - } - - session = new Screenshare(webSocket, connectionId, self._bbbGW, - sessionId, message.callerName, message.vh, message.vw, - message.internalMeetingId); - - self._screenshareSessions[sessionId] = {} - self._screenshareSessions[sessionId] = session; - - // starts presenter by sending sessionID, websocket and sdpoffer - session._startPresenter(connectionId, webSocket, message.sdpOffer, function(error, sdpAnswer) { - console.log(" Started presenter " + connectionId); - if (error) { - return webSocket.send(JSON.stringify({ - id : 'presenterResponse', - response : 'rejected', - message : error - })); - } - - webSocket.send(JSON.stringify({ - id : 'presenterResponse', - response : 'accepted', - sdpAnswer : sdpAnswer - })); - console.log(" [websocket] Sending presenterResponse \n" + sdpAnswer); - }); - break; - - case 'viewer': - console.log("[viewer] Session output \n " + session); - - webSocket.viewer = true; - webSocket.viewerId = message.callerName; - - if (message.sdpOffer && message.voiceBridge) { - if (session) { - session._startViewer(webSocket, message.voiceBridge, message.sdpOffer, message.callerName, self._screenshareSessions[message.voiceBridge]._presenterEndpoint); - } else { - webSocket.sendMessage("voiceBridge not recognized"); - webSocket.sendMessage(Object.keys(self._screenshareSessions)); - webSocket.sendMessage(message.voiceBridge); - } - } - break; - - case 'stop': - console.log('[' + message.id + '] connection ' + connectionId); - - if (session) { - session._stop(sessionId); - } else { - console.log(" [stop] Why is there no session on STOP?"); - } - break; - - case 'onIceCandidate': - if (session) { - console.log(" [CM] What the fluff is happening"); - session._onIceCandidate(message.candidate); - } else { - console.log(" [iceCandidate] Why is there no session on ICE CANDIDATE?"); - } - break; - - case 'ping': - webSocket.send(JSON.stringify({ - id : 'pong', - response : 'accepted' - })); - break; - - - case 'viewerIceCandidate': - console.log("[viewerIceCandidate] Session output => " + session); - if (session) { - session._onViewerIceCandidate(message.candidate, message.callerName); - } else { - console.log("[iceCandidate] Why is there no session on ICE CANDIDATE?"); - } - break; - - default: - webSocket.sendMessage({ id : 'error', message : 'Invalid message ' + message }); - break; - } - }); - } - - _stopSession(sessionId) { - console.log(' [>] Stopping session ' + sessionId); - let session = this._screenshareSessions[sessionId]; - if(typeof session !== 'undefined' && typeof session._stop === 'function') { - session._stop(); - } - - delete this._screenshareSessions[sessionId]; - } - - _stopAll() { - console.log('\n [x] Stopping everything! '); - let sessionIds = Object.keys(this._screenshareSessions); - - for (let i = 0; i < sessionIds.length; i++) { - this._stopSession(sessionIds[i]); - } - - setTimeout(process.exit, 1000); - } -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/Constants.js b/labs/kurento-screenshare/lib/bbb/messages/Constants.js deleted file mode 100644 index 6cccf19f93cadf15684b9a09c2f2ddde37909dbd..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/Constants.js +++ /dev/null @@ -1,91 +0,0 @@ -"use strict"; -/** - * @classdesc - * Message constants for the communication with BigBlueButton - * @constructor - */ - function Constants () { - return { - // Media elements - WebRTC: "WebRtcEndpoint", - RTP: "RtpEndpoint", - AUDIO: "AUDIO", - VIDEO: "VIDEO", - ALL: "ALL", - - // Redis channels - FROM_BBB_TRANSCODE_SYSTEM_CHAN : "bigbluebutton:from-bbb-transcode:system", - FROM_VOICE_CONF_SYSTEM_CHAN: "from-voice-conf-redis-channel", - TO_BBB_TRANSCODE_SYSTEM_CHAN: "bigbluebutton:to-bbb-transcode:system", - - // RedisWrapper events - REDIS_MESSAGE : "redis_message", - - // Message identifiers 1x - START_TRANSCODER_REQUEST: "start_transcoder_request_message", - START_TRANSCODER_REPLY: "start_transcoder_reply_message", - STOP_TRANSCODER_REQUEST: "stop_transcoder_request_message", - STOP_TRANSCODER_REPLY: "stop_transcoder_reply_message", - DESKSHARE_RTMP_BROADCAST_STARTED: "deskshare_rtmp_broadcast_started_message", - DESKSHARE_RTMP_BROADCAST_STOPPED: "deskshare_rtmp_broadcast_stopped_message", - - //Message identifiers 2x - SCREENSHARE_RTMP_BROADCAST_STARTED_2x: "ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg", - SCREENSHARE_RTMP_BROADCAST_STOPPED_2x: "ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg", - START_TRANSCODER_REQ_2x: "StartTranscoderSysReqMsg", - START_TRANSCODER_RESP_2x: "StartTranscoderSysRespMsg", - STOP_TRANSCODER_REQ_2x: "StopTranscoderSysReqMsg", - STOP_TRANSCODER_RESP_2x: "StopTranscoderSysRespMsg", - - // Redis messages fields - // Transcoder 1x - USER_ID : "user_id", - OPTIONS: "options", - VOICE_CONF_ID : "voice_conf_id", - TRANSCODER_ID : "transcoder_id", - - // Transcoder 2x - USER_ID_2x : "userId", - TRANSCODER_ID_2x : "transcoderId", - MEETING_ID_2x: "meetingId", - - // Screenshare 2x - CONFERENCE_NAME: "voiceConf", - SCREENSHARE_CONF: "screenshareConf", - STREAM_URL: "stream", - TIMESTAMP: "timestamp", - VIDEO_WIDTH: "vidWidth", - VIDEO_HEIGHT: "vidHeight", - - // RTP params - MEETING_ID : "meeting_id", - VOICE_CONF : "voice_conf", - KURENTO_ENDPOINT_ID : "kurento_endpoint_id", - PARAMS : "params", - MEDIA_DESCRIPTION: "media_description", - LOCAL_IP_ADDRESS: "local_ip_address", - LOCAL_VIDEO_PORT: "local_video_port", - DESTINATION_IP_ADDRESS : "destination_ip_address", - DESTINATION_VIDEO_PORT : "destination_video_port", - REMOTE_VIDEO_PORT : "remote_video_port", - CODEC_NAME: "codec_name", - CODEC_ID: "codec_id", - CODEC_RATE: "codec_rate", - RTP_PROFILE: "rtp_profile", - SEND_RECEIVE: "send_receive", - FRAME_RATE: "frame_rate", - INPUT: "input", - KURENTO_TOKEN : "kurento_token", - SCREENSHARE: "deskShare", - STREAM_TYPE: "stream_type", - STREAM_TYPE_SCREENSHARE: "stream_type_deskshare", - STREAM_TYPE_VIDEO: "stream_type_video", - RTP_TO_RTMP: "transcode_rtp_to_rtmp", - TRANSCODER_CODEC: "codec", - TRANSCODER_TYPE: "transcoder_type", - CALLERNAME: "callername" - } -} - -module.exports = Constants(); - diff --git a/labs/kurento-screenshare/lib/bbb/messages/Messaging.js b/labs/kurento-screenshare/lib/bbb/messages/Messaging.js deleted file mode 100644 index 92bab79944122fb88e16bb7c30152da68a0f80b7..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/Messaging.js +++ /dev/null @@ -1,69 +0,0 @@ -var Constants = require('./Constants.js'); - -// Messages - -var OutMessage = require('./OutMessage.js'); - -var StartTranscoderRequestMessage = - require('./transcode/StartTranscoderRequestMessage.js')(Constants); -var StopTranscoderRequestMessage = - require('./transcode/StopTranscoderRequestMessage.js')(Constants); -var StartTranscoderSysReqMsg = - require('./transcode/StartTranscoderSysReqMsg.js')(); -var StopTranscoderSysReqMsg = - require('./transcode/StopTranscoderSysReqMsg.js')(); -var DeskShareRTMPBroadcastStartedEventMessage = - require('./screenshare/DeskShareRTMPBroadcastStartedEventMessage.js')(Constants); -var DeskShareRTMPBroadcastStoppedEventMessage = - require('./screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js')(Constants); -var ScreenshareRTMPBroadcastStartedEventMessage2x = - require('./screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js')(Constants); -var ScreenshareRTMPBroadcastStoppedEventMessage2x = - require('./screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js')(Constants); - - - /** - * @classdesc - * Messaging utils to assemble JSON/Redis BigBlueButton messages - * @constructor - */ -function Messaging() {} - -Messaging.prototype.generateStartTranscoderRequestMessage = - function(meetingId, transcoderId, params) { - var statrm = new StartTranscoderSysReqMsg(meetingId, transcoderId, params); - return statrm.toJson(); -} - -Messaging.prototype.generateStopTranscoderRequestMessage = - function(meetingId, transcoderId) { - var stotrm = new StopTranscoderSysReqMsg(meetingId, transcoderId); - return stotrm.toJson(); -} - -Messaging.prototype.generateDeskShareRTMPBroadcastStartedEvent = - function(conferenceName, streamUrl, vw, vh, timestamp) { - var stadrbem = new DeskShareRTMPBroadcastStartedEventMessage(conferenceName, streamUrl, vw, vh, timestamp); - return stadrbem.toJson(); -} - -Messaging.prototype.generateDeskShareRTMPBroadcastStoppedEvent = - function(conferenceName, streamUrl, vw, vh, timestamp) { - var stodrbem = new DeskShareRTMPBroadcastStoppedEventMessage(conferenceName, streamUrl, vw, vh, timestamp); - return stodrbem.toJson(); -} - -Messaging.prototype.generateScreenshareRTMPBroadcastStartedEvent2x = - function(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp) { - var stadrbem = new ScreenshareRTMPBroadcastStartedEventMessage2x(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp); - return stadrbem.toJson(); -} - -Messaging.prototype.generateScreenshareRTMPBroadcastStoppedEvent2x = - function(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp) { - var stodrbem = new ScreenshareRTMPBroadcastStoppedEventMessage2x(conferenceName, screenshareConf, streamUrl, vw, vh, timestamp); - return stodrbem.toJson(); -} - -module.exports = new Messaging(); -module.exports.Constants = Constants; diff --git a/labs/kurento-screenshare/lib/bbb/messages/OutMessage.js b/labs/kurento-screenshare/lib/bbb/messages/OutMessage.js deleted file mode 100644 index 04776dca76e6513f20259b2a47c339f2c175c5e3..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/OutMessage.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * (C) Copyright 2016 Mconf Tecnologia (http://mconf.com/) - */ - -/** - * @classdesc - * Base class for output messages sent to BBB - * @constructor - */ -function OutMessage(messageName) { - /** - * The header template of the message - * @type {Object} - */ - this.header = { - version: "0.0.1", - name: messageName - }; - - /** - * The payload of the message - * @type {Object} - */ - this.payload = null; - - /** - * Generates the JSON representation of the message - * @return {String} The JSON string of this message - */ - this.toJson = function () { - return JSON.stringify(this); - } -}; - -module.exports = OutMessage; diff --git a/labs/kurento-screenshare/lib/bbb/messages/OutMessage2x.js b/labs/kurento-screenshare/lib/bbb/messages/OutMessage2x.js deleted file mode 100644 index a6f9cafcfcd289d2ef95334743fb5c32f63bd8f6..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/OutMessage2x.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (C) Copyright 2016 Mconf Tecnologia (http://mconf.com/) - */ - -/** - * @classdesc - * Base class for output messages sent to BBB - * 2x model - * @constructor - */ -function OutMessage2x(messageName, routing, headerFields) { - - - this.envelope = { - name: messageName, - routing: routing - } - /** - * The header template of the message - * @type {Object} - */ - this.core = { - header : { - name: messageName - } - } - - // Copy header fiels to the header object - var keys1 = Object.keys(headerFields); - for (var k=0; k < keys1.length; k++) { - var key = keys1[k]; - if (typeof this.core.header[key] === 'undefined') { - this.core.header[key] = headerFields[key]; - } - } - - /** - * The body of the message - * @type {Object} - */ - this.core.body = null; - - /** - * Generates the JSON representation of the message - * @return {String} The JSON string of this message - */ - this.toJson = function () { - return JSON.stringify(this); - } -}; - -module.exports = OutMessage2x; diff --git a/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js b/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js deleted file mode 100644 index 34579de0bfa0854f7170d1e92efc7cb818b2cbee..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStartedEventMessage.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * - */ - -var inherits = require('inherits'); -var OutMessage = require('../OutMessage'); - -module.exports = function (Constants) { - function DeskShareRTMPBroadcastStartedEventMessage (conferenceName, streamUrl, vw, vh, timestamp) { - DeskShareRTMPBroadcastStartedEventMessage.super_.call(this, Constants.DESKSHARE_RTMP_BROADCAST_STARTED); - - this.payload = {}; - this.payload[Constants.CONFERENCE_NAME] = conferenceName; - this.payload[Constants.STREAM_URL] = streamUrl; - this.payload[Constants.TIMESTAMP] = timestamp; - this.payload[Constants.VIDEO_WIDTH] = vw; - this.payload[Constants.VIDEO_HEIGHT] = vh; - }; - - inherits(DeskShareRTMPBroadcastStartedEventMessage, OutMessage); - return DeskShareRTMPBroadcastStartedEventMessage; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js b/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js deleted file mode 100644 index 81e7125db7f9d7b61580f4dad93076387b6c8426..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/screenshare/DeskShareRTMPBroadcastStoppedEventMessage.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * - */ - -var inherits = require('inherits'); -var OutMessage = require('../OutMessage'); - -module.exports = function (Constants) { - function DeskShareRTMPBroadcastStoppedEventMessage (conferenceName, streamUrl, vw, vh, timestamp) { - DeskShareRTMPBroadcastStoppedEventMessage.super_.call(this, Constants.DESKSHARE_RTMP_BROADCAST_STOPPED); - - this.payload = {}; - this.payload[Constants.CONFERENCE_NAME] = conferenceName; - this.payload[Constants.STREAM_URL] = streamUrl; - this.payload[Constants.TIMESTAMP] = timestamp; - this.payload[Constants.VIDEO_WIDTH] = vw; - this.payload[Constants.VIDEO_HEIGHT] = vh; - }; - - inherits(DeskShareRTMPBroadcastStoppedEventMessage, OutMessage); - return DeskShareRTMPBroadcastStoppedEventMessage; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js b/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js deleted file mode 100644 index 28867a2265f3a1d6393ebadc4936cc785e0be651..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStartedEventMessage2x.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - */ - -var inherits = require('inherits'); -var OutMessage2x = require('../OutMessage2x'); - -module.exports = function (C) { - function ScreenshareRTMPBroadcastStartedEventMessage2x (conferenceName, screenshareConf, - streamUrl, vw, vh, timestamp) { - ScreenshareRTMPBroadcastStartedEventMessage2x.super_.call(this, C.SCREENSHARE_RTMP_BROADCAST_STARTED_2x, - {voiceConf: conferenceName}, {voiceConf: conferenceName}); - - this.core.body = {}; - this.core.body[C.CONFERENCE_NAME] = conferenceName; - this.core.body[C.SCREENSHARE_CONF] = screenshareConf; - this.core.body[C.STREAM_URL] = streamUrl; - this.core.body[C.VIDEO_WIDTH] = vw; - this.core.body[C.VIDEO_HEIGHT] = vh; - this.core.body[C.TIMESTAMP] = timestamp; - }; - - inherits(ScreenshareRTMPBroadcastStartedEventMessage2x, OutMessage2x); - return ScreenshareRTMPBroadcastStartedEventMessage2x; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js b/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js deleted file mode 100644 index d02dfb2cd3a335518cf5a207880cbb4b17e8cf64..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/screenshare/ScreenshareRTMPBroadcastStoppedEventMessage2x.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - */ - -var inherits = require('inherits'); -var OutMessage2x = require('../OutMessage2x'); - -module.exports = function (C) { - function ScreenshareRTMPBroadcastStoppedEventMessage2x (conferenceName, screenshareConf, - streamUrl, vw, vh, timestamp) { - ScreenshareRTMPBroadcastStoppedEventMessage2x.super_.call(this, C.SCREENSHARE_RTMP_BROADCAST_STOPPED_2x, - {voiceConf: conferenceName}, {voiceConf: conferenceName}); - - this.core.body = {}; - this.core.body[C.CONFERENCE_NAME] = conferenceName; - this.core.body[C.SCREENSHARE_CONF] = screenshareConf; - this.core.body[C.STREAM_URL] = streamUrl; - this.core.body[C.VIDEO_WIDTH] = vw; - this.core.body[C.VIDEO_HEIGHT] = vh; - this.core.body[C.TIMESTAMP] = timestamp; - }; - - inherits(ScreenshareRTMPBroadcastStoppedEventMessage2x, OutMessage2x); - return ScreenshareRTMPBroadcastStoppedEventMessage2x; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js b/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js deleted file mode 100644 index 69d5f0890f7c38d94a62e99e41cd7672ba8269fe..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderRequestMessage.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - */ - -var inherits = require('inherits'); -var OutMessage = require('../OutMessage'); - -module.exports = function (Constants) { - function StartTranscoderRequestMessage (meetingId, transcoderId, params) { - StartTranscoderRequestMessage.super_.call(this, Constants.START_TRANSCODER_REQUEST); - - this.payload = {}; - this.payload[Constants.MEETING_ID] = meetingId; - this.payload[Constants.TRANSCODER_ID] = transcoderId; - this.payload[Constants.PARAMS] = params; - }; - - inherits(StartTranscoderRequestMessage, OutMessage); - return StartTranscoderRequestMessage; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js b/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js deleted file mode 100644 index bd517a14905d51effe3abdc28987d3bca2b91a82..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/transcode/StartTranscoderSysReqMsg.js +++ /dev/null @@ -1,18 +0,0 @@ -var inherits = require('inherits'); -var OutMessage2x = require('../OutMessage2x'); -var C = require('../Constants'); - -module.exports = function() { - function StartTranscoderSysReqMsg(meetingId, transcoderId, params) { - StartTranscoderSysReqMsg.super_.call(this, C.START_TRANSCODER_REQ_2x, - {sender: "kurento-screenshare"}, - {meetingId: meetingId}); - - this.core.body = {}; - this.core.body[C.TRANSCODER_ID_2x] = transcoderId; - this.core.body[C.PARAMS] = params; - }; - - inherits(StartTranscoderSysReqMsg, OutMessage2x); - return StartTranscoderSysReqMsg; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js b/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js deleted file mode 100644 index ad030d2c623252d385c8298bdf79c112caf12623..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderRequestMessage.js +++ /dev/null @@ -1,15 +0,0 @@ -var inherits = require('inherits'); -var OutMessage = require('../OutMessage'); - -module.exports = function (Constants) { - function StopTranscoderRequestMessage (meetingId, transcoderId) { - StopTranscoderRequestMessage.super_.call(this, Constants.STOP_TRANSCODER_REQUEST); - - this.payload = {}; - this.payload[Constants.MEETING_ID] = meetingId; - this.payload[Constants.TRANSCODER_ID] = transcoderId; - }; - - inherits(StopTranscoderRequestMessage, OutMessage); - return StopTranscoderRequestMessage; -} diff --git a/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js b/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js deleted file mode 100644 index 639b415792b643ff20bfa47ad523bf4e72f27d5a..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/messages/transcode/StopTranscoderSysReqMsg.js +++ /dev/null @@ -1,17 +0,0 @@ -var inherits = require('inherits'); -var OutMessage2x = require('../OutMessage2x'); -var C = require('../Constants'); - -module.exports = function() { - function StopTranscoderSysReqMsg(meetingId, transcoderId) { - StopTranscoderSysReqMsg.super_.call(this, C.STOP_TRANSCODER_REQ_2x, - {sender: "kurento-screenshare"}, - {meetingId: meetingId}); - - this.core.body = {}; - this.core.body[C.TRANSCODER_ID_2x] = transcoderId; - }; - - inherits(StopTranscoderSysReqMsg, OutMessage2x); - return StopTranscoderSysReqMsg; -} diff --git a/labs/kurento-screenshare/lib/bbb/pubsub/RedisWrapper.js b/labs/kurento-screenshare/lib/bbb/pubsub/RedisWrapper.js deleted file mode 100644 index da92167e4169e8a03ee3d3cb3e03b78405c1049f..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/pubsub/RedisWrapper.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @classdesc - * Redis wrapper class for connecting to Redis channels - */ - -/* Modules */ - -var redis = require('redis'); -var config = require('config'); -var Constants = require('../messages/Constants.js'); -var util = require('util'); -const EventEmitter = require('events').EventEmitter; -const _retryThreshold = 1000 * 60 * 60; -const _maxRetries = 10; - - -/* Public members */ - -var RedisWrapper = function(subpattern) { - // Redis PubSub client holders - this.redisCli = null; - this.redisPub = null; - // Pub and Sub channels/patterns - this.subpattern = subpattern; - EventEmitter.call(this); -} - -util.inherits(RedisWrapper, EventEmitter); - -RedisWrapper.prototype.startRedis = function(callback) { - var self = this; - if (this.redisCli) { - console.log(" [RedisWrapper] Redis Client already exists"); - callback(false, this); - } - - var options = { - host : config.get('redisHost'), - port : config.get('redisPort'), - //password: config.get('redis.password') - retry_strategy: redisRetry - }; - - this.redisCli = redis.createClient(options); - this.redisPub = redis.createClient(options); - - console.log(" [RedisWrapper] Trying to subscribe to redis channel"); - - this.redisCli.on("psubscribe", function (channel, count) { - console.log(" [RedisWrapper] Successfully subscribed to pattern [" + channel + "]"); - }); - - this.redisCli.on("pmessage", self.onMessage.bind(self)); - this.redisCli.psubscribe(this.subpattern); - - console.log(" [RedisWrapper] Started Redis client at " + options.host + ":" + options.port + - " for subscription pattern: " + this.subpattern); - - callback(false, this); -}; - -RedisWrapper.prototype.stopRedis = function(callback) { - if (this.redisCli){ - this.redisCli.quit(); - } - callback(false); -}; - -RedisWrapper.prototype.publishToChannel = function(message, channel) { - if(this.redisPub) { - console.log(" [RedisWrapper] Sending message to channel [" + channel + "]: " + message); - this.redisPub.publish(channel, message); - } -}; - -RedisWrapper.prototype.onMessage = function(pattern, channel, message) { - console.log(" [RedisWrapper] Message received from channel [" + channel + "] : " + message); - // use event emitter to throw new message - this.emit(Constants.REDIS_MESSAGE, message); -} - -/* Private members */ - -function redisRetry(options) { - if (options.error && options.error.code === 'ECONNREFUSED') { - return new Error('The server refused the connection'); - } - if (options.total_retry_time > _retryThreshold) { - return new Error('Retry time exhausted'); - } - if (options.times_connected > _maxRetries) { - return undefined; - } - return Math.max(options.attempt * 100, 3000); -}; - -module.exports = RedisWrapper; diff --git a/labs/kurento-screenshare/lib/bbb/pubsub/bbb-gw.js b/labs/kurento-screenshare/lib/bbb/pubsub/bbb-gw.js deleted file mode 100644 index 1abbb25aa010d9dc2a18d09edb2064c8516d9463..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/bbb/pubsub/bbb-gw.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @classdesc - * BigBlueButton redis gateway for bbb-screenshare node app - */ - -/* Modules */ - -var C = require('../messages/Constants.js'); -var RedisWrapper = require('./RedisWrapper.js'); -var config = require('config'); -var util = require('util'); -var EventEmitter = require('events').EventEmitter; - -/* Public members */ - -var BigBlueButtonGW = function () { - this.redisClients = null - EventEmitter.call(this); -}; - -util.inherits(BigBlueButtonGW, EventEmitter); - -BigBlueButtonGW.prototype.addSubscribeChannel = function (channel, callback) { - var self = this; - - if (this.redisClients === null) { - this.redisClients = {}; - } - - if (this.redisClients[channel]) { - return callback(null, this.redisClients[channel]); - } - - var wrobj = new RedisWrapper(channel); - this.redisClients[channel] = {}; - this.redisClients[channel] = wrobj; - wrobj.startRedis(function(error, redisCli) { - if(error) { - console.log(" [BigBlueButtonGW] Could not start redis client for channel " + channel); - return callback(error); - } - - console.log(" [BigBlueButtonGW] Added redis client to this.redisClients[" + channel + "]"); - wrobj.on(C.REDIS_MESSAGE, self.incomingMessage.bind(self)); - - return callback(null, wrobj); - }); -}; - -/** - * Capture messages from subscribed channels and emit an event with it's - * identifier and payload. Check Constants.js for the identifiers. - * - * @param {Object} message Redis message - */ -BigBlueButtonGW.prototype.incomingMessage = function (message) { - var msg = JSON.parse(message); - - // Trying to parse both message types, 1x and 2x - if (msg.header) { - var header = msg.header; - var payload = msg.payload; - } - else if (msg.core) { - var header = msg.core.header; - var payload = msg.core.body; - } - - if (header){ - switch (header.name) { - // interoperability with 1.1 - case C.START_TRANSCODER_REPLY: - this.emit(C.START_TRANSCODER_REPLY, payload); - break; - case C.STOP_TRANSCODER_REPLY: - this.emit(C.STOP_TRANSCODER_REPLY, payload); - break; - // 2x messages - case C.START_TRANSCODER_RESP_2x: - payload[C.MEETING_ID_2x] = header[C.MEETING_ID_2x]; - - this.emit(C.START_TRANSCODER_RESP_2x, payload); - break; - case C.STOP_TRANSCODER_RESP_2x: - payload[C.MEETING_ID_2x] = header[C.MEETING_ID_2x]; - this.emit(C.STOP_TRANSCODER_RESP_2x, payload); - break; - - default: - console.log(" [BigBlueButtonGW] Unknown Redis message with ID =>" + header.name); - } - } -}; - -BigBlueButtonGW.prototype.publish = function (message, channel, callback) { - for(var client in this.redisClients) { - if(typeof this.redisClients[client].publishToChannel === 'function') { - this.redisClients[client].publishToChannel(message, channel); - return callback(null); - } - } - return callback("Client not found"); -}; - -module.exports = BigBlueButtonGW; diff --git a/labs/kurento-screenshare/lib/h264-sdp.js b/labs/kurento-screenshare/lib/h264-sdp.js deleted file mode 100644 index 8da8f6d525858749e22f22428680c9985a908f2b..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/h264-sdp.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * A module with the sole purpose of removing all non h264 options from an sdpOffer - * - * We use this to prevent any transcoding from the Kurento side if Firefox or Chrome offer VP8/VP9 as - * the default format. - */ - -var sdpTransform = require('sdp-transform'); - -exports.transform = function(sdp) { - - var mediaIndex = 0; - var res = sdpTransform.parse(sdp); - var validPayloads; - - if (res.media[0].type === 'audio') { - // Audio - res.media[mediaIndex].rtp = res.media[mediaIndex].rtp.filter(function(elem) { - return elem.codec === 'opus'; - }); - - validPayloads = res.media[mediaIndex].rtp.map(function(elem) { - return elem.payload; - }); - - res.media[mediaIndex].fmtp = res.media[mediaIndex].fmtp.filter(function(elem) { - return validPayloads.indexOf(elem.payload) >= 0; - }); - - res.media[mediaIndex].payloads = validPayloads.join(' '); - - mediaIndex += 1; - } - - // Video - res.media[mediaIndex].rtp = res.media[mediaIndex].rtp.filter(function(elem) { - return elem.codec === 'H264'; - }); - - validPayloads = res.media[mediaIndex].rtp.map(function(elem) { - return elem.payload; - }); - - res.media[mediaIndex].fmtp = res.media[mediaIndex].fmtp.filter(function(elem) { - return validPayloads.indexOf(elem.payload) >= 0; - }); - - res.media[mediaIndex].rtcpFb = res.media[mediaIndex].rtcpFb.filter(function(elem) { - return validPayloads.indexOf(elem.payload) >= 0; - }); - - res.media[mediaIndex].payloads = validPayloads.join(' '); - - return sdpTransform.write(res); -}; - diff --git a/labs/kurento-screenshare/lib/media-controller.js b/labs/kurento-screenshare/lib/media-controller.js deleted file mode 100644 index df9697ec6984deb5f425fbb7c210fba4b6ce62e6..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/media-controller.js +++ /dev/null @@ -1,141 +0,0 @@ -'use strict' - -const Constants = require('./bbb/messages/Constants.js'); -const config = require('config'); -const kurento = require('kurento-client'); -const mediaServerClient = null; - -var _mediaPipelines = {}; -var _mediaElements= {}; - -function createMediaPipeline(id, callback) { - console.log(' [media] Creating media pipeline for ' + id); - getMediaServerClient(function (error, mediaServerClient) { - mediaServerClient.create('MediaPipeline', function(err, pipeline) { - if (error) { - console.log("Could not find media server at address " + kurentoUrl); - return callback(error); - } - return callback(null , pipeline); - }); - }); -}; - -function getMediaServerClient (callback) { - let kurentoUrl = config.get('kurentoUrl'); - if (mediaServerClient) { - callback(null, mediaServerClient); - } - else { - kurento(kurentoUrl, function(error, _mediaServerClient) { - if (error) { - console.log("Could not find media server at address " + kurentoUrl); - return callback(error, null); - } - - console.log(" [server] Initiating kurento client. Connecting to: " + kurentoUrl); - return callback(null, _mediaServerClient); - }); - } -}; - -/* Public members */ -module.exports = { - - createMediaElement : function (conference, type, callback) { - let self = this; - self.getMediaPipeline(conference, function(error, pipeline) { - - pipeline.create(type, function(error, mediaElement) { - if (error) { - return callback(error, null); - } - console.log(" [MediaController] Created [" + type + "] media element: " + mediaElement.id); - _mediaElements[mediaElement.id] = mediaElement; - return callback(null, mediaElement); - }); - }); - }, - - connectMediaElements : function (sourceId, sinkId, type, callback) { - let source = _mediaElements[sourceId]; - let sink = _mediaElements[sinkId]; - - if (source && sink) { - if (type === 'ALL') { - source.connect(sink, function (error) { - return callback (error); - }); - } else { - console.log(typeof source.connect); - source.connect(sink, type, function (error) { - return callback (error); - }); - } - } else { - return callback ("Failed to connect " + type + ": " + sourceId + " to " + sinkId); - } - }, - - releaseMediaElement : function (elementId) { - let mediaElement = _mediaElements[elementId]; - - if (typeof mediaElement !== 'undefined' && typeof mediaElement.release === 'function') { - mediaElement.release(); - } - }, - - releasePipeline: function (pipelineId) { - let MediaPipeline = _mediaPipelines[pipelineId]; - - if (typeof mediaElement !== 'undefined' && typeof mediaElement.release === 'function') { - mediaElement.release(); - } - }, - - processOffer : function (elementId, sdpOffer, callback) { - let mediaElement = _mediaElements[elementId]; - - if (typeof mediaElement !== 'undefined' && typeof mediaElement.processOffer === 'function') { - mediaElement.processOffer (sdpOffer, function (error, sdpAnswer) { - return callback (error, sdpAnswer); - }); - } else { - return callback (" [MediaController/processOffer] There is no element " + elementId, null); - } - }, - - getMediaPipeline : function(conference, callback) { - let self = this; - - if (_mediaPipelines[conference]) { - console.log(' [media] Pipeline already exists. ' + JSON.stringify(_mediaPipelines, null, 2)); - return callback(null, _mediaPipelines[conference]); - } else { - createMediaPipeline(conference, function(error, pipeline) { - _mediaPipelines[conference] = pipeline; - return callback(error, pipeline); - }); - } - }, - - addIceCandidate : function (elementId, candidate) { - let mediaElement = _mediaElements[elementId]; - - if (typeof mediaElement !== 'undefined' && typeof mediaElement.addIceCandidate === 'function') { - mediaElement.addIceCandidate(candidate); - } - }, - - gatherCandidates : function (elementId, callback) { - let mediaElement = _mediaElements[elementId]; - - if (typeof mediaElement !== 'undefined' && typeof mediaElement.gatherCandidates === 'function') { - mediaElement.gatherCandidates(function (error) { - return callback(error); - }); - } else { - return callback (" [MediaController/gatherCandidates] There is no element " + elementId, null); - } - }, -}; diff --git a/labs/kurento-screenshare/lib/media-handler.js b/labs/kurento-screenshare/lib/media-handler.js deleted file mode 100644 index 2d1ab3815cb3d583be7a115c12ab6a1c6626fa92..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/media-handler.js +++ /dev/null @@ -1,99 +0,0 @@ -var config = require('config'); -var kurento = require('kurento-client'); -var Constants = require('./bbb/messages/Constants'); - -var kurentoClient = null; -var mediaPipelines = {}; - -module.exports.getKurentoClient = function(kurentoUrl, callback) { - if (kurentoClient !== null) { - return callback(null, kurentoClient); - } - - kurento(kurentoUrl, function(error, _kurentoClient) { - if (error) { - console.log("Could not find media server at address " + kurentoUrl); - return callback("Could not find media server at address" + kurentoUrl + ". Exiting with error " + error); - } - - console.log(" [MediaHandler] Initiating kurento client. Connecting to: " + kurentoUrl); - - kurentoClient = _kurentoClient; - callback(null, kurentoClient); - }); -} - -module.exports.getMediaPipeline = function(id, callback) { - console.log(' [MediaHandler] Creating media pipeline for ' + id); - - if (mediaPipelines[id]) { - console.log(' [media] Pipeline already exists.'); - callback(null, mediaPipelines[id]); - } else { - kurentoClient.create('MediaPipeline', function(err, pipeline) { - mediaPipelines[id] = pipeline; - return callback(err, pipeline); - }); - } -} - -module.exports.generateSdp = function(remote_ip_address, remote_video_port) { - return "v=0\r\n" - + "o=- 0 0 IN IP4 " + remote_ip_address + "\r\n" - + "s=Kurento-SCREENSHARE\r\n" - + "c=IN IP4 " + remote_ip_address + "\r\n" - + "t=0 0\r\n" - + "m=video " + remote_video_port + " RTP/AVPF 96\r\n" - + "a=rtpmap:96 H264/90000\r\n" - + "a=ftmp:96\r\n"; -} - -module.exports.generateVideoSdp = function (sourceIpAddress, sourceVideoPort) { - return "v=0\r\n" - + "o=- 0 0 IN IP4 " + sourceIpAddress + "\r\n" - + "s=Kurento-SCREENSHARE\r\n" - + 'm=video ' + sourceVideoPort + ' ' + this.videoConfiguration.rtpProfile + ' ' + this.videoConfiguration.codecId + '\r\n' - + 'a=' + this.videoConfiguration.sendReceive + '\r\n' - + 'c=IN IP4 ' + sourceIpAddress + '\r\n' - + 'a=rtpmap:' + this.videoConfiguration.codecId + ' ' + this.videoConfiguration.codecName + '/' + this.videoConfiguration.codecRate + '\r\n' - + 'a=fmtp:' + this.videoConfiguration.codecId + '\r\n' - + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' ccm fir \r\n' - + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' nack \r\n' - + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' nack pli \r\n' - + 'a=rtcp-fb:' + this.videoConfiguration.codecId + ' goog-remb \r\n'; -}; - -module.exports.videoConfiguration = { - codecId: '96', - sendReceive: 'sendrecv', - rtpProfile: 'RTP/AVPF', - codecName: 'H264', - frameRate: '30.000000', - codecRate: '90000' -}; - -module.exports.generateStreamUrl = function (address, meeting, path) { - return "rtmp://" + address + "/video-broadcast/" + meeting + "/" + path; -} - -module.exports.generateTranscoderParams = function (localIp, destIp, sendPort, recvPort, input, streamType, transcoderType, codec, callername) { - var rtpParams = {}; - rtpParams[Constants.LOCAL_IP_ADDRESS] = localIp; - rtpParams[Constants.LOCAL_VIDEO_PORT] = sendPort; - rtpParams[Constants.DESTINATION_IP_ADDRESS] = destIp; - rtpParams[Constants.REMOTE_VIDEO_PORT] = recvPort; - rtpParams[Constants.INPUT] = input; - rtpParams[Constants.STREAM_TYPE] = streamType; - rtpParams[Constants.TRANSCODER_TYPE] = transcoderType; - rtpParams[Constants.TRANSCODER_CODEC] = codec; - rtpParams[Constants.CALLERNAME] = callername; - return rtpParams; -} - -module.exports.getPort = function (min_port, max_port) { - return Math.floor((Math.random() * (max_port - min_port + 1) + min_port)); -} - -module.exports.getVideoPort = function () { - return this.getPort(config.get('minVideoPort'), config.get('maxVideoPort')); -} diff --git a/labs/kurento-screenshare/lib/screenshare.js b/labs/kurento-screenshare/lib/screenshare.js deleted file mode 100644 index 8dee4ca81662f0a2c32c669844e579eade2b9d23..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/screenshare.js +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Lucas Fialho Zawacki - * Paulo Renato Lanzarin - * (C) Copyright 2017 Bigbluebutton - * - */ - -'use strict' - -// Imports -const C = require('./bbb/messages/Constants'); -const MediaHandler = require('./media-handler'); -const Messaging = require('./bbb/messages/Messaging'); -const moment = require('moment'); -const h264_sdp = require('./h264-sdp'); -const now = moment(); -const MediaController = require('./media-controller'); - -// Global stuff -var sharedScreens = {}; -var rtpEndpoints = {}; - -const kurento = require('kurento-client'); -const config = require('config'); -const kurentoUrl = config.get('kurentoUrl'); -const kurentoIp = config.get('kurentoIp'); -const localIpAddress = config.get('localIpAddress'); - -if (config.get('acceptSelfSignedCertificate')) { - process.env.NODE_TLS_REJECT_UNAUTHORIZED=0; -} - -module.exports = class Screenshare { - constructor(ws, id, bbbgw, voiceBridge, caller, vh, vw, meetingId) { - this._ws = ws; - this._id = id; - this._BigBlueButtonGW = bbbgw; - this._presenterEndpoint = null; - this._ffmpegRtpEndpoint = null; - this._voiceBridge = voiceBridge; - this._meetingId = meetingId; - this._caller = caller; - this._streamUrl = ""; - this._vw = vw; - this._vh = vh; - this._candidatesQueue = []; - this._viewersEndpoint = []; - this._viewersCandidatesQueue = []; - } - - // TODO isolate ICE - _onIceCandidate(_candidate) { - let candidate = kurento.getComplexType('IceCandidate')(_candidate); - - if (this._presenterEndpoint) { - console.log(" [screenshare] Adding ICE candidate to presenter"); - this._presenterEndpoint.addIceCandidate(candidate); - } - else { - this._candidatesQueue.push(candidate); - } - }; - - _onViewerIceCandidate(_candidate, callerName) { - console.log("onviewericecandidate callerName = " + callerName); - let candidate = kurento.getComplexType('IceCandidate')(_candidate); - - if (this._viewersEndpoint[callerName]) { - this._viewersEndpoint[callerName].addIceCandidate(candidate); - } - else { - if (!this._viewersCandidatesQueue[callerName]) { - this._viewersCandidatesQueue[callerName] = []; - } - this._viewersCandidatesQueue[callerName].push(candidate); - } - } - - _startViewer(ws, voiceBridge, sdp, callerName, presenterEndpoint, callback) { - let self = this; - let _callback = function(){}; - console.log("startviewer callerName = " + callerName); - self._viewersCandidatesQueue[callerName] = []; - - console.log("VIEWER VOICEBRIDGE: "+self._voiceBridge); - - MediaController.createMediaElement(voiceBridge, C.WebRTC, function(error, webRtcEndpoint) { - if (error) { - console.log("Media elements error" + error); - return _callback(error); - } - - self._viewersEndpoint[callerName] = webRtcEndpoint; - - // QUEUES UP ICE CANDIDATES IF NEGOTIATION IS NOT YET READY - while(self._viewersCandidatesQueue[callerName].length) { - let candidate = self._viewersCandidatesQueue[callerName].shift(); - MediaController.addIceCandidate(self._viewersEndpoint[callerName].id, candidate); - } - // CONNECTS TWO MEDIA ELEMENTS - MediaController.connectMediaElements(presenterEndpoint.id, self._viewersEndpoint[callerName].id, C.VIDEO, function(error) { - if (error) { - console.log("Media elements CONNECT error " + error); - //pipeline.release(); - return _callback(error); - } - }); - - // ICE NEGOTIATION WITH THE ENDPOINT - self._viewersEndpoint[callerName].on('OnIceCandidate', function(event) { - let candidate = kurento.getComplexType('IceCandidate')(event.candidate); ws.sendMessage({ id : 'iceCandidate', candidate : candidate }); - }); - - sdp = h264_sdp.transform(sdp); - // PROCESS A SDP OFFER - MediaController.processOffer(webRtcEndpoint.id, sdp, function(error, webRtcSdpAnswer) { - if (error) { - console.log(" [webrtc] processOffer error => " + error + " for SDP " + sdp); - //pipeline.release(); - return _callback(error); - } - ws.sendMessage({id: "viewerResponse", sdpAnswer: webRtcSdpAnswer, response: "accepted"}); - console.log(" Sent sdp message to client with callerName:" + callerName); - - MediaController.gatherCandidates(webRtcEndpoint.id, function(error) { - if (error) { - return _callback(error); - } - - self._viewersEndpoint[callerName].on('MediaFlowInStateChange', function(event) { - if (event.state === 'NOT_FLOWING') { - console.log(" NOT FLOWING "); - } - else if (event.state === 'FLOWING') { - console.log(" FLOWING "); - } - }); - }); - }); - }); - } - - - _startPresenter(id, ws, sdpOffer, callback) { - let self = this; - let _callback = callback; - - // Force H264 on Firefox and Chrome - sdpOffer = h264_sdp.transform(sdpOffer); - console.log("Starting presenter for " + sdpOffer); - console.log("PRESENTER VOICEBRIDGE: " + self._voiceBridge); - MediaController.createMediaElement(self._voiceBridge, C.WebRTC, function(error, webRtcEndpoint) { - if (error) { - console.log("Media elements error" + error); - return _callback(error); - } - MediaController.createMediaElement(self._voiceBridge, C.RTP, function(error, rtpEndpoint) { - if (error) { - console.log("Media elements error" + error); - return _callback(error); - } - - - while(self._candidatesQueue.length) { - let candidate = self._candidatesQueue.shift(); - MediaController.addIceCandidate(webRtcEndpoint.id, candidate); - } - - MediaController.connectMediaElements(webRtcEndpoint.id, rtpEndpoint.id, C.VIDEO, function(error) { - if (error) { - console.log("Media elements CONNECT error " + error); - //pipeline.release(); - return _callback(error); - } - - // It's a user sharing a Screen - sharedScreens[id] = webRtcEndpoint; - rtpEndpoints[id] = rtpEndpoint; - - // Store our endpoint - self._presenterEndpoint = webRtcEndpoint; - self._ffmpegRtpEndpoint = rtpEndpoint; - - self._presenterEndpoint.on('OnIceCandidate', function(event) { - let candidate = kurento.getComplexType('IceCandidate')(event.candidate); - ws.sendMessage({ id : 'iceCandidate', cameraId: id, candidate : candidate }); - }); - - MediaController.processOffer(webRtcEndpoint.id, sdpOffer, function(error, webRtcSdpAnswer) { - if (error) { - console.log(" [webrtc] processOffer error => " + error + " for SDP " + sdpOffer); - //pipeline.release(); - return _callback(error); - } - - let sendVideoPort = MediaHandler.getVideoPort(); - - let rtpSdpOffer = MediaHandler.generateVideoSdp(localIpAddress, sendVideoPort); - console.log(" [rtpendpoint] RtpEndpoint processing => " + rtpSdpOffer); - - MediaController.gatherCandidates(webRtcEndpoint.id, function(error) { - if (error) { - return _callback(error); - } - - MediaController.processOffer(rtpEndpoint.id, rtpSdpOffer, function(error, rtpSdpAnswer) { - if (error) { - console.log(" [rtpendpoint] processOffer error => " + error + " for SDP " + rtpSdpOffer); - //pipeline.release(); - return _callback(error); - } - - console.log(" [rtpendpoint] KMS answer SDP => " + rtpSdpAnswer); - let recvVideoPort = rtpSdpAnswer.match(/m=video\s(\d*)/)[1]; - let rtpParams = MediaHandler.generateTranscoderParams(kurentoIp, localIpAddress, - sendVideoPort, recvVideoPort, self._meetingId, "stream_type_video", C.RTP_TO_RTMP, "copy", "caller"); - - self._ffmpegRtpEndpoint.on('MediaFlowInStateChange', function(event) { - if (event.state === 'NOT_FLOWING') { - self._onRtpMediaNotFlowing(); - } - else if (event.state === 'FLOWING') { - self._onRtpMediaFlowing(self._meetingId, rtpParams); - } - }); - return _callback(null, webRtcSdpAnswer); - }); - }); - }); - }); - }); - }); - }; - - _stop() { - - console.log(' [stop] Releasing endpoints for ' + this._id); - - this._stopScreensharing(); - - if (this._presenterEndpoint) { - MediaController.releaseMediaElement(this._presenterEndpoint.id); - this._presenterEndpoint = null; - } else { - console.log(" [webRtcEndpoint] PLEASE DONT TRY STOPPING THINGS TWICE"); - } - if (this._ffmpegRtpEndpoint) { - MediaController.releaseMediaElement(this._ffmpegRtpEndpoint.id); - this._ffmpegRtpEndpoint = null; - } else { - console.log(" [rtpEndpoint] PLEASE DONT TRY STOPPING THINGS TWICE"); - } - - console.log(' [stop] Screen is shared, releasing ' + this._id); - - delete sharedScreens[this._id]; - - delete this._candidatesQueue; - }; - - _stopScreensharing() { - let self = this; - let strm = Messaging.generateStopTranscoderRequestMessage(this._meetingId, this._meetingId); - - self._BigBlueButtonGW.publish(strm, C.TO_BBB_TRANSCODE_SYSTEM_CHAN, function(error) {}); - - // Interoperability: capturing 1.1 stop_transcoder_reply messages - self._BigBlueButtonGW.once(C.STOP_TRANSCODER_REPLY, function(payload) { - let meetingId = payload[C.MEETING_ID]; - self._stopRtmpBroadcast(meetingId); - }); - - // Capturing stop transcoder responses from the 2x model - self._BigBlueButtonGW.once(C.STOP_TRANSCODER_RESP_2x, function(payload) { - let meetingId = payload[C.MEETING_ID_2x]; - self._stopRtmpBroadcast(meetingId); - }); - - } - - _onRtpMediaFlowing(meetingId, rtpParams) { - console.log(" [screenshare] Media FLOWING for meeting => " + meetingId); - let self = this; - let strm = Messaging.generateStartTranscoderRequestMessage(meetingId, meetingId, rtpParams); - - // Interoperability: capturing 1.1 start_transcoder_reply messages - self._BigBlueButtonGW.once(C.START_TRANSCODER_REPLY, function(payload) { - let meetingId = payload[C.MEETING_ID]; - let output = payload["params"].output; - self._startRtmpBroadcast(meetingId, output); - }); - - // Capturing stop transcoder responses from the 2x model - self._BigBlueButtonGW.once(C.START_TRANSCODER_RESP_2x, function(payload) { - let meetingId = payload[C.MEETING_ID_2x]; - let output = payload["params"].output; - self._startRtmpBroadcast(meetingId, output); - }); - - - self._BigBlueButtonGW.publish(strm, C.TO_BBB_TRANSCODE_SYSTEM_CHAN, function(error) {}); - }; - - _stopRtmpBroadcast (meetingId) { - console.log(" [screenshare] _stopRtmpBroadcast for meeting => " + meetingId); - let self = this; - if(self._meetingId === meetingId) { - // TODO correctly assemble this timestamp - let timestamp = now.format('hhmmss'); - let dsrstom = Messaging.generateScreenshareRTMPBroadcastStoppedEvent2x(self._voiceBridge, - self._voiceBridge, self._streamUrl, self._vw, self._vh, timestamp); - self._BigBlueButtonGW.publish(dsrstom, C.FROM_VOICE_CONF_SYSTEM_CHAN, function(error) {}); - } - } - - _startRtmpBroadcast (meetingId, output) { - console.log(" [screenshare] _startRtmpBroadcast for meeting => " + meetingId); - var self = this; - if(self._meetingId === meetingId) { - // TODO correctly assemble this timestamp - let timestamp = now.format('hhmmss'); - self._streamUrl = MediaHandler.generateStreamUrl(localIpAddress, meetingId, output); - let dsrbstam = Messaging.generateScreenshareRTMPBroadcastStartedEvent2x(self._voiceBridge, - self._voiceBridge, self._streamUrl, self._vw, self._vh, timestamp); - - self._BigBlueButtonGW.publish(dsrbstam, C.FROM_VOICE_CONF_SYSTEM_CHAN, function(error) {}); - } - } - - _onRtpMediaNotFlowing() { - console.log(" [screenshare] TODO RTP NOT_FLOWING"); - }; - - _stopViewer(id) { - let viewer = this._viewersEndpoint[id]; - console.log(' [stop] Releasing endpoints for ' + id); - - if (viewer) { - MediaController.releaseMediaElement(viewer.id); - this._viewersEndpoint[viewer.id] = null; - } else { - console.log(" [webRtcEndpoint] PLEASE DONT TRY STOPPING THINGS TWICE"); - } - - delete this._viewersCandidatesQueue[id]; - }; -}; diff --git a/labs/kurento-screenshare/lib/websocket.js b/labs/kurento-screenshare/lib/websocket.js deleted file mode 100644 index c4fe9f6f18b220e8b4c43be58ec75004a6430124..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/lib/websocket.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Simple wrapper around the ws library - * - */ - -var ws = require('ws'); - -ws.prototype.sendMessage = function(json) { - - return this.send(JSON.stringify(json), function(error) { - if(error) - console.log(' [server] Websocket error "' + error + '" on message "' + json.id + '"'); - }); - -}; - - -module.exports = ws; \ No newline at end of file diff --git a/labs/kurento-screenshare/package.json b/labs/kurento-screenshare/package.json deleted file mode 100644 index f6a75508907a2fe5cd5a74b82d6d495c62e336c3..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "bbb-screenshare-video-kurento-bridge", - "version": "1.0.0", - "private": true, - "scripts": { - "start": "nodejs server.js", - "postinstall": "npm start" - }, - "dependencies": { - "cookie-parser": "^1.3.5", - "express": "~4.12.4", - "express-session": "~1.10.3", - "kurento-client": "6.6.0", - "moment": "*", - "redis": "^2.6.2", - "sdp-transform": "*", - "uuid": "^3.1.0", - "ws": "~1.0.1" - }, - "devDependencies": { - "config": "^1.26.1", - "js-yaml": "^3.8.3" - } -} diff --git a/labs/kurento-screenshare/server.js b/labs/kurento-screenshare/server.js deleted file mode 100755 index f645ac88a52ffa328944f6f775b868bda3b0ae34..0000000000000000000000000000000000000000 --- a/labs/kurento-screenshare/server.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Paulo Renato Lanzarin - * (C) Copyright 2017 Bigbluebutton - * - */ - -const ConnectionManager = require('./lib/ConnectionManager'); -const CM = new ConnectionManager(); - -process.on('SIGTERM', CM._stopAll.bind(CM)); -process.on('SIGINT', CM._stopAll.bind(CM));