UNPKG

vani-meeting-client

Version:
858 lines 61.2 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; import { BaseVideoCallHandler } from "./BaseVideoCallHandler"; import { detectDevice, Device } from 'mediasoup-client'; import { SFUMessageType } from "../websocket-handler/WebsocketHandler"; import { Track, TrackKind } from "../model/Track"; import { LogLevel, VaniEvent } from '..'; import { StreamType, TrackStats } from '../model/TrackStats'; var SFUHandler = /** @class */ (function (_super) { __extends(SFUHandler, _super); function SFUHandler(_meetingStartRequest, _communicationHandler) { var _this = _super.call(this, _meetingStartRequest, _communicationHandler) || this; _this.device = undefined; _this.transportCallBacks = {}; _this.isProduceTrackIntialWorkDone = false; _this.producers = []; _this.consumers = []; _this.dataProducers = []; _this.dataConsumer = []; _this.isInitDone = false; _this.getDevice = function () { if (_this.device) { return _this.device; } var handlerName = detectDevice(); if (handlerName) { _this.device = new Device(); _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("detected handler: %s", handlerName); } else { if (_this.meetingStartRequest && _this.meetingStartRequest.mediasoupDeviceHandlerName) { _this.device = new Device({ handlerName: _this.meetingStartRequest.mediasoupDeviceHandlerName }); } _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.warn("no suitable handler found for current browser/device"); } return _this.device; }; _this.onConsumerNotFound = function (data) { var consumerId = data.message.consumerId; var consumer = _this.consumers.find(function (consumer) { return consumer.id === consumerId; }); if (consumer) { _this.consumers = _this.consumers.filter(function (consumer) { return consumer.id !== consumerId; }); consumer.close(); } }; _this.onProducerNotFound = function (data) { var _a; var producerId = data.message.producerId; var producer = _this.producers.find(function (producer) { return producer.id === producerId; }); if (producer) { _this.producers = _this.producers.filter(function (eachProducer) { return eachProducer.id !== producerId; }); if (producer.appData.trackId) { var track = (_a = _this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getTrackById(producer.appData.trackId); track && _this.sendTrack(track); } } }; _this.onConsumerScoreChange = function (_data) { return __awaiter(_this, void 0, void 0, function () { var data, score, consumerId, consumedProducer, track; var _a, _b; return __generator(this, function (_c) { data = _data.message; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("onConsumerScoreChange", data); score = data.score; consumerId = data.consumerId; consumedProducer = this.consumers.find(function (eachConsumer) { return eachConsumer.id === consumerId; }); if (consumedProducer) { track = (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getAllTracks().find(function (eachTrack) { return consumedProducer.appData.producerData.trackId === eachTrack.trackId; }); (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.emitMessageToSource(VaniEvent.OnConsumerScoreChange, { track: track, score: score, participant: track === null || track === void 0 ? void 0 : track.participant }); } return [2 /*return*/]; }); }); }; _this.onProducerScoreChange = function (_data) { return __awaiter(_this, void 0, void 0, function () { var data, score, producerId, producer, consumedProducer, track, track; var _a, _b, _c, _d; return __generator(this, function (_e) { data = _data.message; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("onProducerScoreChange", data); score = data.score; producerId = data.producerId; producer = this.producers.find(function (producer) { return producer.id === producerId; }); consumedProducer = this.consumers.find(function (eachConsumer) { return eachConsumer.producerId === producerId; }); if (consumedProducer) { track = (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getAllTracks().find(function (eachTrack) { return consumedProducer.appData.producerData.trackId === eachTrack.trackId; }); (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.emitMessageToSource(VaniEvent.OnProducerScoreChange, { track: track, score: score, participant: track === null || track === void 0 ? void 0 : track.participant }); } if (producer) { track = (_c = this.communicationHandler) === null || _c === void 0 ? void 0 : _c.getAllTracks().find(function (eachTrack) { return (producer.appData).trackId === eachTrack.trackId; }); if (track) { (_d = this.communicationHandler) === null || _d === void 0 ? void 0 : _d.emitMessageToSource(VaniEvent.OnProducerScoreChange, { track: track, score: score, participant: track === null || track === void 0 ? void 0 : track.participant }); } } return [2 /*return*/]; }); }); }; _this.onConsumerLayerChange = function (_data) { return __awaiter(_this, void 0, void 0, function () { var data, layer, consumerId, consumer, track; var _a, _b; return __generator(this, function (_c) { data = _data.message; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("onConsumerLayerChange", data); layer = data.layer; consumerId = data.consumerId; consumer = this.consumers.find(function (consumer) { return consumer.id === consumerId; }); if (consumer) { track = (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getAllTracks().find(function (eachTrack) { return consumer.appData.producerData.trackId === eachTrack.trackId; }); if (track) { (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.emitMessageToSource(VaniEvent.OnConsumerLayerChange, { track: track, layer: layer, participant: track.participant }); } } return [2 /*return*/]; }); }); }; _this.getClientStats = function () { return __awaiter(_this, void 0, void 0, function () { var allTracks, promisesArray, allTracks_1, allTracks_1_1, track; var e_1, _a; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!this.communicationHandler) return [3 /*break*/, 2]; allTracks = (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.getAllTracks(); promisesArray = []; try { for (allTracks_1 = __values(allTracks), allTracks_1_1 = allTracks_1.next(); !allTracks_1_1.done; allTracks_1_1 = allTracks_1.next()) { track = allTracks_1_1.value; promisesArray.push(this.eachTrackStats(track)); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (allTracks_1_1 && !allTracks_1_1.done && (_a = allTracks_1.return)) _a.call(allTracks_1); } finally { if (e_1) throw e_1.error; } } return [4 /*yield*/, Promise.all(promisesArray)]; case 1: return [2 /*return*/, _c.sent()]; case 2: return [2 /*return*/, []]; } }); }); }; _this.eachTrackStats = function (track) { return __awaiter(_this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var consumer, _a, _b, _c, producer, _d, _e, _f; return __generator(this, function (_g) { switch (_g.label) { case 0: consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (!consumer) return [3 /*break*/, 2]; _a = resolve; _b = TrackStats.bind; _c = [void 0, track, StreamType.Consumer]; return [4 /*yield*/, consumer.getStats()]; case 1: _a.apply(void 0, [new (_b.apply(TrackStats, _c.concat([_g.sent()])))()]); return [3 /*break*/, 4]; case 2: producer = this.producers.find(function (producer) { return (producer.appData).trackId === track.trackId; }); if (!producer) return [3 /*break*/, 4]; _d = resolve; _e = TrackStats.bind; _f = [void 0, track, StreamType.Producer]; return [4 /*yield*/, producer.getStats()]; case 3: _d.apply(void 0, [new (_e.apply(TrackStats, _f.concat([_g.sent()])))()]); _g.label = 4; case 4: return [2 /*return*/]; } }); }); })]; }); }); }; _this.getDevice(); return _this; } SFUHandler.prototype.reconnectedWithoutPing = function () { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("reconnectedWithoutPing"); this.onReconnect(); }; SFUHandler.prototype.onReconnect = function () { return __awaiter(this, void 0, void 0, function () { var data, data; return __generator(this, function (_a) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("SFU onReconnect"); if (this.sendTransport && (this.sendTransport.connectionState === "disconnected" || this.sendTransport.connectionState === "failed" || this.sendTransport.connectionState === "new")) { data = { to: "self", message: { transportId: this.sendTransport.id }, "type": SFUMessageType.OnRestartIceCandidate }; this.sendSFUMessageToSocket(data); } if (this.consumerTransport && (this.consumerTransport.connectionState === "disconnected" || this.consumerTransport.connectionState === "failed" || this.consumerTransport.connectionState === "new")) { data = { to: "self", message: { transportId: this.consumerTransport.id }, "type": SFUMessageType.OnRestartIceCandidate }; this.sendSFUMessageToSocket(data); } return [2 /*return*/]; }); }); }; SFUHandler.prototype.onRestartIceCandidateResponse = function (data) { var _a, _b; return __awaiter(this, void 0, void 0, function () { var transportId, iceParameters; return __generator(this, function (_c) { switch (_c.label) { case 0: transportId = data.message.transportId; iceParameters = data.message.iceParameters; (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.downloadParticipantsData(); if (!(this.consumerTransport && this.consumerTransport.id === transportId)) return [3 /*break*/, 2]; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("Restat Ice consumer"); return [4 /*yield*/, this.consumerTransport.restartIce({ iceParameters: iceParameters })]; case 1: _c.sent(); return [3 /*break*/, 4]; case 2: if (!(this.sendTransport && this.sendTransport.id === transportId)) return [3 /*break*/, 4]; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("Restat Ice sender"); return [4 /*yield*/, this.sendTransport.restartIce({ iceParameters: iceParameters })]; case 3: _c.sent(); _c.label = 4; case 4: (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.onReconnect(false); return [2 /*return*/]; } }); }); }; SFUHandler.prototype.stopTrack = function (track) { var _this = this; var producers = this.producers.filter(function (producer) { return producer.appData.trackId === track.trackId; }); producers.forEach(function (producer) { if (producer) { // try { // producer.track?.stop() // } // catch (err) { // } producer.close(); var messageJson = { to: "self", type: SFUMessageType.OnProducerClosed, message: { producerId: producer.id } }; _this.sendSFUMessageToSocket(messageJson); var index = _this.producers.indexOf(producer); _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("stopTrack ", index); if (index > -1) { _this.producers.splice(index, 1); _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("stopTrack producers", _this.producers); } } }); }; SFUHandler.prototype.pauseTrack = function (track) { var _this = this; var producers = this.producers.filter(function (producer) { return producer.appData.trackId === track.trackId; }); producers.forEach(function (producer) { var _a; if (producer) { if ((_a = _this.meetingStartRequest) === null || _a === void 0 ? void 0 : _a.isMobileApp) { _this.stopTrack(track); } else { producer.pause(); var messageJson = { to: "self", type: SFUMessageType.OnPauseProducer, message: { producerId: producer.id } }; _this.sendSFUMessageToSocket(messageJson); } } }); }; SFUHandler.prototype.getConsumerForTrack = function (track) { var consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); return consumer; }; SFUHandler.prototype.resumeProducerOrConsumerForTrack = function (track) { return __awaiter(this, void 0, void 0, function () { var producer, producers, consumer; return __generator(this, function (_a) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("resumeProducerOrConsumerForTrack"); if (track.track) { track.track.enabled = true; } producer = this.producers.find(function (producer) { return producer.appData.trackId === track.trackId; }); if (producer) { producers = this.producers.filter(function (producer) { return producer.appData.trackId === track.trackId; }); producers.forEach(function (eachProducer) { eachProducer.resume(); }); } else { consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (consumer) { consumer.resume(); } } return [2 /*return*/]; }); }); }; SFUHandler.prototype.pauseProducerOrConsumerForTrack = function (track) { return __awaiter(this, void 0, void 0, function () { var producer, consumer; return __generator(this, function (_a) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("pauseProducerOrConsumerForTrack"); producer = this.producers.find(function (producer) { return producer.appData.trackId === track.trackId; }); if (producer) { producer.pause(); } else { consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (consumer) { consumer.pause(); } } if (track.track) { track.track.enabled = false; } return [2 /*return*/]; }); }); }; SFUHandler.prototype.resumeTrack = function (track) { var producer = this.producers.find(function (producer) { return producer.appData.trackId === track.trackId; }); if (producer) { producer.resume(); var messageJson = { to: "self", type: SFUMessageType.OnResumeProducer, message: { producerId: producer.id } }; this.sendSFUMessageToSocket(messageJson); } }; SFUHandler.prototype.pauseIncomingTrack = function (track) { var consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (consumer) { var messageJson = { to: "self", type: SFUMessageType.PauseConsumer, message: { id: consumer.id } }; this.sendSFUMessageToSocket(messageJson); consumer.pause(); } }; SFUHandler.prototype.resumeIncomingTrack = function (track) { var consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (consumer) { var messageJson = { to: "self", type: SFUMessageType.ResumeConsumer, message: { id: consumer.id } }; this.sendSFUMessageToSocket(messageJson); consumer.resume(); } }; SFUHandler.prototype.updateSpatialForTrack = function (track, spatialLayerIndex) { return __awaiter(this, void 0, void 0, function () { var consumer, messageJson; return __generator(this, function (_a) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("updateSpatialForTrack"); consumer = this.consumers.find(function (consumer) { return consumer.appData.producerData.trackId === track.trackId; }); if (consumer) { messageJson = { to: "self", type: SFUMessageType.UpdateSpatialConsumer, message: { id: consumer.id, spatialLayer: spatialLayerIndex } }; this.sendSFUMessageToSocket(messageJson); } return [2 /*return*/]; }); }); }; SFUHandler.prototype.sendTrack = function (track) { var _a, _b, _c, _d, _e; return __awaiter(this, void 0, void 0, function () { var producer, appData, producerData, webcamProducer; var _this = this; return __generator(this, function (_f) { switch (_f.label) { case 0: this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("On Send Track - ", this.sendTransport ? true : false); if (!this.sendTransport) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("No Send Transport", track); return [2 /*return*/]; } if (!(track && track.track)) return [3 /*break*/, 5]; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("Inside send Track"); producer = this.producers.find(function (producer) { return producer.appData.trackId === track.trackId; }); if (producer && producer.closed === false && ((_a = this.meetingStartRequest) === null || _a === void 0 ? void 0 : _a.isMobileApp)) { this.stopTrack(track); } if (!(producer && producer.closed === false && ((_b = this.meetingStartRequest) === null || _b === void 0 ? void 0 : _b.isMobileApp) === false)) return [3 /*break*/, 2]; // try { // producer.track?.stop() // } // catch (err) { // } return [4 /*yield*/, producer.replaceTrack({ track: track.track })]; case 1: // try { // producer.track?.stop() // } // catch (err) { // } _f.sent(); this.resumeTrack(track); return [3 /*break*/, 4]; case 2: appData = __assign({}, (_c = this.sendTransport) === null || _c === void 0 ? void 0 : _c.appData); appData.trackKind = track.trackKind; appData.trackId = track.trackId; producerData = { track: track.track, appData: appData, disableTrackOnPause: false, zeroRtpOnPause: true, stopTracks: false }; if (track.trackKind === TrackKind.Video && this.meetingStartRequest.simulcastEncodings.length > 0) { producerData.encodings = this.meetingStartRequest.simulcastEncodings; } if (track.track.kind === "audio") { producerData.codecOptions = { opusStereo: true, opusFec: true, opusDtx: true }; if (this.meetingStartRequest.maxAudioBitrateConfig > 0) { producerData.codecOptions.opusMaxAverageBitrate = (_d = this.meetingStartRequest) === null || _d === void 0 ? void 0 : _d.maxAudioBitrateConfig; } } this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log(producerData); return [4 /*yield*/, ((_e = this.sendTransport) === null || _e === void 0 ? void 0 : _e.produce(producerData))]; case 3: webcamProducer = _f.sent(); if (webcamProducer) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("On webcamProducer"); this.producers.push(webcamProducer); if (webcamProducer) { webcamProducer.observer.on("trackended", function () { _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("On Track Endded producer event"); }); } this.onParticipantUpdated(); // this.sendMessageReadyToConsume(); } else { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("On webcamProducer not created"); } _f.label = 4; case 4: return [3 /*break*/, 6]; case 5: this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("Invalid track", track); _f.label = 6; case 6: return [2 /*return*/]; } }); }); }; SFUHandler.prototype.createDataChannel = function () { var _a, _b; return __awaiter(this, void 0, void 0, function () { var track, webcamProducer; return __generator(this, function (_c) { switch (_c.label) { case 0: if (!(this.dataProducers.length === 0)) return [3 /*break*/, 2]; track = new Track((_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getSelfParticipant(), true, TrackKind.DataChannel, undefined); return [4 /*yield*/, ((_b = this.sendTransport) === null || _b === void 0 ? void 0 : _b.produceData({ appData: track }))]; case 1: webcamProducer = _c.sent(); if (webcamProducer) { this.dataProducers.push(webcamProducer); } _c.label = 2; case 2: return [2 /*return*/]; } }); }); }; SFUHandler.prototype.onParticipantUpdated = function () { var _a; if (this.producers) { if (((_a = this.meetingStartRequest) === null || _a === void 0 ? void 0 : _a.shouldPauseUploadingStreamOnSingleParticipant) && (!this.communicationHandler || this.communicationHandler.getAllParticipants().length < 2)) { this.producers.forEach(function (producer) { producer.pause(); }); } else { this.producers.forEach(function (producer) { producer.resume(); }); } } }; SFUHandler.prototype.sendMessageViaDataChannel = function (messagePayload) { if (this.dataProducers && this.dataProducers.length > 0) { this.dataProducers[0].send(JSON.stringify(messagePayload)); } }; SFUHandler.prototype.init = function (isForceFully) { if (isForceFully === void 0) { isForceFully = false; } return __awaiter(this, void 0, void 0, function () { var messageJson; return __generator(this, function (_a) { if (this.isInitDone && isForceFully === false) { return [2 /*return*/]; } this.isInitDone = true; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("SFU Init"); messageJson = { to: "self", type: SFUMessageType.GetRouterRtpCapabilities, message: SFUMessageType.GetRouterRtpCapabilities }; this.sendSFUMessageToSocket(messageJson); this.addObserverForDevice(); return [2 /*return*/]; }); }); }; SFUHandler.prototype.onTransportNotFound = function (data) { var _a; return __awaiter(this, void 0, void 0, function () { var _b, _c, producer, _d, _e, consumer, messageJson; var e_2, _f, e_3, _g; return __generator(this, function (_h) { try { for (_b = __values(this.producers), _c = _b.next(); !_c.done; _c = _b.next()) { producer = _c.value; if (producer) { producer.close(); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_f = _b.return)) _f.call(_b); } finally { if (e_2) throw e_2.error; } } try { for (_d = __values(this.consumers), _e = _d.next(); !_e.done; _e = _d.next()) { consumer = _e.value; if (consumer) { try { (_a = consumer.track) === null || _a === void 0 ? void 0 : _a.stop(); } catch (err) { } consumer.close(); } } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_e && !_e.done && (_g = _d.return)) _g.call(_d); } finally { if (e_3) throw e_3.error; } } this.producers = []; this.consumers = []; if (this.consumerTransport) { this.consumerTransport.close(); this.consumerTransport = undefined; } if (this.sendTransport) { this.sendTransport.close(); this.sendTransport = undefined; } this.isProduceTrackIntialWorkDone = false; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("OnCreateTransportsForcefully"); messageJson = { to: "self", type: SFUMessageType.OnCreateTransportsForcefully, message: SFUMessageType.OnCreateTransportsForcefully }; this.sendSFUMessageToSocket(messageJson); return [2 /*return*/]; }); }); }; SFUHandler.prototype.restartTransport = function () { this.onTransportNotFound(undefined); }; SFUHandler.prototype.addObserverForDevice = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { this.getDevice().observer.on("newtransport", function (transport) { transport.on("connect", function (transportLocalParameters, _callback, errback) { return __awaiter(_this, void 0, void 0, function () { var messageJson; return __generator(this, function (_a) { this.transportCallBacks[transport.id] = _callback; messageJson = { to: "self", type: SFUMessageType.OnTransportConnect, message: { type: transport.appData.type, transportId: transport.id, dtlsParameters: transportLocalParameters.dtlsParameters } }; this.sendSFUMessageToSocket(messageJson); return [2 /*return*/]; }); }); }); }); return [2 /*return*/]; }); }); }; SFUHandler.prototype.onAllProducers = function (data) { return __awaiter(this, void 0, void 0, function () { var allProducers; var _this = this; return __generator(this, function (_a) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("onAllProducers"); if (this.consumerTransport) { allProducers = data.message.producers; allProducers.forEach(function (eachProducer) { var producerId = eachProducer.id; var consumedProducer = _this.consumers.find(function (eachConsumer) { return eachConsumer.producerId === producerId; }); if (!consumedProducer || consumedProducer.closed) { if (consumedProducer) { consumedProducer.close(); _this.consumers = _this.consumers.filter(function (eachConsumer) { return eachConsumer.producerId !== producerId; }); } _this.onNewProducer({ data: { message: { producer: eachProducer } } }); } }); } return [2 /*return*/]; }); }); }; SFUHandler.prototype.onRouterRtpCapabilities = function (data) { var _a; try { if (this.getDevice() && ((_a = this.getDevice()) === null || _a === void 0 ? void 0 : _a.loaded)) { return; } if (data && data.message && data.message.rtpCapabilities) { this.routerRtpCapabilities = data.message.rtpCapabilities; var routerRtpCapabilities = this.routerRtpCapabilities; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log(routerRtpCapabilities); this.getDevice().load({ routerRtpCapabilities: routerRtpCapabilities }); this.isProduceTrackIntialWorkDone = false; //Create transport this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("OnCreateTransports onRouterRtpCapabilities"); var messageJson = { to: "self", type: SFUMessageType.OnCreateTransports, message: SFUMessageType.OnCreateTransports }; this.sendSFUMessageToSocket(messageJson); } } catch (err) { } }; SFUHandler.prototype.onTransportConnectDone = function (data) { if (data && data.message && data.message.transportId) { var transportId = data.message.transportId; var callBack = this.transportCallBacks[transportId]; if (callBack) { callBack(); delete this.transportCallBacks[transportId]; } } }; SFUHandler.prototype.onSendTransport = function (data) { return __awaiter(this, void 0, void 0, function () { var transport; var _this = this; return __generator(this, function (_a) { if (data && data.message && data.message.transport) { transport = data.message.transport; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log(" onSendTransport start", transport, this.getDevice()); this.sendTransport = this.getDevice().createSendTransport(transport); this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log(" onSendTransport created", transport, this.getDevice()); this.sendTransport.on('produce', function (producerLocalParameters, callback, errback) { var _a; _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log(" onSendTransport produce"); _this.transportCallBacks[producerLocalParameters.appData.trackId] = callback; _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("OnTransportProduceSyncRequest"); var messageJson = { to: "self", type: SFUMessageType.OnTransportProduceSyncRequest, message: { type: producerLocalParameters.appData.type, transportId: (_a = _this.sendTransport) === null || _a === void 0 ? void 0 : _a.id, kind: producerLocalParameters.kind, rtpParameters: producerLocalParameters.rtpParameters, appData: producerLocalParameters.appData } }; _this.sendSFUMessageToSocket(messageJson); }); this.sendTransport.on("producedata", function (producerLocalParameters, callback, errback) { return __awaiter(_this, void 0, void 0, function () { var messageJson; var _a; return __generator(this, function (_b) { this.transportCallBacks[producerLocalParameters.appData.trackId] = callback; messageJson = { to: "self", type: SFUMessageType.OnTransportDataProduceSyncRequest, message: { type: 'send', transportId: (_a = this.sendTransport) === null || _a === void 0 ? void 0 : _a.id, sctpStreamParameters: producerLocalParameters.sctpStreamParameters, label: producerLocalParameters.label, appData: producerLocalParameters.appData } }; this.sendSFUMessageToSocket(messageJson); return [2 /*return*/]; }); }); }); this.sendTransport.on('connectionstatechange', function (newState) { var _a; _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("connectionstatechange sendTransport ", newState); if (newState === "disconnected" || newState === "failed") { (_a = _this.communicationHandler) === null || _a === void 0 ? void 0 : _a.onIceCandidateDisconnected(); } }); } this.produceTracks(); return [2 /*return*/]; }); }); }; SFUHandler.prototype.onConsumeTransportCreated = function (data) { var _this = this; if (data && data.message && data.message.transport) { var transport = data.message.transport; this.consumerTransport = this.getDevice().createRecvTransport(transport); this.consumerTransport.on("connectionstatechange", function (newState) { var _a; _this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("connectionstatechange consumerTransport ", newState); if (newState === "disconnected" || newState === "failed") { (_a = _this.communicationHandler) === null || _a === void 0 ? void 0 : _a.onIceCandidateDisconnected(); } }); } this.produceTracks(); }; SFUHandler.prototype.produceTracks = function () { var _this = this; var _a, _b; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("produceTracks", this.sendTransport, this.consumerTransport, this.isProduceTrackIntialWorkDone); if (!this.sendTransport || !this.consumerTransport || this.isProduceTrackIntialWorkDone) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("produceTracks", this.sendTransport, this.consumerTransport, this.isProduceTrackIntialWorkDone); return; } this.isProduceTrackIntialWorkDone = true; var selfTracks = (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.getAllSelfTracks(); this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("produceTracks selfTracks", selfTracks); if (selfTracks && selfTracks.length > 0) { selfTracks.forEach(function (track) { _this.sendTrack(track); }); this.sendMessageReadyToConsume(); } else { this.sendMessageReadyToConsume(); } //inform init is done(mainly used when restart SFU) (_b = this.communicationHandler) === null || _b === void 0 ? void 0 : _b.onSFUInitDone(); // if (this.meetingStartRequest?.isDataChannelRequired) { // this.createDataChannel() // } }; SFUHandler.prototype.onProduceSyncDone = function (data) { if (data.message.appData && data.message.appData.trackId && data.message.producerId) { var transportId = data.message.transportId; var callBack = this.transportCallBacks[data.message.appData.trackId]; if (callBack) { var id = data.message.producerId; callBack({ id: id }); delete this.transportCallBacks[data.message.appData.trackId]; } } }; SFUHandler.prototype.sendMessageReadyToConsume = function () { var messageJson = { to: "self", type: SFUMessageType.OnReadyToConsume, message: SFUMessageType.OnReadyToConsume }; this.sendSFUMessageToSocket(messageJson); }; SFUHandler.prototype.sendSFUMessageToSocket = function (messageJson) { var _a; this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("sendMessage sendSFUMessageToSocket", messageJson); (_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.sendWebSocketMessage(SFUMessageType.SFUMessage, messageJson); }; SFUHandler.prototype.onSocketMessage = function (websocketCallHandler) { if (websocketCallHandler.type === SFUMessageType.OnRouterRtpCapabilities) { this.onRouterRtpCapabilities(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnTransportConnectDone) { this.onTransportConnectDone(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnSendTransport) { this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("OnSendTransport"); this.onSendTransport(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnConsumeTransport) { this.onConsumeTransportCreated(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnNewProducer) { this.onNewProducer(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnServerConsumer) { this.onServerConsumer(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnConsumerLayerChange) { this.onConsumerLayerChange(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnConsumerScoreChange) { this.onConsumerScoreChange(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnProducerScoreChange) { this.onProducerScoreChange(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnProduceSyncDone) { this.onProduceSyncDone(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnSpeakerChanged) { this.onSpeakerChanged(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnAudioVolumeChanged) { this.onAudioVolumeChanged(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnTrackEnded) { this.onTrackEnded(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnTransportNotFound) { this.onTransportNotFound(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnRestartIceCandidateResponse) { this.onRestartIceCandidateResponse(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnAllProducers) { this.onAllProducers(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnProducerNotFound) { this.onProducerNotFound(websocketCallHandler.data); } else if (websocketCallHandler.type === SFUMessageType.OnConsumerNotFou