387 lines
18 KiB
JavaScript
387 lines
18 KiB
JavaScript
var OV;
|
|
var session;
|
|
var publisher;
|
|
var subscriber;
|
|
|
|
function joinSession() {
|
|
|
|
var mySessionId = document.getElementById("sessionId").value;
|
|
|
|
OV = new OpenVidu();
|
|
OV.enableProdMode();
|
|
session = OV.initSession();
|
|
|
|
session.on("streamCreated", function (event) {
|
|
if (!subscriber) {
|
|
subscriber = session.subscribe(event.stream, "subscriber");
|
|
}
|
|
});
|
|
|
|
// On every asynchronous exception...
|
|
session.on('exception', (exception) => {
|
|
console.warn(exception);
|
|
});
|
|
|
|
getToken(mySessionId).then(token => {
|
|
|
|
session.connect(token)
|
|
.then(() => {
|
|
document.getElementById("session-header").innerText = mySessionId;
|
|
document.getElementById("join").style.display = "none";
|
|
document.getElementById("session").style.display = "block";
|
|
|
|
publisher = OV.initPublisher("publisher");
|
|
session.publish(publisher);
|
|
})
|
|
.catch(error => {
|
|
console.log("There was an error connecting to the session:", error.code, error.message);
|
|
});
|
|
});
|
|
|
|
}
|
|
|
|
function leaveSession() {
|
|
session.disconnect();
|
|
document.getElementById("join").style.display = "block";
|
|
document.getElementById("session").style.display = "none";
|
|
}
|
|
|
|
window.onbeforeunload = function () {
|
|
if (session) session.disconnect()
|
|
};
|
|
|
|
let publisherStartSpeakingSession = [];
|
|
let publisherStopSpeakingSession = [];
|
|
|
|
let publisherStartSpeakingPublisher = [];
|
|
let publisherStopSpeakingPublisher = [];
|
|
|
|
let publisherStartSpeakingSubscriber = [];
|
|
let publisherStopSpeakingSubscriber = [];
|
|
|
|
let streamAudioVolumeChangePublisher = [];
|
|
let streamAudioVolumeChangeSubscriber = [];
|
|
|
|
function attachHandlerHtml(arrayName, handlerNumber, removeCallback) {
|
|
const element = document.createElement('input');
|
|
element.type = 'button';
|
|
element.className = 'handler-btn';
|
|
element.id = arrayName + '-handler' + handlerNumber;
|
|
element.value = 'Handler ' + handlerNumber;
|
|
element.onclick = () => {
|
|
removeCallback();
|
|
};
|
|
document.getElementById(arrayName).append(element);
|
|
}
|
|
|
|
function removeHandlerHtml(regexId) {
|
|
const regexp = new RegExp('^' + regexId + '$');
|
|
const elements = document.getElementById('handlers').getElementsByClassName('handler-btn');
|
|
for (let i = elements.length - 1; i >= 0; i--) {
|
|
let elem = elements[i];
|
|
if (regexp.test(elem.id)) {
|
|
elem.parentNode.removeChild(elem);
|
|
}
|
|
}
|
|
}
|
|
|
|
function offEvent(eventName, target, array, handler, handlerNumber) {
|
|
if (handler != null) {
|
|
target.off(eventName, handler);
|
|
array.splice(array.indexOf(handler), 1);
|
|
removeHandlerHtml(eventName + target.constructor.name + '-handler' + handlerNumber);
|
|
} else {
|
|
target.off(eventName);
|
|
array = [];
|
|
removeHandlerHtml(eventName + target.constructor.name + '-handler.+');
|
|
}
|
|
return array;
|
|
}
|
|
|
|
function onPublisherStartSpeakingSession() {
|
|
const handlerNumber = publisherStartSpeakingSession.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking triggered by ' + event.target.constructor.name + ' and belonging to ' + (event.connection.stream.streamManager.remote ? 'Subscriber' : 'Publisher'));
|
|
}
|
|
publisherStartSpeakingSession.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingSession', handlerNumber, () => offEvent('publisherStartSpeaking', session, publisherStartSpeakingSession, handler, handlerNumber));
|
|
session.on('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStartSpeakingSession() {
|
|
const handlerNumber = publisherStartSpeakingSession.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking (ONCE) triggered by ' + event.target.constructor.name + ' and belonging to ' + (event.connection.stream.streamManager.remote ? 'Subscriber' : 'Publisher'));
|
|
publisherStartSpeakingSession.splice(publisherStartSpeakingSession.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStartSpeakingSession-handler' + handlerNumber);
|
|
}
|
|
publisherStartSpeakingSession.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingSession', handlerNumber, () => offEvent('publisherStartSpeaking', session, publisherStartSpeakingSession, handler, handlerNumber));
|
|
session.once('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStartSpeakingSession(handler) {
|
|
const availableHandlers = publisherStartSpeakingSession.length;
|
|
publisherStartSpeakingSession = offEvent('publisherStartSpeaking', session, publisherStartSpeakingSession);
|
|
console.log('Available publisherStartSpeaking handlers for Session: ' + availableHandlers + '. Remaining: ' + publisherStartSpeakingSession.length);
|
|
}
|
|
|
|
function onPublisherStopSpeakingSession() {
|
|
const handlerNumber = publisherStopSpeakingSession.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking triggered by ' + event.target.constructor.name + ' and belonging to ' + (event.connection.stream.streamManager.remote ? 'Subscriber' : 'Publisher'));
|
|
}
|
|
publisherStopSpeakingSession.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingSession', handlerNumber, () => offEvent('publisherStopSpeaking', session, publisherStopSpeakingSession, handler, handlerNumber));
|
|
session.on('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStopSpeakingSession() {
|
|
const handlerNumber = publisherStopSpeakingSession.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking (ONCE) triggered by ' + event.target.constructor.name + ' and belonging to ' + (event.connection.stream.streamManager.remote ? 'Subscriber' : 'Publisher'));
|
|
publisherStopSpeakingSession.splice(publisherStopSpeakingSession.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStopSpeakingSession-handler' + handlerNumber);
|
|
}
|
|
publisherStopSpeakingSession.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingSession', handlerNumber, () => offEvent('publisherStopSpeaking', session, publisherStopSpeakingSession, handler, handlerNumber));
|
|
session.once('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStopSpeakingSession() {
|
|
const availableHandlers = publisherStopSpeakingSession.length;
|
|
publisherStopSpeakingSession = offEvent('publisherStopSpeaking', session, publisherStopSpeakingSession);
|
|
console.log('Available publisherStopSpeaking handlers for Session: ' + availableHandlers + '. Remaining: ' + publisherStopSpeakingSession.length);
|
|
}
|
|
|
|
function onPublisherStartSpeakingPublisher() {
|
|
const handlerNumber = publisherStartSpeakingPublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking triggered by ' + event.target.constructor.name);
|
|
}
|
|
publisherStartSpeakingPublisher.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingPublisher', handlerNumber, () => offEvent('publisherStartSpeaking', publisher, publisherStartSpeakingPublisher, handler, handlerNumber));
|
|
publisher.on('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStartSpeakingPublisher() {
|
|
const handlerNumber = publisherStartSpeakingPublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking (ONCE) triggered by ' + event.target.constructor.name);
|
|
publisherStartSpeakingPublisher.splice(publisherStartSpeakingPublisher.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStartSpeakingPublisher-handler' + handlerNumber);
|
|
}
|
|
publisherStartSpeakingPublisher.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingPublisher', handlerNumber, () => offEvent('publisherStartSpeaking', publisher, publisherStartSpeakingPublisher, handler, handlerNumber));
|
|
publisher.once('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStartSpeakingPublisher() {
|
|
const availableHandlers = publisherStartSpeakingPublisher.length;
|
|
publisherStartSpeakingPublisher = offEvent('publisherStartSpeaking', publisher, publisherStartSpeakingPublisher);
|
|
console.log('Available publisherStartSpeaking handlers for Publisher: ' + availableHandlers + '. Remaining: ' + publisherStartSpeakingPublisher.length);
|
|
}
|
|
|
|
function onPublisherStopSpeakingPublisher() {
|
|
const handlerNumber = publisherStopSpeakingPublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking triggered by ' + event.target.constructor.name);
|
|
}
|
|
publisherStopSpeakingPublisher.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingPublisher', handlerNumber, () => offEvent('publisherStopSpeaking', publisher, publisherStopSpeakingPublisher, handler, handlerNumber));
|
|
publisher.on('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStopSpeakingPublisher() {
|
|
const handlerNumber = publisherStopSpeakingPublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking (ONCE) triggered by ' + event.target.constructor.name);
|
|
publisherStopSpeakingPublisher.splice(publisherStopSpeakingPublisher.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStopSpeakingPublisher-handler' + handlerNumber);
|
|
}
|
|
publisherStopSpeakingPublisher.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingPublisher', handlerNumber, () => offEvent('publisherStopSpeaking', publisher, publisherStopSpeakingPublisher, handler, handlerNumber));
|
|
publisher.once('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStopSpeakingPublisher() {
|
|
const availableHandlers = publisherStopSpeakingPublisher.length;
|
|
publisherStopSpeakingPublisher = offEvent('publisherStopSpeaking', publisher, publisherStopSpeakingPublisher);
|
|
console.log('Available publisherStopSpeaking handlers for Publisher: ' + availableHandlers + '. Remaining: ' + publisherStopSpeakingPublisher.length);
|
|
}
|
|
|
|
function onPublisherStartSpeakingSubscriber() {
|
|
const handlerNumber = publisherStartSpeakingSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking triggered by ' + event.target.constructor.name);
|
|
}
|
|
publisherStartSpeakingSubscriber.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingSubscriber', handlerNumber, () => offEvent('publisherStartSpeaking', subscriber, publisherStartSpeakingSubscriber, handler, handlerNumber));
|
|
subscriber.on('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStartSpeakingSubscriber() {
|
|
const handlerNumber = publisherStartSpeakingSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStartSpeaking (ONCE) triggered by ' + event.target.constructor.name);
|
|
publisherStartSpeakingSubscriber.splice(publisherStartSpeakingSubscriber.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStartSpeakingSubscriber-handler' + handlerNumber);
|
|
}
|
|
publisherStartSpeakingSubscriber.push(handler);
|
|
attachHandlerHtml('publisherStartSpeakingSubscriber', handlerNumber, () => offEvent('publisherStartSpeaking', subscriber, publisherStartSpeakingSubscriber, handler, handlerNumber));
|
|
subscriber.once('publisherStartSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStartSpeakingSubscriber() {
|
|
const availableHandlers = publisherStartSpeakingSubscriber.length;
|
|
publisherStartSpeakingSubscriber = offEvent('publisherStartSpeaking', subscriber, publisherStartSpeakingSubscriber);
|
|
console.log('Available publisherStartSpeaking handlers for Subscriber: ' + availableHandlers + '. Remaining: ' + publisherStartSpeakingSubscriber.length);
|
|
}
|
|
|
|
function onPublisherStopSpeakingSubscriber() {
|
|
const handlerNumber = publisherStopSpeakingSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking triggered by ' + event.target.constructor.name);
|
|
}
|
|
publisherStopSpeakingSubscriber.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingSubscriber', handlerNumber, () => offEvent('publisherStopSpeaking', subscriber, publisherStopSpeakingSubscriber, handler, handlerNumber));
|
|
subscriber.on('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function oncePublisherStopSpeakingSubscriber() {
|
|
const handlerNumber = publisherStopSpeakingSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing publisherStopSpeaking (ONCE) triggered by ' + event.target.constructor.name);
|
|
publisherStopSpeakingSubscriber.splice(publisherStopSpeakingSubscriber.indexOf(handler), 1);
|
|
removeHandlerHtml('publisherStopSpeakingSubscriber-handler' + handlerNumber);
|
|
}
|
|
publisherStopSpeakingSubscriber.push(handler);
|
|
attachHandlerHtml('publisherStopSpeakingSubscriber', handlerNumber, () => offEvent('publisherStopSpeaking', subscriber, publisherStopSpeakingSubscriber, handler, handlerNumber));
|
|
subscriber.once('publisherStopSpeaking', handler);
|
|
}
|
|
|
|
function offPublisherStopSpeakingSubscriber() {
|
|
const availableHandlers = publisherStopSpeakingSubscriber.length;
|
|
publisherStopSpeakingSubscriber = offEvent('publisherStopSpeaking', subscriber, publisherStopSpeakingSubscriber);
|
|
console.log('Available publisherStopSpeaking handlers for Subscriber: ' + availableHandlers + '. Remaining: ' + publisherStopSpeakingSubscriber.length);
|
|
}
|
|
|
|
function onStreamAudioVolumeChangePublisher() {
|
|
const handlerNumber = streamAudioVolumeChangePublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing streamAudioVolumeChange triggered by ' + event.target.constructor.name);
|
|
}
|
|
streamAudioVolumeChangePublisher.push(handler);
|
|
attachHandlerHtml('streamAudioVolumeChangePublisher', handlerNumber, () => offEvent('streamAudioVolumeChange', publisher, streamAudioVolumeChangePublisher, handler, handlerNumber));
|
|
publisher.on('streamAudioVolumeChange', handler);
|
|
}
|
|
|
|
function onceStreamAudioVolumeChangePublisher() {
|
|
const handlerNumber = streamAudioVolumeChangePublisher.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing streamAudioVolumeChange (ONCE) triggered by ' + event.target.constructor.name);
|
|
streamAudioVolumeChangePublisher.splice(streamAudioVolumeChangePublisher.indexOf(handler), 1);
|
|
removeHandlerHtml('streamAudioVolumeChangePublisher-handler' + handlerNumber);
|
|
}
|
|
streamAudioVolumeChangePublisher.push(handler);
|
|
attachHandlerHtml('streamAudioVolumeChangePublisher', handlerNumber, () => offEvent('streamAudioVolumeChange', publisher, streamAudioVolumeChangePublisher, handler, handlerNumber));
|
|
publisher.once('streamAudioVolumeChange', handler);
|
|
}
|
|
|
|
function offStreamAudioVolumeChangePublisher() {
|
|
const availableHandlers = streamAudioVolumeChangePublisher.length;
|
|
streamAudioVolumeChangePublisher = offEvent('streamAudioVolumeChange', publisher, streamAudioVolumeChangePublisher);
|
|
console.log('Available streamAudioVolumeChange handlers for Publisher: ' + availableHandlers + '. Remaining: ' + streamAudioVolumeChangePublisher.length);
|
|
}
|
|
|
|
function onStreamAudioVolumeChangeSubscriber() {
|
|
const handlerNumber = streamAudioVolumeChangeSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing streamAudioVolumeChange triggered by ' + event.target.constructor.name);
|
|
}
|
|
streamAudioVolumeChangeSubscriber.push(handler);
|
|
attachHandlerHtml('streamAudioVolumeChangeSubscriber', handlerNumber, () => offEvent('streamAudioVolumeChange', subscriber, streamAudioVolumeChangeSubscriber, handler, handlerNumber));
|
|
subscriber.on('streamAudioVolumeChange', handler);
|
|
}
|
|
|
|
function onceStreamAudioVolumeChangeSubscriber() {
|
|
const handlerNumber = streamAudioVolumeChangeSubscriber.length + 1;
|
|
const handler = event => {
|
|
console.log('Handler ' + handlerNumber + ' processing streamAudioVolumeChange (ONCE) triggered by ' + event.target.constructor.name);
|
|
streamAudioVolumeChangeSubscriber.splice(streamAudioVolumeChangeSubscriber.indexOf(handler), 1);
|
|
removeHandlerHtml('streamAudioVolumeChangeSubscriber-handler' + handlerNumber);
|
|
}
|
|
streamAudioVolumeChangeSubscriber.push(handler);
|
|
attachHandlerHtml('streamAudioVolumeChangeSubscriber', handlerNumber, () => offEvent('streamAudioVolumeChange', subscriber, streamAudioVolumeChangeSubscriber, handler, handlerNumber));
|
|
subscriber.once('streamAudioVolumeChange', handler);
|
|
}
|
|
|
|
function offStreamAudioVolumeChangeSubscriber() {
|
|
const availableHandlers = streamAudioVolumeChangeSubscriber.length;
|
|
streamAudioVolumeChangeSubscriber = offEvent('streamAudioVolumeChange', subscriber, streamAudioVolumeChangeSubscriber);
|
|
console.log('Available streamAudioVolumeChange handlers for Subscriber: ' + availableHandlers + '. Remaining: ' + streamAudioVolumeChangeSubscriber.length);
|
|
}
|
|
|
|
|
|
/**
|
|
* --------------------------
|
|
* SERVER-SIDE RESPONSIBILITY
|
|
* --------------------------
|
|
* These methods retrieve the mandatory user token from OpenVidu Server.
|
|
* This behavior 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 /openvidu/api/sessions)
|
|
* 2) Create a Connection in OpenVidu Server (POST /openvidu/api/sessions/<SESSION_ID>/connection)
|
|
* 3) The Connection.token must be consumed in Session.connect() method
|
|
*/
|
|
|
|
var OPENVIDU_SERVER_URL = "https://" + location.hostname + ":4443";
|
|
var OPENVIDU_SERVER_SECRET = "MY_SECRET";
|
|
|
|
function getToken(mySessionId) {
|
|
return createSession(mySessionId).then(sessionId => createToken(sessionId));
|
|
}
|
|
|
|
function createSession(sessionId) { // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-openviduapisessions
|
|
return new Promise((resolve, reject) => {
|
|
$.ajax({
|
|
type: "POST",
|
|
url: OPENVIDU_SERVER_URL + "/openvidu/api/sessions",
|
|
data: JSON.stringify({
|
|
customSessionId: sessionId
|
|
}),
|
|
headers: {
|
|
"Authorization": "Basic " + btoa("OPENVIDUAPP:" + OPENVIDU_SERVER_SECRET),
|
|
"Content-Type": "application/json"
|
|
},
|
|
success: response => resolve(response.id),
|
|
error: (error) => {
|
|
if (error.status === 409) {
|
|
resolve(sessionId);
|
|
} else {
|
|
console.warn('No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU_SERVER_URL);
|
|
if (window.confirm('No connection to OpenVidu Server. This may be a certificate error at \"' + OPENVIDU_SERVER_URL + '\"\n\nClick OK to navigate and accept it. ' +
|
|
'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' + OPENVIDU_SERVER_URL + '"')) {
|
|
location.assign(OPENVIDU_SERVER_URL + '/accept-certificate');
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function createToken(sessionId) { // See https://docs.openvidu.io/en/stable/reference-docs/REST-API/#post-openviduapisessionsltsession_idgtconnection
|
|
return new Promise((resolve, reject) => {
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: OPENVIDU_SERVER_URL + '/openvidu/api/sessions/' + sessionId + '/connection',
|
|
data: JSON.stringify({}),
|
|
headers: {
|
|
'Authorization': 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SERVER_SECRET),
|
|
'Content-Type': 'application/json',
|
|
},
|
|
success: (response) => resolve(response.token),
|
|
error: (error) => reject(error)
|
|
});
|
|
});
|
|
} |