commit
08cf531dfc
@ -42,7 +42,7 @@ RUN set -x \
|
||||
&& chmod -R go=u,go-w /home/ngrok \
|
||||
&& chmod go= /home/ngrok
|
||||
|
||||
EXPOSE 8443
|
||||
EXPOSE 4443
|
||||
EXPOSE 4040
|
||||
|
||||
# Exec supervisord
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
web_addr: 0.0.0.0:4040
|
||||
tunnels:
|
||||
app:
|
||||
addr: 8443
|
||||
addr: 4443
|
||||
proto: http
|
||||
|
||||
@ -9,7 +9,7 @@ command=/bin/bash /kms.sh
|
||||
redirect_stderr=true
|
||||
|
||||
[program:openvidu-server]
|
||||
command=/bin/bash -c "java -Dspring.profiles.active=ngrok -Dserver.port=8443 -Dsecurity.ignored=/** -Dspring.resources.static-locations=file:///web/ -jar /openvidu-server.jar"
|
||||
command=/bin/bash -c "java -Dspring.profiles.active=ngrok -Dserver.port=4443 -Dsecurity.ignored=/** -Dspring.resources.static-locations=file:///web/ -jar /openvidu-server.jar"
|
||||
redirect_stderr=true
|
||||
|
||||
[program:ngrok]
|
||||
|
||||
@ -9,12 +9,12 @@ var numOfVideos = 0; // Keeps track of the number of videos that are being show
|
||||
|
||||
// Check if the URL already has a room
|
||||
window.addEventListener('load', function () {
|
||||
sessionId = window.location.hash; // For 'https://myurl/#roomId', sessionId would be '#roomId'
|
||||
sessionId = window.location.hash.slice(1); // For 'https://myurl/#roomId', sessionId would be 'roomId'
|
||||
if (sessionId) {
|
||||
// The URL has a session id. Join the room right away
|
||||
console.log("Joining to room " + sessionId);
|
||||
showSessionHideJoin();
|
||||
joinRoom(sessionId);
|
||||
joinRoom();
|
||||
} else {
|
||||
// The URL has not a session id. Show welcome page
|
||||
showJoinHideSession();
|
||||
@ -27,26 +27,23 @@ window.addEventListener('beforeunload', function () {
|
||||
});
|
||||
|
||||
|
||||
function joinRoom(sessionId) {
|
||||
function joinRoom() {
|
||||
|
||||
if (!sessionId) {
|
||||
// If the user is joining to a new room
|
||||
sessionId = '#' + randomString();
|
||||
sessionId = randomString();
|
||||
}
|
||||
|
||||
// As insecure OpenVidu, the user's token can be a random string
|
||||
var userId = randomString();
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with a sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
|
||||
// We will join the video-call "sessionId". As there's no server, this parameter must start with the URL of
|
||||
// OpenVidu Server (with secure websocket protocol: "wss://") and must include the OpenVidu secret at the end
|
||||
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + "?secret=MY_SECRET");
|
||||
// --- 2) Init a session ---
|
||||
|
||||
session = OV.initSession();
|
||||
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
@ -67,58 +64,66 @@ function joinRoom(sessionId) {
|
||||
});
|
||||
|
||||
|
||||
// --- 3) Connect to the session ---
|
||||
// --- 4) Connect to the session with a valid user token ---
|
||||
|
||||
// Remember 'userId' param (usually called 'token') is irrelevant when using the insecure version of OpenVidu
|
||||
session.connect(userId, function (error) {
|
||||
// 'getToken' method is simulating what your server-side should do.
|
||||
// 'token' parameter should be retrieved and returned by your own backend
|
||||
getToken(sessionId).then(token => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// Connect with the token
|
||||
session.connect(token)
|
||||
.then(() => {
|
||||
|
||||
// --- 4) Get your own camera stream with the desired resolution ---
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
publisher = OV.initPublisher('publisher', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
// Update the URL shown in the browser's navigation bar to show the session id
|
||||
var path = (location.pathname.slice(-1) == "/" ? location.pathname : location.pathname + "/");
|
||||
window.history.pushState("", "", path + '#' + sessionId);
|
||||
|
||||
// Auxiliary methods to show the session's view
|
||||
showSessionHideJoin();
|
||||
initializeSessionView();
|
||||
|
||||
// --- 6) Get your own camera stream with the desired properties ---
|
||||
|
||||
publisher = OV.initPublisher('publisher', {
|
||||
audioSource: undefined, // The source of audio. If undefined default audio input
|
||||
videoSource: undefined, // The source of video. If undefined default video input
|
||||
publishAudio: true, // Whether to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in target element 'video-container'
|
||||
mirror: true // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
// When your own video is added to DOM, update the page layout to fit it
|
||||
numOfVideos++;
|
||||
updateLayout();
|
||||
$(event.element).prop('muted', true); // Mute local video to avoid feedback
|
||||
});
|
||||
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
});
|
||||
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
// When your own video is added to DOM, update the page layout to fit it
|
||||
numOfVideos++;
|
||||
updateLayout();
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
// Update the URL shown in the browser's navigation bar to show the session id
|
||||
var pathname = (location.pathname.slice(-1) === "/" ? location.pathname : location.pathname+"/");
|
||||
window.history.pushState("", "", pathname + sessionId);
|
||||
|
||||
// Auxiliary methods to show the session's view
|
||||
showSessionHideJoin();
|
||||
initializeSessionView();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function leaveRoom() {
|
||||
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
|
||||
|
||||
// Back to welcome page
|
||||
window.location.href = window.location.origin + window.location.pathname;
|
||||
}
|
||||
@ -154,8 +159,6 @@ function muteVideo() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Generate a random string for sessionId and userId
|
||||
function randomString() {
|
||||
return Math.random().toString(36).slice(2);
|
||||
}
|
||||
@ -249,4 +252,52 @@ function updateLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
/* AUXILIARY METHODS */
|
||||
|
||||
|
||||
/**
|
||||
* --------------------------
|
||||
* SERVER-SIDE RESPONSABILITY
|
||||
* --------------------------
|
||||
* These methods retrieve the mandatory user token from OpenVidu Server.
|
||||
* This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION (by using
|
||||
* the API REST, openvidu-java-client or openvidu-node-client):
|
||||
* 1) Initialize a session in OpenVidu Server (POST /api/sessions)
|
||||
* 2) Generate a token in OpenVidu Server (POST /api/tokens)
|
||||
* 3) The token must be consumed in Session.connect() method
|
||||
*/
|
||||
|
||||
function getToken(mySessionId) {
|
||||
return createSession(mySessionId).then(sId => createToken(sId));
|
||||
}
|
||||
|
||||
function createSession(sId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/sessions",
|
||||
data: JSON.stringify({ customSessionId: sId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.id),
|
||||
error: error => error.status === 409 ? resolve(sId) : reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createToken(sId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/tokens",
|
||||
data: JSON.stringify({ session: sId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.token),
|
||||
error: error => reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="resources/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</head>
|
||||
|
||||
@ -50,11 +47,13 @@
|
||||
</div>
|
||||
</form>
|
||||
<button id="mute-video" type="button" class="btn btn-primary float-right mute-button" onclick="muteVideo()">
|
||||
<span class="glyphicon glyphicon-facetime-video"></span> <span class="hidden-xs">Video</span>
|
||||
</button>
|
||||
<span class="glyphicon glyphicon-facetime-video"></span>
|
||||
<span class="hidden-xs">Video</span>
|
||||
</button>
|
||||
<button id="mute-audio" type="button" class="btn btn-primary float-right mute-button" onclick="muteAudio()">
|
||||
<span class="glyphicon glyphicon-volume-up"></span> <span class="hidden-xs">Audio</span>
|
||||
</button>
|
||||
<span class="glyphicon glyphicon-volume-up"></span>
|
||||
<span class="hidden-xs">Audio</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@ -63,10 +62,10 @@
|
||||
|
||||
<!-- Join page template -->
|
||||
<div id="join" class="row no-margin" hidden>
|
||||
<div id="img-div"><img src="resources/images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<div id="img-div"><img src="resources/images/openvidu_grey_bg_transp_cropped.png"/></div>
|
||||
<div id="join-dialog" class="jumbotron vertical-center">
|
||||
<h1 class="arciform">Get a room</h1>
|
||||
<button type="button" class="btn btn-lg btn-success" onclick="joinRoom()">Go!</button>
|
||||
<button type="button" class="btn btn-lg btn-success" onclick="joinRoom(); return false;">Go!</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-getaroom/web/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-getaroom/web/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -3,41 +3,88 @@ var session;
|
||||
|
||||
function joinSession() {
|
||||
|
||||
var sessionId = document.getElementById("sessionId").value;
|
||||
var mySessionId = document.getElementById("sessionId").value;
|
||||
|
||||
OV = new OpenVidu();
|
||||
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + '?secret=MY_SECRET');
|
||||
session = OV.initSession();
|
||||
|
||||
session.on('streamCreated', function (event) {
|
||||
session.subscribe(event.stream, 'subscriber');
|
||||
session.on("streamCreated", function (event) {
|
||||
session.subscribe(event.stream, "subscriber");
|
||||
});
|
||||
|
||||
session.connect(null, function (error) {
|
||||
getToken(mySessionId).then(token => {
|
||||
|
||||
if (!error) {
|
||||
var publisher = OV.initPublisher('publisher');
|
||||
session.publish(publisher);
|
||||
} else {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
|
||||
session.connect(token)
|
||||
.then(() => {
|
||||
document.getElementById("session-header").innerText = mySessionId;
|
||||
document.getElementById("join").style.display = "none";
|
||||
document.getElementById("session").style.display = "block";
|
||||
|
||||
var publisher = OV.initPublisher("publisher");
|
||||
session.publish(publisher);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("There was an error connecting to the session:", error.code, error.message);
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('session-header').innerText = sessionId;
|
||||
document.getElementById('join').style.display = 'none';
|
||||
document.getElementById('session').style.display = 'block';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
session.disconnect();
|
||||
|
||||
document.getElementById('join').style.display = 'block';
|
||||
document.getElementById('session').style.display = 'none';
|
||||
document.getElementById("join").style.display = "block";
|
||||
document.getElementById("session").style.display = "none";
|
||||
}
|
||||
|
||||
window.onbeforeunload = function () {
|
||||
if (session) session.disconnect()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* --------------------------
|
||||
* SERVER-SIDE RESPONSABILITY
|
||||
* --------------------------
|
||||
* These methods retrieve the mandatory user token from OpenVidu Server.
|
||||
* This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION (by using
|
||||
* the API REST, openvidu-java-client or openvidu-node-client):
|
||||
* 1) Initialize a session in OpenVidu Server (POST /api/sessions)
|
||||
* 2) Generate a token in OpenVidu Server (POST /api/tokens)
|
||||
* 3) The token must be consumed in Session.connect() method
|
||||
*/
|
||||
|
||||
function getToken(mySessionId) {
|
||||
return createSession(mySessionId).then(sessionId => createToken(sessionId));
|
||||
}
|
||||
|
||||
function createSession(sessionId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/sessions",
|
||||
data: JSON.stringify({ customSessionId: sessionId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.id),
|
||||
error: error => error.status === 409 ? resolve(sessionId) : reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createToken(sessionId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/tokens",
|
||||
data: JSON.stringify({ session: sessionId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.token),
|
||||
error: error => reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -2,15 +2,17 @@
|
||||
|
||||
<head>
|
||||
<title>openvidu-hello-world</title>
|
||||
<link rel="shortcut icon" href="resources/images/favicon.ico" type="image/x-icon">
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="join">
|
||||
<h1>Join a video session</h1>
|
||||
<form onsubmit="return joinSession()">
|
||||
<form onsubmit="joinSession(); return false">
|
||||
<p>
|
||||
<label>Session:</label>
|
||||
<input type="text" id="sessionId" value="SessionA" required>
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-hello-world/web/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-hello-world/web/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -7,7 +7,10 @@
|
||||
{
|
||||
"root": "src",
|
||||
"outDir": "dist",
|
||||
"assets": "assets",
|
||||
"assets": [
|
||||
"assets",
|
||||
"assets/images"
|
||||
],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
"test": "test.ts",
|
||||
@ -38,6 +41,9 @@
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"build": {
|
||||
"showCircularDependencies": false
|
||||
},
|
||||
"styleExt": "css",
|
||||
"prefixInterfaces": false
|
||||
}
|
||||
|
||||
@ -1,46 +1,29 @@
|
||||
{
|
||||
"name": "openvidu-insecure-angular",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"angular-cli": {},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"start": "ng serve",
|
||||
"lint": "tslint \"src/**/*.ts\"",
|
||||
"test": "ng test",
|
||||
"pree2e": "webdriver-manager update",
|
||||
"e2e": "protractor"
|
||||
"start": "ng serve"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/common": "^2.4.0",
|
||||
"@angular/compiler": "^2.4.0",
|
||||
"@angular/core": "^2.4.0",
|
||||
"@angular/forms": "^2.4.0",
|
||||
"@angular/http": "^2.4.0",
|
||||
"@angular/platform-browser": "^2.4.0",
|
||||
"@angular/platform-browser-dynamic": "^2.4.0",
|
||||
"@angular/router": "^3.4.0",
|
||||
"core-js": "^2.4.1",
|
||||
"openvidu-browser": "1.5.0",
|
||||
"zone.js": "^0.7.6"
|
||||
"@angular/common": "5.2.10",
|
||||
"@angular/compiler": "5.2.10",
|
||||
"@angular/core": "5.2.10",
|
||||
"@angular/forms": "5.2.10",
|
||||
"@angular/platform-browser": "5.2.10",
|
||||
"@angular/platform-browser-dynamic": "5.2.10",
|
||||
"core-js": "2.5.6",
|
||||
"openvidu-browser": "1.9.0",
|
||||
"openvidu-node-client": "1.9.0",
|
||||
"zone.js": "0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jasmine": "2.5.38",
|
||||
"@types/node": "~6.0.60",
|
||||
"@angular/cli": "1.0.0",
|
||||
"@angular/compiler-cli": "^2.4.0",
|
||||
"codelyzer": "~2.0.0",
|
||||
"jasmine-core": "~2.5.2",
|
||||
"jasmine-spec-reporter": "~3.2.0",
|
||||
"karma": "~1.4.1",
|
||||
"karma-chrome-launcher": "~2.0.0",
|
||||
"karma-cli": "~1.0.1",
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"karma-coverage-istanbul-reporter": "^0.2.0",
|
||||
"protractor": "~5.1.0",
|
||||
"ts-node": "~2.0.0",
|
||||
"tslint": "~4.4.2",
|
||||
"typescript": "2.5.3"
|
||||
"@types/node": "10.0.4",
|
||||
"@angular/cli": "1.7.4",
|
||||
"@angular/compiler-cli": "5.2.10",
|
||||
"codelyzer": "4.3.0",
|
||||
"ts-node": "6.0.3",
|
||||
"tslint": "5.10.0",
|
||||
"typescript": "2.7.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,16 @@
|
||||
<div id="main-container" class="container">
|
||||
<div *ngIf="!session" id="join">
|
||||
<div id="img-div"><img src="src/assets/images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<div id="img-div"><img src="assets/images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<div id="join-dialog" class="jumbotron vertical-center">
|
||||
<h1>Join a video session</h1>
|
||||
<form class="form-group" (submit)="joinSession()">
|
||||
<p>
|
||||
<label>Participant</label>
|
||||
<input class="form-control" type="text" id="userName" name="userName" [(ngModel)]="userName" required>
|
||||
<input class="form-control" type="text" id="userName" name="userName" [(ngModel)]="myUserName" required>
|
||||
</p>
|
||||
<p>
|
||||
<label>Session</label>
|
||||
<input class="form-control" type="text" id="sessionId" name="sessionId" [(ngModel)]="sessionId" required>
|
||||
<input class="form-control" type="text" id="sessionId" name="sessionId" [(ngModel)]="mySessionId" required>
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<input class="btn btn-lg btn-success" type="submit" name="commit" value="Join!">
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
<div *ngIf="session" id="session">
|
||||
<div id="session-header">
|
||||
<h1 id="session-title">{{sessionId}}</h1>
|
||||
<h1 id="session-title">{{mySessionId}}</h1>
|
||||
<input class="btn btn-large btn-danger" type="button" id="buttonLeaveSession" (click)="leaveSession()" value="Leave session">
|
||||
</div>
|
||||
<div *ngIf="this.mainVideoStream" id="main-video" class="col-md-6">
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { OpenVidu, Session, Stream } from 'openvidu-browser';
|
||||
import { Component, HostListener, Input } from '@angular/core';
|
||||
import { Component, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { OpenVidu, Session, Stream, StreamEvent } from 'openvidu-browser';
|
||||
import { OpenVidu as OpenViduAPI } from 'openvidu-node-client';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
export class AppComponent implements OnDestroy {
|
||||
|
||||
// OpenVidu objects
|
||||
OV: OpenVidu;
|
||||
@ -17,8 +18,8 @@ export class AppComponent {
|
||||
localStream: Stream;
|
||||
|
||||
// Join form
|
||||
sessionId: string;
|
||||
userName: string;
|
||||
mySessionId: string;
|
||||
myUserName: string;
|
||||
|
||||
// Main video of the page, will be 'localStream' or one of the 'remoteStreams',
|
||||
// updated by an Output event of StreamComponent children
|
||||
@ -41,81 +42,81 @@ export class AppComponent {
|
||||
|
||||
joinSession() {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with a sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
// Init OpenVidu object
|
||||
this.OV = new OpenVidu();
|
||||
|
||||
// We will join the video-call "sessionId". As there's no server, this parameter must start with the URL of
|
||||
// OpenVidu Server (with secure websocket protocol: "wss://") and must include the OpenVidu secret at the end
|
||||
this.session = this.OV.initSession('wss://' + location.hostname + ':8443/' + this.sessionId + '?secret=MY_SECRET');
|
||||
// --- 2) Init a session ---
|
||||
|
||||
this.session = this.OV.initSession();
|
||||
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
this.session.on('streamCreated', (event) => {
|
||||
this.session.on('streamCreated', (event: StreamEvent) => {
|
||||
|
||||
// Add the new stream to 'remoteStreams' array
|
||||
this.remoteStreams.push(event.stream);
|
||||
|
||||
// Subscribe to the Stream to receive it. Second parameter is an empty string
|
||||
// Subscribe to the Stream to receive it. Second parameter is undefined
|
||||
// so OpenVidu doesn't create an HTML video by its own
|
||||
this.session.subscribe(event.stream, '');
|
||||
this.session.subscribe(event.stream, undefined);
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
this.session.on('streamDestroyed', (event) => {
|
||||
|
||||
// Avoid OpenVidu trying to remove the HTML video element
|
||||
event.preventDefault();
|
||||
this.session.on('streamDestroyed', (event: StreamEvent) => {
|
||||
|
||||
// Remove the stream from 'remoteStreams' array
|
||||
this.deleteRemoteStream(event.stream);
|
||||
});
|
||||
|
||||
|
||||
// --- 3) Connect to the session ---
|
||||
// --- 4) Connect to the session with a valid user token ---
|
||||
|
||||
// First param irrelevant if your app has no server-side. Second param will be received by every user
|
||||
// in Stream.connection.data property, which will be appended to DOM as the user's nickname
|
||||
this.session.connect(null, '{"clientData": "' + this.userName + '"}', (error) => {
|
||||
// 'getToken' method is simulating what your server-side should do.
|
||||
// 'token' parameter should be retrieved and returned by your own backend
|
||||
this.getToken().then(token => {
|
||||
|
||||
// If connection successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// First param is the token got from OpenVidu Server. Second param can be retrieved by every user on event
|
||||
// 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname
|
||||
this.session.connect(token, { clientData: this.myUserName })
|
||||
.then(() => {
|
||||
|
||||
// --- 4) Get your own camera stream with the desired resolution ---
|
||||
// --- 5) Get your own camera stream ---
|
||||
|
||||
// Both audio and video will be active. Second parameter is an empty string
|
||||
// so OpenVidu doesn't create an HTML video by its own
|
||||
let publisher = this.OV.initPublisher('', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
// Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video
|
||||
// element: we will manage it ourselves) and with the desired properties
|
||||
let publisher = this.OV.initPublisher(undefined, {
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// Store your webcam stream in 'localStream' object
|
||||
this.localStream = publisher.stream;
|
||||
// Set the main video in the page to display our webcam
|
||||
this.mainVideoStream = this.localStream;
|
||||
|
||||
// --- 6) Publish your stream ---
|
||||
|
||||
this.session.publish(publisher);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
});
|
||||
|
||||
// Store your webcam stream in 'localStream' object
|
||||
this.localStream = publisher.stream;
|
||||
// Set the main video in the page to display our webcam
|
||||
this.mainVideoStream = this.localStream;
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
|
||||
this.session.publish(publisher);
|
||||
|
||||
} else {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
leaveSession() {
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
// --- 7) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
if (this.session) { this.session.disconnect(); };
|
||||
|
||||
// Empty all properties...
|
||||
@ -129,8 +130,8 @@ export class AppComponent {
|
||||
|
||||
private generateParticipantInfo() {
|
||||
// Random user nickname and sessionId
|
||||
this.sessionId = 'SessionA';
|
||||
this.userName = 'Participant' + Math.floor(Math.random() * 100);
|
||||
this.mySessionId = 'SessionA';
|
||||
this.myUserName = 'Participant' + Math.floor(Math.random() * 100);
|
||||
}
|
||||
|
||||
private deleteRemoteStream(stream: Stream): void {
|
||||
@ -144,4 +145,26 @@ export class AppComponent {
|
||||
this.mainVideoStream = stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* --------------------------
|
||||
* SERVER-SIDE RESPONSABILITY
|
||||
* --------------------------
|
||||
* This method retrieve the mandatory user token from OpenVidu Server,
|
||||
* in this case making use of OpenVidu Node Client.
|
||||
* This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION. In this case:
|
||||
* 1) Initialize a session in OpenVidu Server (OpenVidu.createSession with OpenVidu Node Client)
|
||||
* 2) Generate a token in OpenVidu Server (Session.generateToken with OpenVidu Node Client)
|
||||
* 3) The token must be consumed in Session.connect() method of OpenVidu Browser
|
||||
*/
|
||||
|
||||
getToken(): Promise<string> {
|
||||
let OV_NodeClient = new OpenViduAPI('https://' + location.hostname + ':4443', 'MY_SECRET');
|
||||
return OV_NodeClient.createSession({ customSessionId: this.mySessionId })
|
||||
.then(session_NodeClient => {
|
||||
return session_NodeClient.generateToken();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { StreamComponent } from './stream.component';
|
||||
@ -12,8 +11,7 @@ import { StreamComponent } from './stream.component';
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpModule
|
||||
FormsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Component, Input, Output, AfterViewInit, DoCheck, EventEmitter, ViewChild, ElementRef } from '@angular/core';
|
||||
|
||||
import { Stream } from 'openvidu-browser';
|
||||
|
||||
@Component({
|
||||
@ -61,7 +60,7 @@ export class StreamComponent implements AfterViewInit, DoCheck {
|
||||
return JSON.parse(this.stream.connection.data).clientData;
|
||||
}
|
||||
|
||||
videoClicked() { // Triggers event for the parent component to update its view
|
||||
videoClicked() { // Triggers event for the parent component to update its main video display
|
||||
this.mainVideoStream.next(this.stream);
|
||||
}
|
||||
|
||||
|
||||
BIN
openvidu-insecure-angular/src/assets/images/favicon.ico
Normal file
BIN
openvidu-insecure-angular/src/assets/images/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@ -3,18 +3,15 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>openvidu-insecure-angular</title>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" charset="utf-8">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
</head>
|
||||
@ -24,7 +21,7 @@
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><img class="demo-logo" src="src/assets/images/openvidu_vert_white_bg_trans_cropped.png"/> Insecure Angular</a>
|
||||
<a class="navbar-brand" href="/"><img class="demo-logo" src="assets/images/openvidu_vert_white_bg_trans_cropped.png"/> Insecure Angular</a>
|
||||
<a class="navbar-brand nav-icon" href="https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-insecure-angular" title="GitHub Repository" target="_blank"><i class="fa fa-github" aria-hidden="true"></i></a>
|
||||
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-insecure-angular/" title="Documentation" target="_blank"><i class="fa fa-book" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
@ -36,7 +33,7 @@
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="text-muted">OpenVidu © 2017</div>
|
||||
<a href="http://www.openvidu.io/" target="_blank"><img class="openvidu-logo" src="src/assets/images/openvidu_globe_bg_transp_cropped.png"/></a>
|
||||
<a href="http://www.openvidu.io/" target="_blank"><img class="openvidu-logo" src="assets/images/openvidu_globe_bg_transp_cropped.png"/></a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ RUN set -x \
|
||||
&& chmod go= /home/ngrok
|
||||
|
||||
EXPOSE 4040
|
||||
EXPOSE 8443
|
||||
EXPOSE 4443
|
||||
|
||||
# Exec supervisord
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
web_addr: 0.0.0.0:4040
|
||||
tunnels:
|
||||
app:
|
||||
addr: 8443
|
||||
addr: 4443
|
||||
proto: http
|
||||
|
||||
@ -9,7 +9,7 @@ command=/bin/bash /kms.sh
|
||||
redirect_stderr=true
|
||||
|
||||
[program:openvidu-server]
|
||||
command=/bin/bash -c "java -Dspring.profiles.active=ngrok -Dserver.port=8443 -Dsecurity.ignored=/** -Dspring.resources.static-locations=file:///web/ -jar /openvidu-server.jar"
|
||||
command=/bin/bash -c "java -Dspring.profiles.active=ngrok -Dserver.port=4443 -Dsecurity.ignored=/** -Dspring.resources.static-locations=file:///web/ -jar /openvidu-server.jar"
|
||||
redirect_stderr=true
|
||||
|
||||
[program:ngrok]
|
||||
|
||||
@ -6,29 +6,27 @@ var session;
|
||||
|
||||
function joinSession() {
|
||||
|
||||
var sessionId = document.getElementById("sessionId").value;
|
||||
var userName = document.getElementById("userName").value;
|
||||
var mySessionId = document.getElementById("sessionId").value;
|
||||
var myUserName = document.getElementById("userName").value;
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with a sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
// Init OpenVidu object
|
||||
OV = new OpenVidu();
|
||||
|
||||
// We will join the video-call "sessionId". As there's no server, this parameter must start with the URL of
|
||||
// OpenVidu Server (with secure websocket protocol: "wss://") and must include the OpenVidu secret at the end
|
||||
session = OV.initSession("wss://" + location.hostname + ":8443/" + sessionId + '?secret=MY_SECRET');
|
||||
// --- 2) Init a session ---
|
||||
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', event => {
|
||||
|
||||
// Subscribe to the Stream to receive it. HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
subscriber.on('videoElementCreated', event => {
|
||||
|
||||
// Add a new <p> element for the user's nickname just below its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
@ -36,63 +34,70 @@ function joinSession() {
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
session.on('streamDestroyed', event => {
|
||||
|
||||
// Delete the HTML element with the user's nickname. HTML videos are automatically removed from DOM
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
|
||||
// --- 3) Connect to the session ---
|
||||
// --- 4) Connect to the session with a valid user token ---
|
||||
|
||||
// First param irrelevant if your app has no server-side. Second param will be received by every user
|
||||
// in Stream.connection.data property, which will be appended to DOM as the user's nickname
|
||||
session.connect(null, '{"clientData": "' + userName + '"}', function (error) {
|
||||
// 'getToken' method is simulating what your server-side should do.
|
||||
// 'token' parameter should be retrieved and returned by your own backend
|
||||
getToken(mySessionId).then(token => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// First param is the token got from OpenVidu Server. Second param can be retrieved by every user on event
|
||||
// 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname
|
||||
session.connect(token, { clientData: myUserName })
|
||||
.then(() => {
|
||||
|
||||
// --- 4) Get your own camera stream with the desired resolution ---
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
document.getElementById('session-title').innerText = mySessionId;
|
||||
document.getElementById('join').style.display = 'none';
|
||||
document.getElementById('session').style.display = 'block';
|
||||
|
||||
// --- 6) Get your own camera stream with the desired properties ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
initMainVideo(event.element, myUserName);
|
||||
appendUserData(event.element, myUserName);
|
||||
event.element['muted'] = true;
|
||||
});
|
||||
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
});
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
initMainVideo(event.element, userName);
|
||||
appendUserData(event.element, userName);
|
||||
event.element['muted'] = true;
|
||||
});
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
console.log('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('session-title').innerText = sessionId;
|
||||
document.getElementById('join').style.display = 'none';
|
||||
document.getElementById('session').style.display = 'block';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
|
||||
// Removing all HTML elements with the user's nicknames.
|
||||
// Removing all HTML elements with user's nicknames.
|
||||
// HTML videos are automatically removed when leaving a Session
|
||||
removeAllUserData();
|
||||
|
||||
@ -101,9 +106,6 @@ function leaveSession() {
|
||||
document.getElementById('session').style.display = 'none';
|
||||
}
|
||||
|
||||
/* OPENVIDU METHODS */
|
||||
|
||||
|
||||
|
||||
|
||||
/* APPLICATION SPECIFIC METHODS */
|
||||
@ -168,4 +170,52 @@ function initMainVideo(videoElement, userData) {
|
||||
document.querySelector('#main-video video')['muted'] = true;
|
||||
}
|
||||
|
||||
/* APPLICATION SPECIFIC METHODS */
|
||||
|
||||
|
||||
/**
|
||||
* --------------------------
|
||||
* SERVER-SIDE RESPONSABILITY
|
||||
* --------------------------
|
||||
* These methods retrieve the mandatory user token from OpenVidu Server.
|
||||
* This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION (by using
|
||||
* the API REST, openvidu-java-client or openvidu-node-client):
|
||||
* 1) Initialize a session in OpenVidu Server (POST /api/sessions)
|
||||
* 2) Generate a token in OpenVidu Server (POST /api/tokens)
|
||||
* 3) The token must be consumed in Session.connect() method
|
||||
*/
|
||||
|
||||
function getToken(mySessionId) {
|
||||
return createSession(mySessionId).then(sessionId => createToken(sessionId));
|
||||
}
|
||||
|
||||
function createSession(sessionId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/sessions",
|
||||
data: JSON.stringify({ customSessionId: sessionId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.id),
|
||||
error: error => error.status === 409 ? resolve(sessionId) : reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createToken(sessionId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "https://" + location.hostname + ":4443/api/tokens",
|
||||
data: JSON.stringify({ session: sessionId }),
|
||||
headers: {
|
||||
"Authorization": "Basic " + btoa("OPENVIDUAPP:MY_SECRET"),
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: response => resolve(response.token),
|
||||
error: error => reject(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="resources/images/favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="stylesheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</head>
|
||||
|
||||
@ -38,7 +35,7 @@
|
||||
<div id="img-div"><img src="resources/images/openvidu_grey_bg_transp_cropped.png" /></div>
|
||||
<div id="join-dialog" class="jumbotron vertical-center">
|
||||
<h1>Join a video session</h1>
|
||||
<form class="form-group" onsubmit="return joinSession()">
|
||||
<form class="form-group" onsubmit="joinSession(); return false">
|
||||
<p>
|
||||
<label>Participant</label>
|
||||
<input class="form-control" type="text" id="userName" required>
|
||||
@ -73,4 +70,4 @@
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-insecure-js/web/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-insecure-js/web/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -15,6 +15,7 @@
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
|
||||
@ -95,7 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -63,7 +63,7 @@ public class LoginController {
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/logout", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "/logout", method = RequestMethod.POST)
|
||||
public ResponseEntity<Object> logout(HttpSession session) {
|
||||
System.out.println("'" + session.getAttribute("loggedUser") + "' has logged out");
|
||||
session.invalidate();
|
||||
|
||||
@ -25,22 +25,28 @@ import io.openvidu.java.client.OpenViduRole;
|
||||
@RequestMapping("/api-sessions")
|
||||
public class SessionController {
|
||||
|
||||
OpenVidu openVidu;
|
||||
// OpenVidu object as entrypoint of the SDK
|
||||
private OpenVidu openVidu;
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
|
||||
// Collection to pair session names and tokens (the inner Map pairs tokens and role associated)
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionNamesTokens = new ConcurrentHashMap<>();
|
||||
|
||||
// URL where our OpenVidu server is listening
|
||||
private String OPENVIDU_URL;
|
||||
// Secret shared with our OpenVidu server
|
||||
private String SECRET;
|
||||
|
||||
|
||||
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
|
||||
this.SECRET = secret;
|
||||
this.OPENVIDU_URL = openviduUrl;
|
||||
this.openVidu = new OpenVidu(OPENVIDU_URL, SECRET);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get-sessionid-token", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> getSessionIdToken(@RequestBody String sessionNameParam, HttpSession httpSession)
|
||||
@RequestMapping(value = "/get-token", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> getToken(@RequestBody String sessionNameParam, HttpSession httpSession)
|
||||
throws ParseException {
|
||||
|
||||
try {
|
||||
@ -48,12 +54,12 @@ public class SessionController {
|
||||
} catch (Exception e) {
|
||||
return getErrorResponse(e);
|
||||
}
|
||||
System.out.println("Getting sessionId and token | {sessionName}=" + sessionNameParam);
|
||||
System.out.println("Getting a token from OpenVidu Server | {sessionName}=" + sessionNameParam);
|
||||
|
||||
JSONObject sessionJSON = (JSONObject) new JSONParser().parse(sessionNameParam);
|
||||
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
String sessionName = (String) sessionJSON.get("session");
|
||||
// The video-call to connect
|
||||
String sessionName = (String) sessionJSON.get("sessionName");
|
||||
|
||||
// Role associated to this user
|
||||
OpenViduRole role = LoginController.users.get(httpSession.getAttribute("loggedUser")).role;
|
||||
@ -68,22 +74,18 @@ public class SessionController {
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
// Session already exists
|
||||
System.out.println("Existing session " + sessionName);
|
||||
try {
|
||||
|
||||
// Get the existing sessionId from our collection with
|
||||
// the sessionName param ("TUTORIAL")
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
|
||||
|
||||
// Update our collection storing the new token
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
// Prepare the response with the token
|
||||
responseJson.put(0, token);
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
@ -94,25 +96,22 @@ public class SessionController {
|
||||
}
|
||||
|
||||
} else {
|
||||
// New session: return a new sessionId and token
|
||||
// New session
|
||||
System.out.println("New session " + sessionName);
|
||||
try {
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
Session session = this.openVidu.createSession();
|
||||
// Get the sessionId
|
||||
String sessionId = session.getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = session.generateToken(tokenOptions);
|
||||
|
||||
// Store the session and the token in our collections
|
||||
this.mapSessions.put(sessionName, session);
|
||||
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.put(sessionName, new ConcurrentHashMap<>());
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
// Prepare the response with the token
|
||||
responseJson.put(0, token);
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
@ -140,29 +139,23 @@ public class SessionController {
|
||||
String sessionName = (String) sessionNameTokenJSON.get("sessionName");
|
||||
String token = (String) sessionNameTokenJSON.get("token");
|
||||
|
||||
// If the session exists ("TUTORIAL" in this case)
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
|
||||
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
|
||||
// If the token exists
|
||||
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
// If the session exists
|
||||
if (this.mapSessions.get(sessionName) != null && this.mapSessionNamesTokens.get(sessionName) != null) {
|
||||
|
||||
// If the token exists
|
||||
if (this.mapSessionNamesTokens.get(sessionName).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionNamesTokens.get(sessionName).isEmpty()) {
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
// The SESSIONID wasn't valid
|
||||
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
} else {
|
||||
// The SESSION does not exist
|
||||
System.out.println("Problems in the app server: the SESSION does not exist");
|
||||
|
||||
@ -5,5 +5,5 @@ server.ssl.key-store-password: openvidu
|
||||
server.ssl.key-store-type: JKS
|
||||
server.ssl.key-alias: openvidu-selfsigned
|
||||
|
||||
openvidu.url: https://localhost:8443/
|
||||
openvidu.url: https://localhost:4443/
|
||||
openvidu.secret: MY_SECRET
|
||||
|
||||
@ -1,35 +1,34 @@
|
||||
var OV;
|
||||
var session;
|
||||
|
||||
var sessionId;
|
||||
var token;
|
||||
var nickName;
|
||||
var userName;
|
||||
var sessionName;
|
||||
var sessionName; // Name of the video session the user will connect to
|
||||
var token; // Token retrieved from OpenVidu Server
|
||||
|
||||
|
||||
/* OPENVIDU METHODS */
|
||||
|
||||
function joinSession() {
|
||||
getSessionIdAndToken(function () {
|
||||
getToken((token) => {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
session = OV.initSession(sessionId);
|
||||
|
||||
// --- 2) Init a session ---
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
@ -37,38 +36,49 @@ function joinSession() {
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
session.on('streamDestroyed', (event) => {
|
||||
// Delete the HTML element with the user's name and nickname
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
|
||||
var nickName = $("#nickName").val();
|
||||
session.connect(token, { clientData: nickName })
|
||||
.then(() => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
// Here we check somehow if the user has at least 'PUBLISHER' role before
|
||||
var userName = $("#user").val();
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
|
||||
// Here we check somehow if the user has 'PUBLISHER' role before
|
||||
// trying to publish its stream. Even if someone modified the client's code and
|
||||
// published the stream, it wouldn't work if the token sent in Session.connect
|
||||
// method doesn't belong to a 'PUBLIHSER' role
|
||||
if (isPublisher()) {
|
||||
// method is not recognized as 'PUBLIHSER' role by OpenVidu Server
|
||||
if (isPublisher(userName)) {
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
// Init the main video with ours and append our data
|
||||
var userData = {
|
||||
nickName: nickName,
|
||||
@ -80,7 +90,7 @@ function joinSession() {
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
@ -88,22 +98,18 @@ function joinSession() {
|
||||
console.warn('You don\'t have permissions to publish');
|
||||
initMainVideoThumbnail(); // Show SUBSCRIBER message in main video
|
||||
}
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// 6) Leave the session by calling 'disconnect' method over the Session object
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
session = null;
|
||||
@ -124,68 +130,66 @@ function leaveSession() {
|
||||
function logIn() {
|
||||
var user = $("#user").val(); // Username
|
||||
var pass = $("#pass").val(); // Password
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'user': user,
|
||||
'pass': pass
|
||||
});
|
||||
|
||||
userName = user;
|
||||
|
||||
httpRequest('POST', 'api-login/login', jsonBody, 'Login WRONG', function successCallback(response) {
|
||||
console.warn(userName + ' login');
|
||||
$("#name-user").text(user);
|
||||
$("#not-logged").hide();
|
||||
$("#logged").show();
|
||||
// Random nickName and session
|
||||
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
|
||||
$("#participantName").val("Participant " + Math.floor(Math.random() * 100));
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-login/login',
|
||||
{user: user, pass: pass},
|
||||
'Login WRONG',
|
||||
(response) => {
|
||||
$("#name-user").text(user);
|
||||
$("#not-logged").hide();
|
||||
$("#logged").show();
|
||||
// Random nickName and session
|
||||
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
|
||||
$("#nickName").val("Participant " + Math.floor(Math.random() * 100));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
httpRequest('GET', 'api-login/logout', null, 'Logout WRONG', function successCallback(response) {
|
||||
console.warn(userName + ' logout');
|
||||
$("#not-logged").show();
|
||||
$("#logged").hide();
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-login/logout',
|
||||
{},
|
||||
'Logout WRONG',
|
||||
(response) => {
|
||||
$("#not-logged").show();
|
||||
$("#logged").hide();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
function getToken(callback) {
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
nickName = $("#participantName").val(); // Nickname chosen by the user
|
||||
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-sessions/get-token',
|
||||
{sessionName: sessionName},
|
||||
'Request of TOKEN gone WRONG:',
|
||||
(response) => {
|
||||
token = response[0]; // Get token from response
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
callback(token); // Continue the join operation
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn(userName + " correctly removed from session");
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-sessions/remove-user',
|
||||
{sessionName: sessionName, token: token},
|
||||
'User couldn\'t be removed from session',
|
||||
(response) => {
|
||||
console.warn("You have been removed from session " + sessionName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function httpRequest(method, url, body, errorMsg, callback) {
|
||||
function httpPostRequest(url, body, errorMsg, callback) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open(method, url, true);
|
||||
http.open('POST', url, true);
|
||||
http.setRequestHeader('Content-type', 'application/json');
|
||||
http.addEventListener('readystatechange', processRequest, false);
|
||||
http.send(body);
|
||||
http.send(JSON.stringify(body));
|
||||
|
||||
function processRequest() {
|
||||
if (http.readyState == 4) {
|
||||
@ -209,7 +213,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
|
||||
/* APPLICATION BROWSER METHODS */
|
||||
|
||||
window.onbeforeunload = function () { // Gracefully leave session
|
||||
window.onbeforeunload = () => { // Gracefully leave session
|
||||
if (session) {
|
||||
removeUser();
|
||||
leaveSession();
|
||||
@ -261,9 +265,12 @@ function addClickListener(videoElement, clientData, serverData) {
|
||||
videoElement.addEventListener('click', function () {
|
||||
var mainVideo = $('#main-video video').get(0);
|
||||
if (mainVideo.srcObject !== videoElement.srcObject) {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeOut("fast", () => {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeIn("fast");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -279,7 +286,7 @@ function initMainVideoThumbnail() {
|
||||
$('#main-video video').css("background", "url('images/subscriber-msg.jpg') round");
|
||||
}
|
||||
|
||||
function isPublisher() {
|
||||
function isPublisher(userName) {
|
||||
return userName.includes('publisher');
|
||||
}
|
||||
|
||||
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
@ -88,7 +85,7 @@
|
||||
<form class="form-group" onsubmit="return false">
|
||||
<p>
|
||||
<label>Participant</label>
|
||||
<input class="form-control" type="text" id="participantName" required>
|
||||
<input class="form-control" type="text" id="nickName" required>
|
||||
</p>
|
||||
<p>
|
||||
<label>Session</label>
|
||||
@ -130,4 +127,4 @@
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-js-java/src/main/resources/static/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-js-java/src/main/resources/static/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -17,9 +17,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.17.2",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"openvidu-node-client": "1.7.0"
|
||||
"body-parser": "1.18.2",
|
||||
"express": "4.16.3",
|
||||
"express-session": "1.15.6",
|
||||
"openvidu-node-client": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,75 +1,84 @@
|
||||
var OV;
|
||||
var session;
|
||||
|
||||
var sessionId;
|
||||
var token;
|
||||
var nickName;
|
||||
var userName;
|
||||
var sessionName;
|
||||
var sessionName; // Name of the video session the user will connect to
|
||||
var token; // Token retrieved from OpenVidu Server
|
||||
|
||||
|
||||
/* OPENVIDU METHODS */
|
||||
|
||||
function joinSession() {
|
||||
getSessionIdAndToken(function () {
|
||||
getToken((token) => {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
session = OV.initSession(sessionId);
|
||||
|
||||
// --- 2) Init a session ---
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
|
||||
// Add a new <p> element for the user's name and nickname just below its video
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
});
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
session.on('streamDestroyed', (event) => {
|
||||
// Delete the HTML element with the user's name and nickname
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
var nickName = $("#nickName").val();
|
||||
session.connect(token, { clientData: nickName })
|
||||
.then(() => {
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
|
||||
var userName = $("#user").val();
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
|
||||
// Here we check somehow if the user has at least 'PUBLISHER' role before
|
||||
// Here we check somehow if the user has 'PUBLISHER' role before
|
||||
// trying to publish its stream. Even if someone modified the client's code and
|
||||
// published the stream, it wouldn't work if the token sent in Session.connect
|
||||
// method doesn't belong to a 'PUBLIHSER' role
|
||||
if (isPublisher()) {
|
||||
// method is not recognized as 'PUBLIHSER' role by OpenVidu Server
|
||||
if (isPublisher(userName)) {
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
// Init the main video with ours and append our data
|
||||
var userData = {
|
||||
nickName: nickName,
|
||||
@ -77,11 +86,11 @@ function joinSession() {
|
||||
};
|
||||
initMainVideo(event.element, userData);
|
||||
appendUserData(event.element, userData);
|
||||
$(event.element).prop('muted', true); // Mute lcoal video
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
@ -89,22 +98,18 @@ function joinSession() {
|
||||
console.warn('You don\'t have permissions to publish');
|
||||
initMainVideoThumbnail(); // Show SUBSCRIBER message in main video
|
||||
}
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// 6) Leave the session by calling 'disconnect' method over the Session object
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
session = null;
|
||||
@ -125,67 +130,66 @@ function leaveSession() {
|
||||
function logIn() {
|
||||
var user = $("#user").val(); // Username
|
||||
var pass = $("#pass").val(); // Password
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'user': user,
|
||||
'pass': pass
|
||||
});
|
||||
|
||||
userName = user;
|
||||
|
||||
httpRequest('POST', '/api-login/login', jsonBody, 'Login WRONG', function successCallback(response){ // Send POST request
|
||||
console.warn(userName + ' login');
|
||||
$("#name-user").text(user);
|
||||
$("#not-logged").hide();
|
||||
$("#logged").show();
|
||||
// Random nickName and session
|
||||
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
|
||||
$("#participantName").val("Participant " + Math.floor(Math.random() * 100));
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-login/login',
|
||||
{user: user, pass: pass},
|
||||
'Login WRONG',
|
||||
(response) => {
|
||||
$("#name-user").text(user);
|
||||
$("#not-logged").hide();
|
||||
$("#logged").show();
|
||||
// Random nickName and session
|
||||
$("#sessionName").val("Session " + Math.floor(Math.random() * 10));
|
||||
$("#nickName").val("Participant " + Math.floor(Math.random() * 100));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
httpRequest('GET', 'api-login/logout', null, 'Logout WRONG', function successCallback(response) {
|
||||
console.warn(userName + ' logout');
|
||||
$("#not-logged").show();
|
||||
$("#logged").hide();
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-login/logout',
|
||||
{},
|
||||
'Logout WRONG',
|
||||
(response) => {
|
||||
$("#not-logged").show();
|
||||
$("#logged").hide();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
function getToken(callback) {
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
nickName = $("#participantName").val(); // Nickname chosen by the user
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-sessions/get-token',
|
||||
{sessionName: sessionName},
|
||||
'Request of TOKEN gone WRONG:',
|
||||
(response) => {
|
||||
token = response[0]; // Get token from response
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
callback(token); // Continue the join operation
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api-sessions/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn(userName + " correctly removed from session");
|
||||
});
|
||||
httpPostRequest(
|
||||
'api-sessions/remove-user',
|
||||
{sessionName: sessionName, token: token},
|
||||
'User couldn\'t be removed from session',
|
||||
(response) => {
|
||||
console.warn("You have been removed from session " + sessionName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function httpRequest(method, url, body, errorMsg, callback) {
|
||||
function httpPostRequest(url, body, errorMsg, callback) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open(method, url, true);
|
||||
http.open('POST', url, true);
|
||||
http.setRequestHeader('Content-type', 'application/json');
|
||||
http.addEventListener('readystatechange', processRequest, false);
|
||||
http.send(body);
|
||||
http.send(JSON.stringify(body));
|
||||
|
||||
function processRequest() {
|
||||
if (http.readyState == 4) {
|
||||
@ -209,7 +213,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
|
||||
/* APPLICATION BROWSER METHODS */
|
||||
|
||||
window.onbeforeunload = function () { // Gracefully leave session
|
||||
window.onbeforeunload = () => { // Gracefully leave session
|
||||
if (session) {
|
||||
removeUser();
|
||||
leaveSession();
|
||||
@ -261,9 +265,12 @@ function addClickListener(videoElement, clientData, serverData) {
|
||||
videoElement.addEventListener('click', function () {
|
||||
var mainVideo = $('#main-video video').get(0);
|
||||
if (mainVideo.srcObject !== videoElement.srcObject) {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeOut("fast", () => {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeIn("fast");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -279,7 +286,7 @@ function initMainVideoThumbnail() {
|
||||
$('#main-video video').css("background", "url('images/subscriber-msg.jpg') round");
|
||||
}
|
||||
|
||||
function isPublisher() {
|
||||
function isPublisher(userName) {
|
||||
return userName.includes('publisher');
|
||||
}
|
||||
|
||||
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
@ -88,7 +85,7 @@
|
||||
<form class="form-group" onsubmit="return false">
|
||||
<p>
|
||||
<label>Participant</label>
|
||||
<input class="form-control" type="text" id="participantName" required>
|
||||
<input class="form-control" type="text" id="nickName" required>
|
||||
</p>
|
||||
<p>
|
||||
<label>Session</label>
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-js-node/public/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-js-node/public/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -63,13 +63,13 @@ var OPENVIDU_URL = process.argv[2];
|
||||
// Environment variable: secret shared with our OpenVidu server
|
||||
var OPENVIDU_SECRET = process.argv[3];
|
||||
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
// Entrypoint to OpenVidu Node Client SDK
|
||||
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
var mapSessionNameSession = {};
|
||||
// Collection to pair sessionId's (identifiers of Session objects) and tokens
|
||||
var mapSessionIdTokens = {};
|
||||
// Collection to pair session names with OpenVidu Session objects
|
||||
var mapSessions = {};
|
||||
// Collection to pair session names with tokens
|
||||
var mapSessionNamesTokens = {};
|
||||
|
||||
console.log("App listening on port 5000");
|
||||
|
||||
@ -81,7 +81,7 @@ console.log("App listening on port 5000");
|
||||
|
||||
// Login
|
||||
app.post('/api-login/login', function (req, res) {
|
||||
|
||||
|
||||
// Retrieve params from POST body
|
||||
var user = req.body.user;
|
||||
var pass = req.body.pass;
|
||||
@ -102,91 +102,89 @@ app.post('/api-login/login', function (req, res) {
|
||||
});
|
||||
|
||||
// Logout
|
||||
app.get('/api-login/logout', function (req, res) {
|
||||
app.post('/api-login/logout', function (req, res) {
|
||||
console.log("'" + req.session.loggedUser + "' has logged out");
|
||||
req.session.destroy();
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
// Get sessionId and token (add new user to session)
|
||||
app.post('/api-sessions/get-sessionid-token', function (req, res) {
|
||||
// Get token (add new user to session)
|
||||
app.post('/api-sessions/get-token', function (req, res) {
|
||||
if (!isLogged(req.session)) {
|
||||
req.session.destroy();
|
||||
res.status(401).send('User not logged');
|
||||
} else {
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
var sessionName = req.body.session;
|
||||
|
||||
// The video-call to connect
|
||||
var sessionName = req.body.sessionName;
|
||||
|
||||
// Role associated to this user
|
||||
var role = users.find(u => (u.user === req.session.loggedUser)).role;
|
||||
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the req.session object on login
|
||||
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
|
||||
var serverData = JSON.stringify({ serverData: req.session.loggedUser });
|
||||
|
||||
console.log("Getting a token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
var tokenOptions = new TokenOptions.Builder()
|
||||
.data(serverData)
|
||||
.role(role)
|
||||
.build();
|
||||
var tokenOptions = {
|
||||
data: serverData,
|
||||
role: role
|
||||
};
|
||||
|
||||
if (mapSessionNameSession[sessionName]) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
if (mapSessions[sessionName]) {
|
||||
// Session already exists
|
||||
console.log('Existing session ' + sessionName);
|
||||
|
||||
|
||||
// Get the existing Session from the collection
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
|
||||
var mySession = mapSessions[sessionName];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Get the existing sessionId
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
mySession.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Return the token to the client
|
||||
res.status(200).send({
|
||||
0: sessionId,
|
||||
1: token
|
||||
0: token
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
} else { // New session: return a new sessionId and a new token
|
||||
} else {
|
||||
// New session
|
||||
console.log('New session ' + sessionName);
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
var mySession = OV.createSession();
|
||||
|
||||
// Get the sessionId asynchronously
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
// Create a new OpenVidu Session asynchronously
|
||||
OV.createSession()
|
||||
.then(session => {
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessions[sessionName] = session;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName] = [];
|
||||
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
res.status(200).send({
|
||||
0: sessionId,
|
||||
1: token
|
||||
});
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
session.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Return the Token to the client
|
||||
res.status(200).send({
|
||||
0: token
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -203,35 +201,26 @@ app.post('/api-sessions/remove-user', function (req, res) {
|
||||
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
|
||||
|
||||
// If the session exists
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
if (mySession) {
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
var tokens = mapSessionIdTokens[sessionId];
|
||||
if (tokens) {
|
||||
var index = tokens.indexOf(token);
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed!
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + mapSessionIdTokens[sessionId].toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
if (mapSessionIdTokens[sessionId].length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessionNameSession[sessionName];
|
||||
}
|
||||
res.status(200).send();
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSIONID wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
});
|
||||
if (mapSessions[sessionName] && mapSessionNamesTokens[sessionName]) {
|
||||
var tokens = mapSessionNamesTokens[sessionName];
|
||||
var index = tokens.indexOf(token);
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + tokens.toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
if (tokens.length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessions[sessionName];
|
||||
}
|
||||
res.status(200).send();
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSION does not exist';
|
||||
console.log(msg);
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -20,18 +20,19 @@ import io.openvidu.java.client.TokenOptions;
|
||||
@Controller
|
||||
public class SessionController {
|
||||
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
// OpenVidu object as entrypoint of the SDK
|
||||
private OpenVidu openVidu;
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
|
||||
// Collection to pair sessionId's and tokens (the inner Map pairs tokens and role associated)
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
|
||||
// Collection to pair session names and tokens (the inner Map pairs tokens and role associated)
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionNamesTokens = new ConcurrentHashMap<>();
|
||||
|
||||
// URL where our OpenVidu server is listening
|
||||
private String OPENVIDU_URL;
|
||||
// Secret shared with our OpenVidu server
|
||||
private String SECRET;
|
||||
|
||||
|
||||
public SessionController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
|
||||
this.SECRET = secret;
|
||||
@ -61,25 +62,21 @@ public class SessionController {
|
||||
TokenOptions tokenOptions = new TokenOptions.Builder().data(serverData).role(role).build();
|
||||
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
// Session already exists
|
||||
System.out.println("Existing session " + sessionName);
|
||||
try {
|
||||
|
||||
// Get the existing sessionId from our collection with
|
||||
// the sessionName param ("TUTORIAL")
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
|
||||
|
||||
|
||||
// Update our collection storing the new token
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Add all the needed attributes to the template
|
||||
model.addAttribute("sessionId", sessionId);
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
model.addAttribute("token", token);
|
||||
model.addAttribute("nickName", clientData);
|
||||
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
|
||||
// Return session.html template
|
||||
return "session";
|
||||
@ -90,28 +87,25 @@ public class SessionController {
|
||||
return "dashboard";
|
||||
}
|
||||
} else {
|
||||
// New session: return a new sessionId and a new token
|
||||
// New session
|
||||
System.out.println("New session " + sessionName);
|
||||
try {
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
Session session = this.openVidu.createSession();
|
||||
// Get the sessionId
|
||||
String sessionId = session.getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = session.generateToken(tokenOptions);
|
||||
|
||||
// Store the session and the token in our collections
|
||||
this.mapSessions.put(sessionName, session);
|
||||
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.put(sessionName, new ConcurrentHashMap<>());
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Add all the needed attributes to the template
|
||||
model.addAttribute("sessionId", sessionId);
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
model.addAttribute("token", token);
|
||||
model.addAttribute("nickName", clientData);
|
||||
model.addAttribute("userName", httpSession.getAttribute("loggedUser"));
|
||||
model.addAttribute("sessionName", sessionName);
|
||||
|
||||
// Return session.html template
|
||||
return "session";
|
||||
@ -135,31 +129,24 @@ public class SessionController {
|
||||
}
|
||||
System.out.println("Removing user | sessioName=" + sessionName + ", token=" + token);
|
||||
|
||||
// If the session exists
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
|
||||
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
|
||||
// If the token exists
|
||||
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
|
||||
System.out.println(sessionName + ": " + this.mapSessionIdsTokens.get(sessionId).toString());
|
||||
// User left the session
|
||||
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()) {
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
System.out.println(sessionName + " empty!");
|
||||
}
|
||||
return "redirect:/dashboard";
|
||||
} else {
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return "redirect:/dashboard";
|
||||
// If the session exists ("TUTORIAL" in this case)
|
||||
if (this.mapSessions.get(sessionName) != null && this.mapSessionNamesTokens.get(sessionName) != null) {
|
||||
|
||||
// If the token exists
|
||||
if (this.mapSessionNamesTokens.get(sessionName).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionNamesTokens.get(sessionName).isEmpty()) {
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return "redirect:/dashboard";
|
||||
|
||||
} else {
|
||||
// The SESSIONID wasn't valid
|
||||
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return "redirect:/dashboard";
|
||||
}
|
||||
|
||||
} else {
|
||||
// The SESSION does not exist
|
||||
System.out.println("Problems in the app server: the SESSION does not exist");
|
||||
|
||||
@ -5,5 +5,5 @@ server.ssl.key-store-password: openvidu
|
||||
server.ssl.key-store-type: JKS
|
||||
server.ssl.key-alias: openvidu-selfsigned
|
||||
|
||||
openvidu.url: https://localhost:8443/
|
||||
openvidu.url: https://localhost:4443/
|
||||
openvidu.secret: MY_SECRET
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-mvc-java/src/main/resources/static/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-mvc-java/src/main/resources/static/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon"></link>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous"></link>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"></link>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"></link>
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen"></link>
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -25,10 +22,15 @@
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><img class="demo-logo" src="images/openvidu_vert_white_bg_trans_cropped.png"/> MVC Java</a>
|
||||
<a class="navbar-brand" href="/">
|
||||
<img class="demo-logo" src="images/openvidu_vert_white_bg_trans_cropped.png" /> MVC Java</a>
|
||||
<a class="navbar-brand nav-icon" href="https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-mvc-java" title="GitHub Repository"
|
||||
target="_blank"><i class="fa fa-github" aria-hidden="true"></i></a>
|
||||
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-mvc-java/" title="Documentation" target="_blank"><i class="fa fa-book" aria-hidden="true"></i></a>
|
||||
target="_blank">
|
||||
<i class="fa fa-github" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-mvc-java/" title="Documentation" target="_blank">
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@ -58,7 +60,9 @@
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="text-muted">OpenVidu © 2017</div>
|
||||
<a href="http://www.openvidu.io/" target="_blank"><img class="openvidu-logo" src="images/openvidu_globe_bg_transp_cropped.png"/></a>
|
||||
<a href="http://www.openvidu.io/" target="_blank">
|
||||
<img class="openvidu-logo" src="images/openvidu_globe_bg_transp_cropped.png" />
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@ -67,32 +71,32 @@
|
||||
<script th:inline="javascript">
|
||||
|
||||
// Get all the attributes from the template in Thymeleaf style
|
||||
var sessionId = [[${sessionId}]];
|
||||
var token = [[${token}]];
|
||||
var nickName = [[${nickName}]];
|
||||
var userName = [[${userName}]];
|
||||
var sessionName = [[${sessionName}]];
|
||||
var sessionName = [[${ sessionName }]];
|
||||
var token = [[${ token }]];
|
||||
var nickName = [[${ nickName }]];
|
||||
var userName = [[${ userName }]];
|
||||
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' +
|
||||
sessionId + ", TOKEN:" + token + ")");
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
var OV = new OpenVidu();
|
||||
var session = OV.initSession(sessionId);
|
||||
OV = new OpenVidu();
|
||||
|
||||
// --- 2) Init a session ---
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
@ -100,38 +104,47 @@
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
session.on('streamDestroyed', (event) => {
|
||||
// Delete the HTML element with the user's name and nickname
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
|
||||
session.connect(token, { clientData: nickName })
|
||||
.then(() => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
// Here we check somehow if the user has at least 'PUBLISHER' role before
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
|
||||
// Here we check somehow if the user has 'PUBLISHER' role before
|
||||
// trying to publish its stream. Even if someone modified the client's code and
|
||||
// published the stream, it wouldn't work if the token sent in Session.connect
|
||||
// method doesn't belong to a 'PUBLIHSER' role
|
||||
// method is not recognized as 'PUBLIHSER' role by OpenVidu Server
|
||||
if (isPublisher()) {
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
// Init the main video with ours and append our data
|
||||
var userData = {
|
||||
nickName: nickName,
|
||||
@ -143,7 +156,7 @@
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
@ -151,15 +164,15 @@
|
||||
console.warn('You don\'t have permissions to publish');
|
||||
initMainVideoThumbnail(); // Show SUBSCRIBER message in main video
|
||||
}
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
session.disconnect();
|
||||
}
|
||||
|
||||
@ -207,9 +220,12 @@
|
||||
videoElement.addEventListener('click', function () {
|
||||
var mainVideo = $('#main-video video').get(0);
|
||||
if (mainVideo.srcObject !== videoElement.srcObject) {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeOut("fast", () => {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeIn("fast");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -17,10 +17,10 @@
|
||||
},
|
||||
"homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.17.2",
|
||||
"ejs": "^2.5.6",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"openvidu-node-client": "1.7.0"
|
||||
"body-parser": "1.18.2",
|
||||
"ejs": "2.6.1",
|
||||
"express": "4.16.3",
|
||||
"express-session": "1.15.6",
|
||||
"openvidu-node-client": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-mvc-node/public/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-mvc-node/public/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -64,13 +64,13 @@ var OPENVIDU_URL = process.argv[2];
|
||||
// Environment variable: secret shared with our OpenVidu server
|
||||
var OPENVIDU_SECRET = process.argv[3];
|
||||
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
// Entrypoint to OpenVidu Node Client SDK
|
||||
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
var mapSessionNameSession = {};
|
||||
// Collection to pair sessionId's (identifiers of Session objects) and tokens
|
||||
var mapSessionIdTokens = {};
|
||||
// Collection to pair session names with OpenVidu Session objects
|
||||
var mapSessions = {};
|
||||
// Collection to pair session names with tokens
|
||||
var mapSessionNamesTokens = {};
|
||||
|
||||
console.log("App listening on port 5000");
|
||||
|
||||
@ -103,36 +103,36 @@ app.get('/dashboard', dashboardController);
|
||||
|
||||
function dashboardController(req, res) {
|
||||
|
||||
// Check if the user is already logged in
|
||||
if (isLogged(req.session)) {
|
||||
// User is already logged. Immediately return dashboard
|
||||
user = req.session.loggedUser;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else {
|
||||
// User wasn't logged and wants to
|
||||
|
||||
// Retrieve params from POST body
|
||||
var user = req.body.user;
|
||||
// Check if the user is already logged in
|
||||
if (isLogged(req.session)) {
|
||||
// User is already logged. Immediately return dashboard
|
||||
user = req.session.loggedUser;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else {
|
||||
// User wasn't logged and wants to
|
||||
|
||||
// Retrieve params from POST body
|
||||
var user = req.body.user;
|
||||
var pass = req.body.pass;
|
||||
console.log("Logging in | {user, pass}={" + user + ", " + pass + "}");
|
||||
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
// Validate session and return OK
|
||||
|
||||
if (login(user, pass)) { // Correct user-pass
|
||||
// Validate session and return OK
|
||||
// Value stored in req.session allows us to identify the user in future requests
|
||||
console.log("'" + user + "' has logged in");
|
||||
req.session.loggedUser = user;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else { // Wrong user-pass
|
||||
req.session.loggedUser = user;
|
||||
res.render('dashboard.ejs', {
|
||||
user: user
|
||||
});
|
||||
} else { // Wrong user-pass
|
||||
// Invalidate session and return index template
|
||||
console.log("'" + user + "' invalid credentials");
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
}
|
||||
}
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.post('/session', (req, res) => {
|
||||
@ -140,9 +140,9 @@ app.post('/session', (req, res) => {
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
} else {
|
||||
// The nickname sent by the client
|
||||
// The nickname sent by the client
|
||||
var clientData = req.body.data;
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
// The video-call to connect
|
||||
var sessionName = req.body.sessionname;
|
||||
|
||||
// Role associated to this user
|
||||
@ -150,77 +150,76 @@ app.post('/session', (req, res) => {
|
||||
|
||||
// Optional data to be passed to other users when this user connects to the video-call
|
||||
// In this case, a JSON with the value we stored in the req.session object on login
|
||||
var serverData = '{"serverData": "' + req.session.loggedUser + '"}';
|
||||
|
||||
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
var serverData = JSON.stringify({ serverData: req.session.loggedUser });
|
||||
|
||||
console.log("Getting a token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
var tokenOptions = new TokenOptions.Builder()
|
||||
.data(serverData)
|
||||
.role(role)
|
||||
.build();
|
||||
var tokenOptions = {
|
||||
data: serverData,
|
||||
role: role
|
||||
};
|
||||
|
||||
if (mapSessionNameSession[sessionName]) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
if (mapSessions[sessionName]) {
|
||||
// Session already exists
|
||||
console.log('Existing session ' + sessionName);
|
||||
|
||||
|
||||
// Get the existing Session from the collection
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
|
||||
var mySession = mapSessions[sessionName];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Get the existing sessionId
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
mySession.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Return session template with all the needed attributes
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
res.render('session.ejs', {
|
||||
sessionId: sessionId,
|
||||
sessionId: mySession.getSessionId(),
|
||||
token: token,
|
||||
nickName: clientData,
|
||||
userName: req.session.loggedUser,
|
||||
sessionName: sessionName
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
} else { // New session: return a new sessionId and a new token
|
||||
} else {
|
||||
// New session
|
||||
console.log('New session ' + sessionName);
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
var mySession = OV.createSession();
|
||||
|
||||
// Get the sessionId asynchronously
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
// Create a new OpenVidu Session asynchronously
|
||||
OV.createSession()
|
||||
.then(session => {
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessions[sessionName] = session;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName] = [];
|
||||
|
||||
// Return session template with all the needed attributes
|
||||
res.render('session.ejs', {
|
||||
sessionId: sessionId,
|
||||
token: token,
|
||||
nickName: clientData,
|
||||
userName: req.session.loggedUser,
|
||||
sessionName: sessionName
|
||||
});
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
session.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Return session template with all the needed attributes
|
||||
res.render('session.ejs', {
|
||||
sessionName: sessionName,
|
||||
token: token,
|
||||
nickName: clientData,
|
||||
userName: req.session.loggedUser,
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -234,41 +233,32 @@ app.post('/leave-session', (req, res) => {
|
||||
var sessionName = req.body.sessionname;
|
||||
var token = req.body.token;
|
||||
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
|
||||
|
||||
|
||||
// If the session exists
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
if (mySession) {
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
var tokens = mapSessionIdTokens[sessionId];
|
||||
if (tokens) {
|
||||
var index = tokens.indexOf(token);
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed!
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + mapSessionIdTokens[sessionId].toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.redirect('/dashboard');
|
||||
}
|
||||
if (mapSessionIdTokens[sessionId].length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessionNameSession[sessionName];
|
||||
}
|
||||
res.redirect('/dashboard');
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSIONID wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.redirect('/dashboard');
|
||||
}
|
||||
});
|
||||
if (mapSessions[sessionName] && mapSessionNamesTokens[sessionName]) {
|
||||
var tokens = mapSessionNamesTokens[sessionName];
|
||||
var index = tokens.indexOf(token);
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + tokens.toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.redirect('/dashboard');
|
||||
}
|
||||
if (tokens.length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessions[sessionName];
|
||||
}
|
||||
res.redirect('/dashboard');
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSION does not exist';
|
||||
console.log(msg);
|
||||
res.redirect('/dashboard');
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon"></link>
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous"></link>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"></link>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"></link>
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen"></link>
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -25,10 +22,15 @@
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="/"><img class="demo-logo" src="images/openvidu_vert_white_bg_trans_cropped.png"/> MVC Node</a>
|
||||
<a class="navbar-brand" href="/">
|
||||
<img class="demo-logo" src="images/openvidu_vert_white_bg_trans_cropped.png" /> MVC Node</a>
|
||||
<a class="navbar-brand nav-icon" href="https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-mvc-node" title="GitHub Repository"
|
||||
target="_blank"><i class="fa fa-github" aria-hidden="true"></i></a>
|
||||
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-mvc-node/" title="Documentation" target="_blank"><i class="fa fa-book" aria-hidden="true"></i></a>
|
||||
target="_blank">
|
||||
<i class="fa fa-github" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="navbar-brand nav-icon" href="http://www.openvidu.io/docs/tutorials/openvidu-mvc-node/" title="Documentation" target="_blank">
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@ -58,7 +60,9 @@
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="text-muted">OpenVidu © 2017</div>
|
||||
<a href="http://www.openvidu.io/" target="_blank"><img class="openvidu-logo" src="images/openvidu_globe_bg_transp_cropped.png"/></a>
|
||||
<a href="http://www.openvidu.io/" target="_blank">
|
||||
<img class="openvidu-logo" src="images/openvidu_globe_bg_transp_cropped.png" />
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@ -66,71 +70,80 @@
|
||||
|
||||
<script>
|
||||
// Get all the attributes from the template in EJS style
|
||||
var sessionId = <%- JSON.stringify(sessionId) %>;
|
||||
var sessionName = <%- JSON.stringify(sessionName) %>;
|
||||
var token = <%- JSON.stringify(token) %>;
|
||||
var nickName = <%- JSON.stringify(nickName) %>;
|
||||
var userName = <%- JSON.stringify(userName) %>;
|
||||
var sessionName = <%- JSON.stringify(sessionName) %>;
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' +
|
||||
sessionId + ", TOKEN:" + token + ")");
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
|
||||
var OV = new OpenVidu();
|
||||
var session = OV.initSession(sessionId);
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
// --- 2) Init a session ---
|
||||
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname just below its video
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
appendUserData(event.element, subscriber.stream.connection);
|
||||
});
|
||||
});
|
||||
|
||||
// On every Stream destroyed...
|
||||
session.on('streamDestroyed', function (event) {
|
||||
session.on('streamDestroyed', (event) => {
|
||||
// Delete the HTML element with the user's name and nickname
|
||||
removeUserData(event.stream.connection);
|
||||
});
|
||||
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
session.connect(token, { clientData: nickName })
|
||||
.then(() => {
|
||||
|
||||
session.connect(token, '{"clientData": "' + nickName + '"}', function (error) {
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
// Here we check somehow if the user has at least 'PUBLISHER' role before
|
||||
|
||||
// Here we check somehow if the user has 'PUBLISHER' role before
|
||||
// trying to publish its stream. Even if someone modified the client's code and
|
||||
// published the stream, it wouldn't work if the token sent in Session.connect
|
||||
// method doesn't belong to a 'PUBLIHSER' role
|
||||
// method is not recognized as 'PUBLIHSER' role by OpenVidu Server
|
||||
if (isPublisher()) {
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
// Init the main video with ours and append our data
|
||||
var userData = {
|
||||
nickName: nickName,
|
||||
@ -142,23 +155,23 @@
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
console.warn('You don\'t have permissions to publish');
|
||||
initMainVideoThumbnail(); // Show SUBSCRIBER message in main video
|
||||
}
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// --- 6) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
session.disconnect();
|
||||
}
|
||||
|
||||
@ -206,9 +219,12 @@
|
||||
videoElement.addEventListener('click', function () {
|
||||
var mainVideo = $('#main-video video').get(0);
|
||||
if (mainVideo.srcObject !== videoElement.srcObject) {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeOut("fast", () => {
|
||||
$('#main-video p.nickName').html(clientData);
|
||||
$('#main-video p.userName').html(serverData);
|
||||
mainVideo.srcObject = videoElement.srcObject;
|
||||
$('#main-video').fadeIn("fast");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@
|
||||
<dependency>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>1.8.0</version>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package io.openvidu.js.java;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
@ -16,9 +18,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.openvidu.java.client.Archive;
|
||||
import io.openvidu.java.client.Recording;
|
||||
import io.openvidu.java.client.OpenVidu;
|
||||
import io.openvidu.java.client.OpenViduException;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.Session;
|
||||
import io.openvidu.java.client.TokenOptions;
|
||||
import io.openvidu.java.client.OpenViduRole;
|
||||
@ -27,13 +30,19 @@ import io.openvidu.java.client.OpenViduRole;
|
||||
@RequestMapping("/api")
|
||||
public class MyRestController {
|
||||
|
||||
OpenVidu openVidu;
|
||||
// OpenVidu object as entrypoint of the SDK
|
||||
private OpenVidu openVidu;
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
private Map<String, Session> mapSessions = new ConcurrentHashMap<>();
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionIdsTokens = new ConcurrentHashMap<>();
|
||||
// Collection to pair session names and tokens (the inner Map pairs tokens and role associated)
|
||||
private Map<String, Map<String, OpenViduRole>> mapSessionNamesTokens = new ConcurrentHashMap<>();
|
||||
// Collection to pair session names and recording objects
|
||||
private Map<String, Boolean> sessionRecordings = new ConcurrentHashMap<>();
|
||||
|
||||
// URL where our OpenVidu server is listening
|
||||
private String OPENVIDU_URL;
|
||||
// Secret shared with our OpenVidu server
|
||||
private String SECRET;
|
||||
|
||||
public MyRestController(@Value("${openvidu.secret}") String secret, @Value("${openvidu.url}") String openviduUrl) {
|
||||
@ -46,15 +55,15 @@ public class MyRestController {
|
||||
/*** Session API ***/
|
||||
/*******************/
|
||||
|
||||
@RequestMapping(value = "/get-sessionid-token", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> getSessionIdToken(@RequestBody String sessionNameParam) throws ParseException {
|
||||
@RequestMapping(value = "/get-token", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> getToken(@RequestBody String sessionNameParam) throws ParseException {
|
||||
|
||||
System.out.println("Getting sessionId and token | {sessionName}=" + sessionNameParam);
|
||||
|
||||
JSONObject sessionJSON = (JSONObject) new JSONParser().parse(sessionNameParam);
|
||||
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
String sessionName = (String) sessionJSON.get("session");
|
||||
String sessionName = (String) sessionJSON.get("sessionName");
|
||||
|
||||
// Role associated to this user
|
||||
OpenViduRole role = OpenViduRole.PUBLISHER;
|
||||
@ -65,22 +74,18 @@ public class MyRestController {
|
||||
JSONObject responseJson = new JSONObject();
|
||||
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
// Session already exists
|
||||
System.out.println("Existing session " + sessionName);
|
||||
try {
|
||||
|
||||
// Get the existing sessionId from our collection with
|
||||
// the sessionName param ("TUTORIAL")
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = this.mapSessions.get(sessionName).generateToken(tokenOptions);
|
||||
|
||||
// Update our collection storing the new token
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
// Prepare the response with the token
|
||||
responseJson.put(0, token);
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
@ -91,25 +96,22 @@ public class MyRestController {
|
||||
}
|
||||
|
||||
} else {
|
||||
// New session: return a new sessionId and token
|
||||
// New session
|
||||
System.out.println("New session " + sessionName);
|
||||
try {
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
Session session = this.openVidu.createSession();
|
||||
// Get the sessionId
|
||||
String sessionId = session.getSessionId();
|
||||
// Generate a new token with the recently created tokenOptions
|
||||
String token = session.generateToken(tokenOptions);
|
||||
|
||||
// Store the session and the token in our collections
|
||||
this.mapSessions.put(sessionName, session);
|
||||
this.mapSessionIdsTokens.put(sessionId, new ConcurrentHashMap<>());
|
||||
this.mapSessionIdsTokens.get(sessionId).put(token, role);
|
||||
this.mapSessionNamesTokens.put(sessionName, new ConcurrentHashMap<>());
|
||||
this.mapSessionNamesTokens.get(sessionName).put(token, role);
|
||||
|
||||
// Prepare the response with the sessionId and the token
|
||||
responseJson.put(0, sessionId);
|
||||
responseJson.put(1, token);
|
||||
responseJson.put(0, token);
|
||||
|
||||
// Return the response to the client
|
||||
return new ResponseEntity<>(responseJson, HttpStatus.OK);
|
||||
@ -131,30 +133,23 @@ public class MyRestController {
|
||||
String sessionName = (String) sessionNameTokenJSON.get("sessionName");
|
||||
String token = (String) sessionNameTokenJSON.get("token");
|
||||
|
||||
// If the session exists ("TUTORIAL" in this case)
|
||||
if (this.mapSessions.get(sessionName) != null) {
|
||||
String sessionId = this.mapSessions.get(sessionName).getSessionId();
|
||||
// If the session exists
|
||||
if (this.mapSessions.get(sessionName) != null && this.mapSessionNamesTokens.get(sessionName) != null) {
|
||||
|
||||
if (this.mapSessionIdsTokens.containsKey(sessionId)) {
|
||||
// If the token exists
|
||||
if (this.mapSessionIdsTokens.get(sessionId).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionIdsTokens.get(sessionId).isEmpty()
|
||||
&& !this.sessionRecordings.containsKey(sessionId)) {
|
||||
// Last user left and recording is not taking place: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
// If the token exists
|
||||
if (this.mapSessionNamesTokens.get(sessionName).remove(token) != null) {
|
||||
// User left the session
|
||||
if (this.mapSessionNamesTokens.get(sessionName).isEmpty()) {
|
||||
// Last user left: session must be removed
|
||||
this.mapSessions.remove(sessionName);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} else {
|
||||
// The SESSIONID wasn't valid
|
||||
System.out.println("Problems in the app server: the SESSIONID wasn't valid");
|
||||
// The TOKEN wasn't valid
|
||||
System.out.println("Problems in the app server: the TOKEN wasn't valid");
|
||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
} else {
|
||||
// The SESSION does not exist
|
||||
System.out.println("Problems in the app server: the SESSION does not exist");
|
||||
@ -174,10 +169,10 @@ public class MyRestController {
|
||||
System.out.println("Starting recording | {sessionId}=" + sessionId);
|
||||
|
||||
try {
|
||||
Archive archive = this.openVidu.startRecording(sessionId);
|
||||
Recording recording = this.openVidu.startRecording(sessionId);
|
||||
this.sessionRecordings.put(sessionId, true);
|
||||
return new ResponseEntity<>(archive, HttpStatus.OK);
|
||||
} catch (OpenViduException e) {
|
||||
return new ResponseEntity<>(getJsonFromRecording(recording), HttpStatus.OK);
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@ -190,10 +185,10 @@ public class MyRestController {
|
||||
System.out.println("Stoping recording | {recordingId}=" + recordingId);
|
||||
|
||||
try {
|
||||
Archive archive = this.openVidu.stopRecording(recordingId);
|
||||
this.sessionRecordings.remove(archive.getSessionId());
|
||||
return new ResponseEntity<>(archive, HttpStatus.OK);
|
||||
} catch (OpenViduException e) {
|
||||
Recording recording = this.openVidu.stopRecording(recordingId);
|
||||
this.sessionRecordings.remove(recording.getSessionId());
|
||||
return new ResponseEntity<>(getJsonFromRecording(recording), HttpStatus.OK);
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@ -208,7 +203,7 @@ public class MyRestController {
|
||||
try {
|
||||
this.openVidu.deleteRecording(recordingId);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
} catch (OpenViduException e) {
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@ -219,9 +214,9 @@ public class MyRestController {
|
||||
System.out.println("Getting recording | {recordingId}=" + recordingId);
|
||||
|
||||
try {
|
||||
Archive archive = this.openVidu.getRecording(recordingId);
|
||||
return new ResponseEntity<>(archive, HttpStatus.OK);
|
||||
} catch (OpenViduException e) {
|
||||
Recording recording = this.openVidu.getRecording(recordingId);
|
||||
return new ResponseEntity<>(getJsonFromRecording(recording), HttpStatus.OK);
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
@ -232,13 +227,15 @@ public class MyRestController {
|
||||
System.out.println("Listing recordings");
|
||||
|
||||
try {
|
||||
List<Archive> archives = this.openVidu.listRecordings();
|
||||
return new ResponseEntity<>(archives, HttpStatus.OK);
|
||||
} catch (OpenViduException e) {
|
||||
List<Recording> recordings = this.openVidu.listRecordings();
|
||||
|
||||
return new ResponseEntity<>(getJsonArrayFromRecordingList(recordings), HttpStatus.OK);
|
||||
} catch (OpenViduJavaClientException | OpenViduHttpException e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ResponseEntity<JSONObject> getErrorResponse(Exception e) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("cause", e.getCause());
|
||||
@ -247,4 +244,30 @@ public class MyRestController {
|
||||
return new ResponseEntity<>(json, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private JSONObject getJsonFromRecording(Recording recording) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("createdAt", recording.getCreatedAt());
|
||||
json.put("duration", recording.getDuration());
|
||||
json.put("hasAudio", recording.hasAudio());
|
||||
json.put("hasVideo", recording.hasVideo());
|
||||
json.put("id", recording.getId());
|
||||
json.put("recordingLayout", recording.getRecordingLayout());
|
||||
json.put("name", recording.getName());
|
||||
json.put("sessionId", recording.getSessionId());
|
||||
json.put("size", recording.getSize());
|
||||
json.put("status", recording.getStatus());
|
||||
json.put("url", recording.getUrl());
|
||||
return json;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private JSONArray getJsonArrayFromRecordingList(Collection<Recording> recordings) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Recording recording : recordings) {
|
||||
array.add(getJsonFromRecording(recording));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,5 +5,5 @@ server.ssl.key-store-password: openvidu
|
||||
server.ssl.key-store-type: JKS
|
||||
server.ssl.key-alias: openvidu-selfsigned
|
||||
|
||||
openvidu.url: https://localhost:8443/
|
||||
openvidu.url: https://localhost:4443/
|
||||
openvidu.secret: MY_SECRET
|
||||
|
||||
@ -1,88 +1,94 @@
|
||||
var OV;
|
||||
var session;
|
||||
|
||||
var sessionId;
|
||||
var token;
|
||||
var sessionName;
|
||||
var token;
|
||||
var numVideos = 0;
|
||||
|
||||
|
||||
/* OPENVIDU METHODS */
|
||||
|
||||
function joinSession() {
|
||||
getSessionIdAndToken(function () {
|
||||
getToken(function () {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
session = OV.initSession(sessionId);
|
||||
|
||||
// --- 2) Init a session ---
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(1);
|
||||
});
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementDestroyed', function (event) {
|
||||
subscriber.on('videoElementDestroyed', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(-1);
|
||||
});
|
||||
});
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token ---
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
session.connect(token, null, function (error) {
|
||||
session.connect(token)
|
||||
.then(() => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
updateNumVideos(1);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
publisher.on('videoElementDestroyed', function (event) {
|
||||
publisher.on('videoElementDestroyed', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(-1);
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
@ -90,7 +96,7 @@ function joinSession() {
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// 6) Leave the session by calling 'disconnect' method over the Session object
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
session = null;
|
||||
@ -106,33 +112,32 @@ function leaveSession() {
|
||||
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
function getToken(callback) {
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/get-token',
|
||||
{sessionName: sessionName},
|
||||
'Request of TOKEN gone WRONG:',
|
||||
(response) => {
|
||||
token = response[0]; // Get token from response
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
callback(token); // Continue the join operation
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn("User correctly removed from session");
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/remove-user',
|
||||
{sessionName: sessionName, token: token},
|
||||
'User couldn\'t be removed from session',
|
||||
(response) => {
|
||||
console.warn("You have been removed from session " + sessionName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function httpRequest(method, url, body, errorMsg, callback) {
|
||||
@ -141,7 +146,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
http.open(method, url, true);
|
||||
http.setRequestHeader('Content-type', 'application/json');
|
||||
http.addEventListener('readystatechange', processRequest, false);
|
||||
http.send(body);
|
||||
http.send(JSON.stringify(body));
|
||||
|
||||
function processRequest() {
|
||||
if (http.readyState == 4) {
|
||||
@ -163,48 +168,69 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
var recordingId;
|
||||
|
||||
function startRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'session': session.sessionId
|
||||
});
|
||||
httpRequest('POST', 'api/recording/start', jsonBody, 'Start recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
recordingId = response.id;
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/recording/start',
|
||||
{session: session.sessionId},
|
||||
'Start recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
recordingId = response.id;
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function stopRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'recording': recordingId
|
||||
});
|
||||
httpRequest('POST', 'api/recording/stop', jsonBody, 'Stop recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/recording/stop',
|
||||
{recording: recordingId},
|
||||
'Stop recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function deleteRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'recording': recordingId
|
||||
});
|
||||
httpRequest('DELETE', 'api/recording/delete', jsonBody, 'Delete recording WRONG', function successCallback() {
|
||||
console.log("DELETE ok");
|
||||
$('#text-area').text("DELETE ok");
|
||||
});
|
||||
httpRequest(
|
||||
'DELETE',
|
||||
'api/recording/delete',
|
||||
{recording: recordingId},
|
||||
'Delete recording WRONG',
|
||||
() => {
|
||||
console.log("DELETE ok");
|
||||
$('#text-area').text("DELETE ok");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getRecording() {
|
||||
httpRequest('GET', 'api/recording/get/' + recordingId, '', 'Get recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'GET',
|
||||
'api/recording/get/' + recordingId,
|
||||
{},
|
||||
'Get recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function listRecordings() {
|
||||
httpRequest('GET', 'api/recording/list', '', 'List recordings WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'GET',
|
||||
'api/recording/list',
|
||||
{},
|
||||
'List recordings WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
@ -7,17 +7,14 @@
|
||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||
crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -17,9 +17,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.17.2",
|
||||
"express": "^4.15.3",
|
||||
"express-session": "^1.15.3",
|
||||
"openvidu-node-client": "1.8.0"
|
||||
"body-parser": "1.18.2",
|
||||
"express": "4.16.3",
|
||||
"openvidu-node-client": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,88 +1,94 @@
|
||||
var OV;
|
||||
var session;
|
||||
|
||||
var sessionId;
|
||||
var token;
|
||||
var sessionName;
|
||||
var token;
|
||||
var numVideos = 0;
|
||||
|
||||
|
||||
/* OPENVIDU METHODS */
|
||||
|
||||
function joinSession() {
|
||||
getSessionIdAndToken(function () {
|
||||
getToken(function () {
|
||||
|
||||
// --- 1) Get an OpenVidu object and init a session with the retrieved sessionId ---
|
||||
// --- 1) Get an OpenVidu object ---
|
||||
|
||||
OV = new OpenVidu();
|
||||
session = OV.initSession(sessionId);
|
||||
|
||||
// --- 2) Init a session ---
|
||||
|
||||
// --- 2) Specify the actions when events take place ---
|
||||
session = OV.initSession();
|
||||
|
||||
// --- 3) Specify the actions when events take place in the session ---
|
||||
|
||||
// On every new Stream received...
|
||||
session.on('streamCreated', function (event) {
|
||||
session.on('streamCreated', (event) => {
|
||||
|
||||
// Subscribe to the Stream to receive it
|
||||
// HTML video will be appended to element with 'video-container' id
|
||||
var subscriber = session.subscribe(event.stream, 'video-container');
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementCreated', function (event) {
|
||||
subscriber.on('videoElementCreated', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(1);
|
||||
});
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
subscriber.on('videoElementDestroyed', function (event) {
|
||||
subscriber.on('videoElementDestroyed', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(-1);
|
||||
});
|
||||
});
|
||||
|
||||
// --- 3) Connect to the session passing the retrieved token ---
|
||||
// --- 4) Connect to the session passing the retrieved token and some more data from
|
||||
// the client (in this case a JSON with the nickname chosen by the user) ---
|
||||
|
||||
session.connect(token, null, function (error) {
|
||||
session.connect(token)
|
||||
.then(() => {
|
||||
|
||||
// If the connection is successful, initialize a publisher and publish to the session
|
||||
if (!error) {
|
||||
// --- 5) Set page layout for active call ---
|
||||
|
||||
// --- 4) Get your own camera stream ---
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
|
||||
// --- 6) Get your own camera stream ---
|
||||
|
||||
var publisher = OV.initPublisher('video-container', {
|
||||
audio: true, // Whether you want to transmit audio or not
|
||||
video: true, // Whether you want to transmit video or not
|
||||
audioActive: true, // Whether you want to start the publishing with your audio unmuted or muted
|
||||
videoActive: true, // Whether you want to start the publishing with your video enabled or disabled
|
||||
quality: 'MEDIUM', // The quality of your video ('LOW', 'MEDIUM', 'HIGH')
|
||||
screen: false // true to get your screen as video source instead of your camera
|
||||
audioSource: undefined, // The source of audio. If undefined default microphone
|
||||
videoSource: undefined, // The source of video. If undefined default webcam
|
||||
publishAudio: true, // Whether you want to start publishing with your audio unmuted or not
|
||||
publishVideo: true, // Whether you want to start publishing with your video enabled or not
|
||||
resolution: '640x480', // The resolution of your video
|
||||
frameRate: 30, // The frame rate of your video
|
||||
insertMode: 'APPEND', // How the video is inserted in the target element 'video-container'
|
||||
mirror: false // Whether to mirror your local video or not
|
||||
});
|
||||
|
||||
// --- 7) Specify the actions when events take place in our publisher ---
|
||||
|
||||
// When our HTML video has been added to DOM...
|
||||
publisher.on('videoElementCreated', function (event) {
|
||||
publisher.on('videoElementCreated', (event) => {
|
||||
updateNumVideos(1);
|
||||
$(event.element).prop('muted', true); // Mute local video
|
||||
});
|
||||
|
||||
// When the HTML video has been appended to DOM...
|
||||
publisher.on('videoElementDestroyed', function (event) {
|
||||
publisher.on('videoElementDestroyed', (event) => {
|
||||
// Add a new HTML element for the user's name and nickname over its video
|
||||
updateNumVideos(-1);
|
||||
});
|
||||
|
||||
|
||||
// --- 5) Publish your stream ---
|
||||
// --- 8) Publish your stream ---
|
||||
|
||||
session.publish(publisher);
|
||||
|
||||
} else {
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn('There was an error connecting to the session:', error.code, error.message);
|
||||
}
|
||||
});
|
||||
|
||||
$('#session-title').text(sessionName);
|
||||
$('#join').hide();
|
||||
$('#session').show();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
@ -90,12 +96,12 @@ function joinSession() {
|
||||
|
||||
function leaveSession() {
|
||||
|
||||
// 6) Leave the session by calling 'disconnect' method over the Session object
|
||||
// --- 9) Leave the session by calling 'disconnect' method over the Session object ---
|
||||
|
||||
session.disconnect();
|
||||
session = null;
|
||||
numVideos = 0;
|
||||
|
||||
|
||||
$('#join').show();
|
||||
$('#session').hide();
|
||||
}
|
||||
@ -106,33 +112,32 @@ function leaveSession() {
|
||||
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
function getSessionIdAndToken(callback) {
|
||||
function getToken(callback) {
|
||||
sessionName = $("#sessionName").val(); // Video-call chosen by the user
|
||||
|
||||
var jsonBody = JSON.stringify({ // Body of POST request
|
||||
'session': sessionName
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api/get-sessionid-token', jsonBody, 'Request of SESSIONID and TOKEN gone WRONG:', function successCallback(response) {
|
||||
sessionId = response[0]; // Get sessionId from response
|
||||
token = response[1]; // Get token from response
|
||||
console.warn('Request of SESSIONID and TOKEN gone WELL (SESSIONID:' + sessionId + ", TOKEN:" + token + ")");
|
||||
callback(); // Continue the join operation
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/get-token',
|
||||
{sessionName: sessionName},
|
||||
'Request of TOKEN gone WRONG:',
|
||||
(response) => {
|
||||
token = response[0]; // Get token from response
|
||||
console.warn('Request of TOKEN gone WELL (TOKEN:' + token + ')');
|
||||
callback(token); // Continue the join operation
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function removeUser() {
|
||||
// Body of POST request with the name of the session and the token of the leaving user
|
||||
var jsonBody = JSON.stringify({
|
||||
'sessionName': sessionName,
|
||||
'token': token
|
||||
});
|
||||
|
||||
// Send POST request
|
||||
httpRequest('POST', 'api/remove-user', jsonBody, 'User couldn\'t be removed from session', function successCallback(response) {
|
||||
console.warn("User correctly removed from session");
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/remove-user',
|
||||
{sessionName: sessionName, token: token},
|
||||
'User couldn\'t be removed from session',
|
||||
(response) => {
|
||||
console.warn("You have been removed from session " + sessionName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function httpRequest(method, url, body, errorMsg, callback) {
|
||||
@ -141,7 +146,7 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
http.open(method, url, true);
|
||||
http.setRequestHeader('Content-type', 'application/json');
|
||||
http.addEventListener('readystatechange', processRequest, false);
|
||||
http.send(body);
|
||||
http.send(JSON.stringify(body));
|
||||
|
||||
function processRequest() {
|
||||
if (http.readyState == 4) {
|
||||
@ -163,48 +168,69 @@ function httpRequest(method, url, body, errorMsg, callback) {
|
||||
var recordingId;
|
||||
|
||||
function startRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'session': session.sessionId
|
||||
});
|
||||
httpRequest('POST', 'api/recording/start', jsonBody, 'Start recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
recordingId = response.id;
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/recording/start',
|
||||
{session: session.sessionId},
|
||||
'Start recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
recordingId = response.id;
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function stopRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'recording': recordingId
|
||||
});
|
||||
httpRequest('POST', 'api/recording/stop', jsonBody, 'Stop recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'POST',
|
||||
'api/recording/stop',
|
||||
{recording: recordingId},
|
||||
'Stop recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function deleteRecording() {
|
||||
var jsonBody = JSON.stringify({
|
||||
'recording': recordingId
|
||||
});
|
||||
httpRequest('DELETE', 'api/recording/delete', jsonBody, 'Delete recording WRONG', function successCallback() {
|
||||
console.log("DELETE ok");
|
||||
$('#text-area').text("DELETE ok");
|
||||
});
|
||||
httpRequest(
|
||||
'DELETE',
|
||||
'api/recording/delete',
|
||||
{recording: recordingId},
|
||||
'Delete recording WRONG',
|
||||
() => {
|
||||
console.log("DELETE ok");
|
||||
$('#text-area').text("DELETE ok");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getRecording() {
|
||||
httpRequest('GET', 'api/recording/get/' + recordingId, '', 'Get recording WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'GET',
|
||||
'api/recording/get/' + recordingId,
|
||||
{},
|
||||
'Get recording WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function listRecordings() {
|
||||
httpRequest('GET', 'api/recording/list', '', 'List recordings WRONG', function successCallback(response) {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
});
|
||||
httpRequest(
|
||||
'GET',
|
||||
'api/recording/list',
|
||||
{},
|
||||
'List recordings WRONG',
|
||||
(response) => {
|
||||
console.log(response);
|
||||
$('#text-area').text(JSON.stringify(response, null, "\t"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* APPLICATION REST METHODS */
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
<!-- Bootstrap -->
|
||||
|
||||
<link rel="styleSheet" href="style.css" type="text/css" media="screen">
|
||||
<script src="openvidu-browser-1.8.0.js"></script>
|
||||
<script src="openvidu-browser-2.0.0.js"></script>
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
File diff suppressed because one or more lines are too long
10273
openvidu-recording-node/public/openvidu-browser-2.0.0.js
Normal file
10273
openvidu-recording-node/public/openvidu-browser-2.0.0.js
Normal file
File diff suppressed because one or more lines are too long
@ -16,17 +16,11 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
||||
// Node imports
|
||||
var express = require('express');
|
||||
var fs = require('fs');
|
||||
var session = require('express-session');
|
||||
var https = require('https');
|
||||
var bodyParser = require('body-parser'); // Pull information from HTML POST (express4)
|
||||
var app = express(); // Create our app with express
|
||||
|
||||
// Server configuration
|
||||
app.use(session({
|
||||
saveUninitialized: true,
|
||||
resave: false,
|
||||
secret: 'MY_SECRET'
|
||||
}));
|
||||
app.use(express.static(__dirname + '/public')); // Set the static files location
|
||||
app.use(bodyParser.urlencoded({
|
||||
'extended': 'true'
|
||||
@ -48,13 +42,13 @@ var OPENVIDU_URL = process.argv[2];
|
||||
// Environment variable: secret shared with our OpenVidu server
|
||||
var OPENVIDU_SECRET = process.argv[3];
|
||||
|
||||
// OpenVidu object to ask openvidu-server for sessionId and token
|
||||
// Entrypoint to OpenVidu Node Client SDK
|
||||
var OV = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET);
|
||||
|
||||
// Collection to pair session names and OpenVidu Session objects
|
||||
var mapSessionNameSession = {};
|
||||
// Collection to pair sessionId's (identifiers of Session objects) and tokens
|
||||
var mapSessionIdTokens = {};
|
||||
// Collection to pair session names with OpenVidu Session objects
|
||||
var mapSessions = {};
|
||||
// Collection to pair session names with tokens
|
||||
var mapSessionNamesTokens = {};
|
||||
|
||||
console.log("App listening on port 5000");
|
||||
|
||||
@ -63,76 +57,72 @@ console.log("App listening on port 5000");
|
||||
|
||||
/* Session API */
|
||||
|
||||
// Get sessionId and token (add new user to session)
|
||||
app.post('/api/get-sessionid-token', function (req, res) {
|
||||
// The video-call to connect ("TUTORIAL")
|
||||
var sessionName = req.body.session;
|
||||
|
||||
console.log("Getting sessionId and token | {sessionName}={" + sessionName + "}");
|
||||
// Get token (add new user to session)
|
||||
app.post('/api/get-token', function (req, res) {
|
||||
// The video-call to connect
|
||||
var sessionName = req.body.sessionName;
|
||||
|
||||
// Role associated to this user
|
||||
var role = OpenViduRole.PUBLISHER;
|
||||
|
||||
// Build tokenOptions object with the serverData and the role
|
||||
var tokenOptions = new TokenOptions.Builder()
|
||||
.role(role)
|
||||
.build();
|
||||
console.log("Getting a token | {sessionName}={" + sessionName + "}");
|
||||
|
||||
if (mapSessionNameSession[sessionName]) {
|
||||
// Session already exists: return existing sessionId and a new token
|
||||
// Build tokenOptions object with PUBLIHSER role
|
||||
var tokenOptions = { role: role }
|
||||
|
||||
if (mapSessions[sessionName]) {
|
||||
// Session already exists
|
||||
console.log('Existing session ' + sessionName);
|
||||
|
||||
// Get the existing Session from the collection
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
var mySession = mapSessions[sessionName];
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Get the existing sessionId
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
mySession.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
// Return the token to the client
|
||||
res.status(200).send({
|
||||
0: sessionId,
|
||||
1: token
|
||||
0: token
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
} else { // New session: return a new sessionId and a new token
|
||||
} else {
|
||||
// New session
|
||||
console.log('New session ' + sessionName);
|
||||
|
||||
// Create a new OpenVidu Session
|
||||
var mySession = OV.createSession();
|
||||
// Create a new OpenVidu Session asynchronously
|
||||
OV.createSession()
|
||||
.then(session => {
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessions[sessionName] = session;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName] = [];
|
||||
|
||||
// Get the sessionId asynchronously
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
session.generateToken(tokenOptions)
|
||||
.then(token => {
|
||||
|
||||
// Store the new Session in the collection of Sessions
|
||||
mapSessionNameSession[sessionName] = mySession;
|
||||
// Store a new empty array in the collection of tokens
|
||||
mapSessionIdTokens[sessionId] = [];
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionNamesTokens[sessionName].push(token);
|
||||
|
||||
// Generate a new token asynchronously with the recently created tokenOptions
|
||||
mySession.generateToken(tokenOptions, function (token) {
|
||||
|
||||
// Store the new token in the collection of tokens
|
||||
mapSessionIdTokens[sessionId].push(token);
|
||||
|
||||
console.log('SESSIONID: ' + sessionId);
|
||||
console.log('TOKEN: ' + token);
|
||||
|
||||
// Return the sessionId and token to the client
|
||||
res.status(200).send({
|
||||
0: sessionId,
|
||||
1: token
|
||||
});
|
||||
// Return the Token to the client
|
||||
res.status(200).send({
|
||||
0: token
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -143,36 +133,27 @@ app.post('/api/remove-user', function (req, res) {
|
||||
var token = req.body.token;
|
||||
console.log('Removing user | {sessionName, token}={' + sessionName + ', ' + token + '}');
|
||||
|
||||
// If the session exists
|
||||
var mySession = mapSessionNameSession[sessionName];
|
||||
if (mySession) {
|
||||
mySession.getSessionId(function (sessionId) {
|
||||
var tokens = mapSessionIdTokens[sessionId];
|
||||
if (tokens) {
|
||||
var index = tokens.indexOf(token);
|
||||
// If the session exists
|
||||
if (mapSessions[sessionName] && mapSessionNamesTokens[sessionName]) {
|
||||
var tokens = mapSessionNamesTokens[sessionName];
|
||||
var index = tokens.indexOf(token);
|
||||
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed!
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + mapSessionIdTokens[sessionId].toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
if (mapSessionIdTokens[sessionId].length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessionNameSession[sessionName];
|
||||
}
|
||||
res.status(200).send();
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSIONID wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
});
|
||||
// If the token exists
|
||||
if (index !== -1) {
|
||||
// Token removed
|
||||
tokens.splice(index, 1);
|
||||
console.log(sessionName + ': ' + tokens.toString());
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the TOKEN wasn\'t valid';
|
||||
console.log(msg);
|
||||
res.status(500).send(msg);
|
||||
}
|
||||
if (tokens.length == 0) {
|
||||
// Last user left: session must be removed
|
||||
console.log(sessionName + ' empty!');
|
||||
delete mapSessions[sessionName];
|
||||
}
|
||||
res.status(200).send();
|
||||
} else {
|
||||
var msg = 'Problems in the app server: the SESSION does not exist';
|
||||
console.log(msg);
|
||||
@ -182,32 +163,31 @@ app.post('/api/remove-user', function (req, res) {
|
||||
|
||||
|
||||
|
||||
|
||||
/* Recording API */
|
||||
|
||||
// Start session recording
|
||||
// Start recording
|
||||
app.post('/api/recording/start', function (req, res) {
|
||||
// Retrieve params from POST body
|
||||
var sessionId = req.body.session;
|
||||
console.log("Starting recording | {sessionId}=" + sessionId);
|
||||
|
||||
OV.startRecording(sessionId)
|
||||
.then(archive => res.status(200).send(archive))
|
||||
.then(recording => res.status(200).send(getJsonFromRecording(recording)))
|
||||
.catch(error => res.status(400).send(error.message));
|
||||
});
|
||||
|
||||
// Start session recording
|
||||
// Stop recording
|
||||
app.post('/api/recording/stop', function (req, res) {
|
||||
// Retrieve params from POST body
|
||||
var recordingId = req.body.recording;
|
||||
console.log("Stoping recording | {recordingId}=" + recordingId);
|
||||
|
||||
OV.stopRecording(recordingId)
|
||||
.then(archive => res.status(200).send(archive))
|
||||
.then(recording => res.status(200).send(getJsonFromRecording(recording)))
|
||||
.catch(error => res.status(400).send(error.message));
|
||||
});
|
||||
|
||||
// Start session recording
|
||||
// Delete recording
|
||||
app.delete('/api/recording/delete', function (req, res) {
|
||||
// Retrieve params from DELETE body
|
||||
var recordingId = req.body.recording;
|
||||
@ -218,22 +198,46 @@ app.delete('/api/recording/delete', function (req, res) {
|
||||
.catch(error => res.status(400).send(error.message));
|
||||
});
|
||||
|
||||
// Start session recording
|
||||
// Get recording
|
||||
app.get('/api/recording/get/:recordingId', function (req, res) {
|
||||
// Retrieve params from GET url
|
||||
var recordingId = req.params.recordingId;
|
||||
console.log("Getting recording | {recordingId}=" + recordingId);
|
||||
|
||||
OV.getRecording(recordingId)
|
||||
.then(archive => res.status(200).send(archive))
|
||||
.then(recording => res.status(200).send(getJsonFromRecording(recording)))
|
||||
.catch(error => res.status(400).send(error.message));
|
||||
});
|
||||
|
||||
// Start session recording
|
||||
// List all recordings
|
||||
app.get('/api/recording/list', function (req, res) {
|
||||
console.log("Listing recordings");
|
||||
|
||||
OV.listRecordings()
|
||||
.then(archives => res.status(200).send(archives))
|
||||
.then(recordings => res.status(200).send(getJsonArrayFromRecordingList(recordings)))
|
||||
.catch(error => res.status(400).send(error.message));
|
||||
});
|
||||
});
|
||||
|
||||
function getJsonFromRecording(recording) {
|
||||
return {
|
||||
"createdAt": recording.createdAt,
|
||||
"duration": recording.duration,
|
||||
"hasAudio": recording.hasAudio,
|
||||
"hasVideo": recording.hasVideo,
|
||||
"id": recording.id,
|
||||
"name": recording.name,
|
||||
"recordingLayout": recording.recordingLayout,
|
||||
"sessionId": recording.sessionId,
|
||||
"size": recording.size,
|
||||
"status": recording.status,
|
||||
"url": recording.url
|
||||
}
|
||||
}
|
||||
|
||||
function getJsonArrayFromRecordingList(recordings) {
|
||||
var jsonArray = [];
|
||||
recordings.forEach(recording => {
|
||||
jsonArray.push(getJsonFromRecording(recording));
|
||||
})
|
||||
return jsonArray;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user