UNPKG

podchat-browser

Version:

Javascript SDK to use POD's Chat Service - Browser Only

987 lines (900 loc) 38.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.CallTopicManager = CallTopicManager; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _errorHandler = require("../errorHandler"); var _topicMetaDataManager = require("./topicMetaDataManager"); var _webrtcPeer = require("./webrtcPeer"); var _utility = _interopRequireDefault(require("../../utility/utility")); function CallTopicManager(_ref) { var app = _ref.app, callId = _ref.callId, userId = _ref.userId, user = _ref.user, topic = _ref.topic, mediaType = _ref.mediaType, direction = _ref.direction, deviceManager = _ref.deviceManager, isScreenShare = _ref.isScreenShare, onHTMLElement = _ref.onHTMLElement; var config = { callId: callId, userId: userId, user: user, state: 0, //0: disconnected, 1: connecting, 2: failed, 3: connected, 4: disconnected peer: null, topic: topic, mediaType: mediaType, direction: direction, isScreenShare: isScreenShare, sdpOfferRequestSent: false, htmlElement: null, topicMetaData: { interval: null, receivedSdpAnswer: false, connectionQualityInterval: null, poorConnectionCount: 0, poorConnectionResolvedCount: 0, isConnectionPoor: false }, isDestroyed: false, dataStream: null, statusEventsInterval: null, audioObject: null, alreadyAddedStreamTrackToElement: false }; var metadataInstance = new _topicMetaDataManager.topicMetaDataManager({ userId: userId, topic: topic }); var peerStates = { DISCONNECTED: 0, CONNECTING: 1, FAILED: 3, CONNECTED: 4 }; function removeStreamHTML() { if (!config.htmlElement) return; config.htmlElement.srcObject = null; config.htmlElement.remove(); if (document.getElementById('callUserVideo-' + config.user.videoTopicName)) { document.getElementById('callUserVideo-' + config.user.videoTopicName).remove(); } delete config.htmlElement; } function addStreamTrackToElement(stream) { if (config.alreadyAddedStreamTrackToElement) return; config.alreadyAddedStreamTrackToElement = true; config.dataStream = stream; if (config.mediaType == 'audio' && direction == 'receive') { config.audioObject = new Audio(); config.audioObject.srcObject = stream; config.audioObject.autoplay = true; config.audioObject.play(); publicized.watchAudioLevel(); } else if (config.mediaType == 'audio' && direction == 'send') { publicized.watchAudioLevel(); } else if (config.mediaType == 'video' && app.sdkParams.enableCallDivs) { var htmlElement = publicized.getHtmlElement(); htmlElement.mute = true; config.htmlElement.srcObject = stream; if (config.mediaType === "video") { config.htmlElement.load(); } onHTMLElement(config.htmlElement); } else if (config.mediaType == 'video' && !app.sdkParams.enableCallDivs) { app.call.currentCall().sendCallDivs(); } } var publicized = { getAudioObject: function getAudioObject() { return config.audioObject; }, getHtmlElement: function getHtmlElement() { var elementUniqueId = _utility["default"].generateUUID(); if (config.mediaType === 'video' && config.user.video && !config.htmlElement) { config.htmlElement = document.createElement('video'); var el = config.htmlElement; el.setAttribute('id', 'callUserVideo-' + config.user.videoTopicName); el.setAttribute('class', app.call.sharedVariables.callVideoTagClassName); el.setAttribute('playsinline', ''); el.setAttribute('muted', ''); el.setAttribute('autoplay', ''); el.setAttribute('data-uniqueId', elementUniqueId); el.setAttribute('width', app.call.sharedVariables.callVideoMinWidth + 'px'); el.setAttribute('height', app.call.sharedVariables.callVideoMinHeight + 'px'); // el.setAttribute('controls', ''); } return config.htmlElement; }, setPeerState: function setPeerState(state) { config.state = state; }, setIsScreenShare: function setIsScreenShare() { config.isScreenShare = true; }, setDirection: function setDirection(direction) { config.direction = direction; }, getPeer: function getPeer() { return config.peer; }, metadata: function metadata() { return metadataInstance; }, isPeerConnecting: function isPeerConnecting() { return config.state === peerStates.CONNECTING; }, isPeerFailed: function isPeerFailed() { return config.state === peerStates.FAILED; }, isPeerConnected: function isPeerConnected() { return config.state === peerStates.CONNECTED; }, isPeerDisconnected: function isPeerDisconnected() { return config.state === peerStates.DISCONNECTED; }, createTopic: function createTopic() { var manager = this; if (config.peer) { return; } publicized.resumeSendStream(); this.generateSdpOfferOptions().then(function (options) { app.sdkParams.consoleLogging && console.debug("[SDK][generateSdpOfferOptions] Options for this request have been resolved: ", { options: options }, "userId: ", config.userId, "topic: ", config.topic, "direction: ", config.direction); manager.establishPeerConnection(options); })["catch"](function (error) { console.error(error); }); }, generateSdpOfferOptions: function generateSdpOfferOptions() { var topicManager = this; return new Promise(function (resolve, reject) { var mediaConstraints = { audio: config.mediaType === 'audio', video: config.mediaType === 'video' }; if (config.direction === 'send' && config.mediaType === 'video') { mediaConstraints.video = { width: app.call.sharedVariables.callVideoMinWidth, height: app.call.sharedVariables.callVideoMinHeight, framerate: 15 }; } var options = { mediaConstraints: mediaConstraints, // iceTransportPolicy: 'relay', // onicecandidate: (candidate) => { // topicManager.watchForIceCandidates(candidate) // }, configuration: { iceServers: app.call.currentCall().getTurnServer(app.call.currentCall().callConfig()) } }; if (config.direction === 'send') { if (config.mediaType === 'video') { if (config.isScreenShare) { app.call.deviceManager.grantScreenSharePermission({ closeStream: false }).then(function (stream) { // let stream = currentCall().deviceManager().mediaStreams.getScreenShareInput(); if (!stream) { reject("Error: could not find screenShareInput"); } else { var onScreenShareEndCallback = function onScreenShareEndCallback(event) { // Click on browser UI stop sharing button if (publicized.isDestroyed()) return; stream.getVideoTracks()[0].removeEventListener("ended", onScreenShareEndCallback); if (!publicized.isDestroyed() && config.peer) { app.call.endScreenShare({ callId: config.callId }); } }; stream.getVideoTracks()[0].addEventListener("ended", onScreenShareEndCallback); options.stream = stream; options.sendSource = 'screen'; resolve(options); } })["catch"](function (error) { var errorString = "[SDK][grantScreenSharePermission][catch] " + JSON.stringify(error); console.error(errorString); app.call.currentCall().raiseCallError(_errorHandler.errorList.SCREENSHARE_PERMISSION_ERROR, null, true); publicized.explainUserMediaError(error, 'video', 'screen'); //resolve(options); app.call.endScreenShare({ callId: config.callId }); }); } else { app.call.deviceManager.grantUserMediaDevicesPermissions({ video: true }, function (result) { if (!result.hasError) { options.stream = app.call.deviceManager.mediaStreams.getVideoInput(); resolve(options); } else { reject(result); } }); } } else if (config.mediaType === 'audio') { app.call.deviceManager.grantUserMediaDevicesPermissions({ audio: true }, function (result) { if (!result.hasError) { var audioInput = app.call.deviceManager.mediaStreams.getAudioInput(); app.call.deviceManager.watchAudioInputStream(app.call.currentCall().raiseCallError); options.stream = audioInput; resolve(options); } else { reject(result); } }); } } else { resolve(options); } app.sdkParams.consoleLogging && console.log("[SDK][getSdpOfferOptions] ", "topic: ", config.topic, "mediaType: ", config.mediaType, "direction: ", config.direction, "options: ", options); }); }, establishPeerConnection: function establishPeerConnection(options) { var manager = this, user = config.user, topicElement = config.htmlElement; config.state = peerStates.CONNECTING; config.peer = new _webrtcPeer.WebrtcPeerConnection({ callId: config.callId, userId: config.userId, direction: config.direction, mediaType: config.mediaType, stream: options.stream, rtcPeerConfig: options.configuration, connectionStateChange: publicized.onConnectionStateChange, iceConnectionStateChange: publicized.onIceConnectionStateChange, onTrackCallback: addStreamTrackToElement }, function (err) { app.sdkParams.consoleLogging && console.debug("[SDK][establishPeerConnection][KurentoUtils.WebRtcPeer][WebRtcFunction]: ", { options: options }, "userId: ", config.userId, "topic: ", config.topic, "direction: ", config.direction); if (err) { var errorString = "[SDK][start/webRtc " + config.direction + " " + config.mediaType + " Peer] Error: " + publicized.explainUserMediaError(err, config.mediaType); console.error(errorString); app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: errorString, environmentDetails: app.call.currentCall().getCallDetails() }); return; } if (config.direction === 'send') { //publicized.startMedia(); if (app.call.currentCall().users().get(config.userId).user().cameraPaused) { publicized.pauseSendStream(); } } if (app.call.currentCall().callServerController().isJanus() && config.direction === 'receive') { var msgParams = { id: 'REGISTER_RECV_NOTIFICATION', topic: config.topic, mediaType: config.mediaType === 'video' ? 2 : 1 }; app.call.currentCall().sendCallMessage(msgParams, null, { timeoutTime: 4000, timeoutRetriesCount: 5 // timeoutCallback(){ // sendCallMessage(msgParams, null, {}); // } }); } else { config.peer.generateOffer(function (err, sdpOffer) { // app.sdkParams.consoleLogging && console.debug("[SDK][establishPeerConnection][generateOffer] GenerateOffer:: ", " sdpOffer: ", sdpOffer, " err: ", err); if (err) { var _errorString = "[SDK][start/WebRc " + config.direction + " " + config.mediaType + " Peer/generateOffer] " + err; console.error(_errorString); app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: _errorString, environmentDetails: app.call.currentCall().getCallDetails() }); return; } if (!config.sdpOfferRequestSent) { config.sdpOfferRequestSent = true; manager.sendSDPOfferRequestMessage(sdpOffer, 1); } }); } }); }, onConnectionStateChange: function onConnectionStateChange() { app.chatEvents.fireEvent("callStreamEvents", { type: 'WEBRTC_CONNECTION_STATE_CHANGE', callId: config.callId, userId: config.userId, topic: config.topic, direction: config.direction, connectionState: config.peer.peerConnection.connectionState, mediaType: config.mediaType }); if (!config.peer || publicized.isDestroyed()) { return; //avoid log errors } app.sdkParams.consoleLogging && console.log("[SDK][peerConnection.onconnectionstatechange] ", "peer: ", config.topic, " peerConnection.connectionState: ", config.peer.peerConnection.connectionState); if (config.peer.peerConnection.connectionState === 'disconnected') { publicized.removeConnectionQualityInterval(); publicized.removeAudioWatcherInterval(); } if (config.peer.peerConnection.connectionState === "failed") { if (publicized.isPeerFailed()) return; config.state = peerStates.FAILED; app.chatEvents.fireEvent('callEvents', { type: 'CALL_STATUS', callId: config.callId, errorCode: 7000, errorMessage: "Call Peer (".concat(config.topic, ") has failed!"), errorInfo: config.peer }); if (app.messenger.chatState) { publicized.shouldReconnectTopic(); } else { app.call.currentCall().queueMeForReconnect(publicized); } } if (config.peer.peerConnection.connectionState === 'connected') { config.state = peerStates.CONNECTED; if (config.direction === 'send' && !config.topicMetaData.connectionQualityInterval) { config.topicMetaData.connectionQualityInterval = setInterval(function () { publicized.checkConnectionQuality(); }, 1000); } } }, onIceConnectionStateChange: function onIceConnectionStateChange() { if (!config.peer || publicized.isDestroyed()) { return; //avoid log errors } app.sdkParams.consoleLogging && console.log("[SDK][oniceconnectionstatechange] ", "peer: ", config.topic, " peerConnection.connectionState: ", config.peer.peerConnection.iceConnectionState); if (config.peer.peerConnection.iceConnectionState === 'disconnected') { config.state = peerStates.DISCONNECTED; app.chatEvents.fireEvent('callEvents', { type: 'CALL_STATUS', callId: config.callId, errorCode: 7000, errorMessage: "Call Peer (".concat(config.topic, ") is disconnected!"), errorInfo: config.peer }); app.sdkParams.consoleLogging && console.log('[SDK][oniceconnectionstatechange]:[disconnected] Internet connection failed, Reconnect your call, topic:', config.topic); } if (config.peer.peerConnection.iceConnectionState === "failed") { if (publicized.isPeerFailed()) return; config.state = peerStates.FAILED; app.chatEvents.fireEvent('callEvents', { type: 'CALL_STATUS', callId: config.callId, errorCode: 7000, errorMessage: "Call Peer (".concat(config.topic, ") has failed!"), errorInfo: config.peer }); if (app.messenger.chatState) { publicized.shouldReconnectTopic(); } else { app.call.currentCall().queueMeForReconnect(publicized); } } if (config.peer.peerConnection.iceConnectionState === "connected") { config.state = peerStates.CONNECTED; if (config.direction === 'send' && !config.topicMetaData.connectionQualityInterval) { config.topicMetaData.connectionQualityInterval = setInterval(function () { publicized.checkConnectionQuality(); }, 1000); } if (config.mediaType === 'video') { if (config.direction === 'receive') { app.chatEvents.fireEvent("callEvents", { type: "RECEIVE_VIDEO_CONNECTION_ESTABLISHED", callId: config.callId, userId: config.userId }); } } config.state = peerStates.CONNECTED; // callRequestController.callEstablishedInMySide = true; app.chatEvents.fireEvent('callEvents', { type: 'CALL_STATUS', callId: config.callId, errorCode: 7000, errorMessage: "Call Peer (".concat(config.topic, ") has connected!"), errorInfo: config.peer }); } }, sendSDPOfferRequestMessage: function sendSDPOfferRequestMessage(sdpOffer, retries) { app.call.currentCall().sendCallMessage({ id: config.direction === 'send' ? 'SEND_SDP_OFFER' : 'RECIVE_SDP_OFFER', sdpOffer: sdpOffer, useComedia: true, useSrtp: false, topic: config.topic, mediaType: config.mediaType === 'video' ? 2 : 1 }, function (result) { if (result.done === 'FALSE' && retries > 0) { retries -= 1; publicized.sendSDPOfferRequestMessage(sdpOffer); } }, { timeoutTime: 4000, timeoutRetriesCount: 5 }); }, watchAudioLevel: function watchAudioLevel() { var stream = config.dataStream; var user = config.user, topicMetadata = config.topicMetaData; // Create and configure the audio pipeline var analyzer = app.call.audioCtx().createAnalyser(); analyzer.fftSize = 512; analyzer.smoothingTimeConstant = 0.1; var sourceNode = app.call.audioCtx().createMediaStreamSource(stream); sourceNode.connect(analyzer); // Analyze the sound topicMetadata.audioLevelInterval = setInterval(function () { // Compute the max volume level (-Infinity...0) var fftBins = new Float32Array(analyzer.frequencyBinCount); // Number of values manipulated for each sample analyzer.getFloatFrequencyData(fftBins); // audioPeakDB varies from -Infinity up to 0 var audioPeakDB = Math.max.apply(Math, (0, _toConsumableArray2["default"])(fftBins)); // Compute a wave (0...) var frequencyRangeData = new Uint8Array(analyzer.frequencyBinCount); analyzer.getByteFrequencyData(frequencyRangeData); var sum = frequencyRangeData.reduce(function (p, c) { return p + c; }, 0); // audioMeter varies from 0 to 10 var audioMeter = Math.sqrt(sum / frequencyRangeData.length); //console.log({audioMeter}, {audioPeakDB}); if (audioPeakDB > -50 && audioMeter > 0) { app.chatEvents.fireEvent('callStreamEvents', { type: 'USER_SPEAKING', callId: config.callId, userId: config.userId, audioLevel: convertToAudioLevel(audioPeakDB), isNoise: false, isMute: false }); } else if (audioPeakDB !== -Infinity && audioPeakDB < -60 && audioMeter > 0) { app.chatEvents.fireEvent('callStreamEvents', { type: 'USER_SPEAKING', callId: config.callId, userId: config.userId, audioLevel: 0, isNoise: true, isMute: false }); } else if (audioPeakDB === -Infinity && audioMeter == 0) { app.chatEvents.fireEvent('callStreamEvents', { type: 'USER_SPEAKING', callId: config.callId, userId: config.userId, audioLevel: 0, isNoise: false, isMute: true }); } }, 500); function convertToAudioLevel(soundPower) { if (soundPower <= -60) { return 0; } else if (soundPower >= -60 && soundPower < -50) { return 1; } else if (soundPower >= -50 && soundPower < -40) { return 2; } else if (soundPower >= -40 && soundPower < 30) { return 3; } else if (soundPower >= -30) { return 4; } } }, checkConnectionQuality: function checkConnectionQuality() { if (!app.call.currentCall() || !app.call.currentCall().users().get(config.userId) || !config.peer || !config.peer.peerConnection) { this.removeConnectionQualityInterval(); this.removeAudioWatcherInterval(); return; } config.peer.peerConnection.getStats(null).then(function (stats) { // console.log(' watchRTCPeerConnection:: window.setInterval then(stats:', stats) // let statsOutput = ""; var user = config.user, topicMetadata = config.topicMetaData; stats.forEach(function (report) { if (report && report.type && report.type === 'remote-inbound-rtp') { // statsOutput += `<h2>Report: ${report.type}</h2>\n<strong>ID:</strong> ${report.id}<br>\n` + // `<strong>Timestamp:</strong> ${report.timestamp}<br>\n`; // Now the statistics for this report; we intentially drop the ones we // sorted to the top above if (!report['roundTripTime'] || report['roundTripTime'] > 1) { if (topicMetadata.poorConnectionCount === 10) { app.call.currentCall().sendQualityCheckEvent({ userId: config.userId, topic: config.topic, mediaType: config.mediaType, isLongTime: true }); } if (topicMetadata.poorConnectionCount > 3 && !topicMetadata.isConnectionPoor) { app.sdkParams.consoleLogging && console.log('[SDK][checkConnectionQuality] Poor connection detected...'); app.call.currentCall().sendQualityCheckEvent({ userId: config.userId, topic: config.topic, mediaType: config.mediaType }); topicMetadata.isConnectionPoor = true; topicMetadata.poorConnectionCount = 0; topicMetadata.poorConnectionResolvedCount = 0; } else { config.topicMetaData.poorConnectionCount++; } } else if (report['roundTripTime'] || report['roundTripTime'] < 1) { if (topicMetadata.poorConnectionResolvedCount > 3 && topicMetadata.isConnectionPoor) { topicMetadata.poorConnectionResolvedCount = 0; topicMetadata.poorConnectionCount = 0; topicMetadata.isConnectionPoor = false; app.call.currentCall().sendQualityCheckEvent({ userId: config.userId, topic: config.topic, mediaType: config.mediaType, isResolved: true }); } else { topicMetadata.poorConnectionResolvedCount++; } } // Object.keys(report).forEach(function (statName) { // if (statName !== "id" && statName !== "timestamp" && statName !== "type") { // statsOutput += `<strong>${statName}:</strong> ${report[statName]}<br>\n`; // } // }); } }); // document.querySelector(".stats-box").innerHTML = statsOutput; }); }, removeConnectionQualityInterval: function removeConnectionQualityInterval() { if (config.topicMetaData) { config.topicMetaData.poorConnectionCount = 0; clearInterval(config.topicMetaData.connectionQualityInterval); } }, removeAudioWatcherInterval: function removeAudioWatcherInterval() { if (config.topicMetaData) { clearInterval(config.topicMetaData.audioLevelInterval); } }, shouldReconnectTopic: function shouldReconnectTopic() { var iceConnectionState = config.peer.peerConnection.iceConnectionState; if (!publicized.isDestroyed()) { if (config.peer && iceConnectionState != 'connected') { app.logger.log(app.logger.tags.CALL_PROCESS.id, "[shouldReconnectTopic]", " Call Peer (".concat(config.topic, ") is not in connected state, reconnecting peer ...! ")); app.call.currentCall().users().get(config.userId).reconnectTopic(config.mediaType); } } }, explainUserMediaError: function explainUserMediaError(err, deviceType, deviceSource) { /*app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', code: 7000, message: err, environmentDetails: getSDKCallDetails() });*/ var n = err.name; if (n === 'NotFoundError' || n === 'DevicesNotFoundError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: "Missing " + (deviceType === 'video' ? 'webcam' : 'mice') + " for required tracks", environmentDetails: app.call.currentCall().getCallDetails() }); alert("Missing " + (deviceType === 'video' ? 'webcam' : 'mice') + " for required tracks"); return "Missing " + (deviceType === 'video' ? 'webcam' : 'mice') + " for required tracks"; } else if (n === 'NotReadableError' || n === 'TrackStartError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: (deviceType === 'video' ? 'Webcam' : 'Mice') + " is already in use", environmentDetails: app.call.currentCall().getCallDetails() }); alert((deviceType === 'video' ? 'Webcam' : 'Mice') + " is already in use"); return (deviceType === 'video' ? 'Webcam' : 'Mice') + " is already in use"; } else if (n === 'OverconstrainedError' || n === 'ConstraintNotSatisfiedError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: (deviceType === 'video' ? 'Webcam' : 'Mice') + " doesn't provide required tracks", environmentDetails: app.call.currentCall().getCallDetails() }); alert((deviceType === 'video' ? 'Webcam' : 'Mice') + " doesn't provide required tracks"); return (deviceType === 'video' ? 'Webcam' : 'Mice') + " doesn't provide required tracks"; } else if (n === 'NotAllowedError' || n === 'PermissionDeniedError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: (deviceType === 'video' ? deviceSource === 'screen' ? 'ScreenShare' : 'Webcam' : 'Mice') + " permission has been denied by the user", environmentDetails: app.call.currentCall().getCallDetails() }); alert((deviceType === 'video' ? deviceSource === 'screen' ? 'ScreenShare' : 'Webcam' : 'Mice') + " permission has been denied by the user"); return (deviceType === 'video' ? deviceSource === 'screen' ? 'ScreenShare' : 'Webcam' : 'Mice') + " permission has been denied by the user"; } else if (n === 'TypeError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: "No media tracks have been requested", environmentDetails: app.call.currentCall().getCallDetails() }); return "No media tracks have been requested"; } else { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: "Unknown error: " + err, environmentDetails: app.call.currentCall().getCallDetails() }); return "Unknown error: " + err; } }, stopTopicOnServer: function stopTopicOnServer() { return new Promise(function (resolve) { app.callsManager.get(config.callId).sendCallMessage({ id: 'STOP', topic: config.topic }, function (result) { if (result.done === 'TRUE' || result.done === 'SKIP') { // manager.reconnectTopic(); resolve(); } else { console.warn("[SDK] SDK tried to stop the topic but failed.", config.topic); } }, {}); }); }, removeTopic: function () { var _removeTopic = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { var manager; return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: manager = this; if (direction == 'send') publicized.pauseSendStream(); if (config.peer) { manager.removeConnectionQualityInterval(); manager.removeAudioWatcherInterval(); removeStreamHTML(); if (config.audioObject) { config.audioObject.srcObject = null; delete config.audioObject; } config.peer.dispose(); config.peer = null; config.state = peerStates.DISCONNECTED; } case 3: case "end": return _context.stop(); } } }, _callee, this); })); function removeTopic() { return _removeTopic.apply(this, arguments); } return removeTopic; }(), topicMetaData: function topicMetaData() { return config.topicMetaData; }, /** * Pauses camera-send without closing its topic * @param params * @param callback */ pauseSendStream: function pauseSendStream() { var localStream; switch (config.mediaType) { case 'audio': localStream = app.call.deviceManager.mediaStreams.getAudioInput(); break; case 'video': if (config.isScreenShare) { localStream = app.call.deviceManager.mediaStreams.getScreenShareInput(); } else { localStream = app.call.deviceManager.mediaStreams.getVideoInput(); } } if (localStream) localStream.getTracks()[0].enabled = false; }, resumeSendStream: function resumeSendStream() { var localStream; switch (config.mediaType) { case 'audio': localStream = app.call.deviceManager.mediaStreams.getAudioInput(); break; case 'video': if (config.isScreenShare) { localStream = app.call.deviceManager.mediaStreams.getScreenShareInput(); } else { localStream = app.call.deviceManager.mediaStreams.getVideoInput(); } } if (localStream) localStream.getTracks()[0].enabled = true; // if(config.peer && config.peer.getLocalStream()) // config.peer.getLocalStream().getTracks()[0].enabled = true; }, startMedia: function startMedia() { app.sdkParams.consoleLogging && console.log("[SDK][startMedia] called with: ", config.htmlElement); if (!config.htmlElement) return; config.htmlElement.play()["catch"](function (err) { if (err.name === 'NotAllowedError') { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', callId: config.callId, code: 7000, message: "[startMedia] Browser doesn't allow playing media: " + err, environmentDetails: app.call.currentCall().getCallDetails() }); } }); }, restartMediaOnKeyFrame: function restartMediaOnKeyFrame(userId, timeouts) { if (app.call.currentCall().callServerController().isJanus()) return; for (var i = 0; i < timeouts.length; i++) { setTimeout(function () { if (!publicized.isDestroyed() && config.peer) publicized.restartMedia(); }, timeouts[i]); } }, restartMedia: function restartMedia() { if (!publicized.isDestroyed() && !app.call.currentCall().users().get(config.userId).user().cameraPaused && config.mediaType == 'video') { app.sdkParams.consoleLogging && console.log('[SDK] Sending Key Frame ...'); var el = document.getElementById('callUserVideo-' + config.user.videoTopicName); if (!el.srcObject) el.srcObject = config.dataStream; var videoElement = el; var videoTrack = videoElement.srcObject.getTracks()[0]; videoTrack.enabled = true; setTimeout(function () { videoTrack.enabled = false; setTimeout(function () { videoTrack.enabled = true; }, 1500); }, 1500); if (videoElement) { var width = config.isScreenShare ? app.call.currentCall().screenShareInfo.getWidth() : app.call.sharedVariables.callVideoMinWidth, height = config.isScreenShare ? app.call.currentCall().screenShareInfo.getHeight() : app.call.sharedVariables.callVideoMinHeight, rand = Math.random(), newWidth = width - 5, newHeight = height - 5; if (navigator && !!navigator.userAgent.match(/firefox/gi)) { // videoTrack.enable = false; newWidth = width - 150; newHeight = height - 150; videoTrack.applyConstraints({ // width: { // min: newWidth, // ideal: 1280 // }, // height: { // min: newHeight, // ideal: 720 // }, width: newWidth, height: newHeight, advanced: [{ aspectRatio: 1.77 }] }).then(function (res) { videoTrack.enabled = true; setTimeout(function () { videoTrack.applyConstraints({ width: width, height: height }); }, 1500); })["catch"](function (e) { return app.sdkParams.consoleLogging && console.log(e); }); } else { videoTrack.applyConstraints({ width: newWidth, height: newHeight, advanced: [{ aspectRatio: 1.777 }] }).then(function (res) {})["catch"](function (e) { return app.sdkParams.consoleLogging && console.log(e); }); setTimeout(function () { videoTrack.applyConstraints({ width: width, height: height }); }, 1500); } } } }, startStatusPrint: function startStatusPrint() { config.statusEventsInterval && clearInterval(config.statusEventsInterval); config.statusEventsInterval = setInterval(function () { if (!config.peer) { config.statusEventsInterval && clearInterval(config.statusEventsInterval); return; } config.peer.peerConnection.getStats(null).then(function (stats) { // console.log(' watchRTCPeerConnection:: window.setInterval then(stats:', stats) var statsOutput = ""; var user = config.user, topicMetadata = config.topicMetaData; stats.forEach(function (report) { // if(report && report.type && report.type === 'remote-inbound-rtp') { statsOutput += "<h2>Report: ".concat(report.type, "</h2>\n<strong>ID:</strong> ").concat(report.id, "<br>\n") + "<strong>Timestamp:</strong> ".concat(report.timestamp, "<br>\n"); // Now the statistics for this report; we intentially drop the ones we // sorted to the top above Object.keys(report).forEach(function (statName) { if (statName !== "id" && statName !== "timestamp" && statName !== "type") { statsOutput += "<strong>".concat(statName, ":</strong> ").concat(report[statName], "<br>\n"); } }); // } }); document.getElementById("peer-status-container").innerHTML = statsOutput; // document.querySelector(".stats-box").innerHTML = statsOutput; }); }, 1000); }, getStream: function getStream() { return config.dataStream; }, updateStream: function updateStream(stream) { if (mediaType == 'audio') { publicized.removeAudioWatcherInterval(); config.dataStream = stream; publicized.watchAudioLevel(); } else { config.dataStream = stream; config.htmlElement.srcObject = stream; } config.peer.updateStream(stream); }, stopStatusPrint: function stopStatusPrint() { config.statusEventsInterval && clearInterval(config.statusEventsInterval); }, changeAudioObject: function changeAudioObject(deviceId) { config.audioObject.srcObject = null; config.audioObject.srcObject = config.dataStream; config.audioObject.setSinkId(deviceId); }, isDestroyed: function isDestroyed() { return config.isDestroyed; }, destroy: function destroy() { return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: config.isDestroyed = true; // publicized.removeStreamHTML(); _context2.next = 3; return publicized.removeTopic(); case 3: case "end": return _context2.stop(); } } }, _callee2); }))(); } }; return publicized; }