bigbluebutton-Github/labs/bbb-webrtc-sfu/lib/video/video.js
2017-12-20 14:56:28 -02:00

167 lines
4.4 KiB
JavaScript

'use strict';
// Global stuff
var sharedWebcams = {};
const kurento = require('kurento-client');
const config = require('config');
const kurentoUrl = config.get('kurentoUrl');
const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
const C = require('../bbb/messages/Constants');
if (config.get('acceptSelfSignedCertificate')) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
}
module.exports = class Video {
constructor(_bbbGW, _id, _shared, _sessionId) {
this.mcs = new MCSApi();
this.bbbGW = _bbbGW;
this.id = _id;
this.sessionId = _sessionId;
this.meetingId = _id;
this.shared = _shared;
this.role = this.shared? 'share' : 'view'
this.webRtcEndpoint = null;
this.mediaId = null;
this.candidatesQueue = [];
}
onIceCandidate (_candidate) {
if (this.mediaId) {
try {
this.flushCandidatesQueue();
this.mcs.addIceCandidate(this.mediaId, _candidate);
}
catch (err) {
console.log(err);
}
}
else {
this.candidatesQueue.push(_candidate);
}
};
flushCandidatesQueue () {
if (this.mediaId) {
try {
while(this.candidatesQueue.length) {
let candidate = this.candidatesQueue.shift();
this.mcs.addIceCandidate(this.mediaId, candidate);
}
}
catch (err) {
console.log(err);
}
}
}
mediaState (event) {
let msEvent = event.event;
switch (event.eventTag) {
case "OnIceCandidate":
//console.log(" [video] Sending ICE candidate to user => " + this.id);
let candidate = msEvent.candidate;
this.bbbGW.publish(JSON.stringify({
connectionId: this.sessionId,
type: 'video',
role: this.role,
id : 'iceCandidate',
cameraId: this.id,
candidate: candidate
}), C.FROM_VIDEO);
break;
case "MediaStateChanged":
break;
case "MediaFlowOutStateChange":
case "MediaFlowInStateChange":
console.log(' [video] ' + msEvent.type + '[' + msEvent.state + ']' + ' for endpoint ' + this.id);
if (msEvent.state === 'NOT_FLOWING') {
this.bbbGW.publish(JSON.stringify({
connectionId: this.sessionId,
type: 'video',
role: this.role,
id : 'playStop',
cameraId: this.id,
}), C.FROM_VIDEO);
}
else if (msEvent.state === 'FLOWING') {
this.bbbGW.publish(JSON.stringify({
connectionId: this.sessionId,
type: 'video',
role: this.role,
id : 'playStart',
cameraId: this.id,
}), C.FROM_VIDEO);
}
break;
default: console.log(" [video] Unrecognized event");
}
}
async start (sdpOffer, callback) {
console.log(" [video] start");
let sdpAnswer;
try {
this.userId = await this.mcs.join(this.meetingId, 'SFU', {});
console.log(" [video] Join returned => " + this.userId);
if (this.shared) {
const ret = await this.mcs.publish(this.userId, this.meetingId, 'WebRtcEndpoint', {descriptor: sdpOffer});
this.mediaId = ret.sessionId;
sharedWebcams[this.id] = this.mediaId;
sdpAnswer = ret.answer;
this.flushCandidatesQueue();
this.mcs.on('MediaEvent' + this.mediaId, this.mediaState.bind(this));
console.log(" [video] Publish returned => " + this.mediaId);
return callback(null, sdpAnswer);
}
else {
const ret = await this.mcs.subscribe(this.userId, sharedWebcams[this.id], 'WebRtcEndpoint', {descriptor: sdpOffer});
this.mediaId = ret.sessionId;
sdpAnswer = ret.answer;
this.flushCandidatesQueue();
this.mcs.on('MediaEvent' + this.mediaId, this.mediaState.bind(this));
console.log(" [video] Subscribe returned => " + this.mediaId);
return callback(null, sdpAnswer);
}
}
catch (err) {
console.log(" [video] MCS returned error => " + err);
return callback(err);
}
};
async stop () {
console.log(' [stop] Releasing endpoints for user ' + this.userId + ' at room ' + this.meetingId);
try {
await this.mcs.leave(this.meetingId, this.userId);
if (this.shared) {
sharedWebcams[this.id] = null;
}
this._candidatesQueue = null;
return;
}
catch (err) {
// TODO error handling
return;
}
return;
};
};