UNPKG

podchat-browser

Version:

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

640 lines (559 loc) 21.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.DeviceManager = DeviceManager; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); require("../constants.js"); var _errorHandler = require("../errorHandler.js"); function MediaStreamManager() { var deviceStreams = { videoIn: null, audioIn: null, audioOut: null, screenShare: null, deviceChangeFlag: false }; return { setAudioInput: function setAudioInput(stream) { deviceStreams.audioIn = stream; }, setVideoInput: function setVideoInput(stream) { deviceStreams.videoIn = stream; }, setScreenShareInput: function setScreenShareInput(stream) { deviceStreams.screenShare = stream; }, getVideoInput: function getVideoInput() { return deviceStreams.videoIn; }, getAudioInput: function getAudioInput() { return deviceStreams.audioIn; }, getScreenShareInput: function getScreenShareInput() { return deviceStreams.screenShare; }, stopAudioInput: function stopAudioInput() { return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (deviceStreams.audioIn) { _context.next = 2; break; } return _context.abrupt("return"); case 2: deviceStreams.audioIn.getTracks().forEach(function (track) { if (!!track) { track.stop(); } deviceStreams.audioIn = null; }); case 3: case "end": return _context.stop(); } } }, _callee); }))(); }, stopVideoInput: function stopVideoInput() { 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: if (deviceStreams.videoIn) { _context2.next = 2; break; } return _context2.abrupt("return"); case 2: deviceStreams.videoIn.getTracks().forEach(function (track) { track.stop(); deviceStreams.videoIn = null; }); case 3: case "end": return _context2.stop(); } } }, _callee2); }))(); }, stopScreenShareInput: function stopScreenShareInput() { return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() { return _regenerator["default"].wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (deviceStreams.screenShare) { _context3.next = 2; break; } return _context3.abrupt("return"); case 2: deviceStreams.screenShare.getTracks().forEach(function (track) { track.stop(); }); deviceStreams.screenShare = null; case 4: case "end": return _context3.stop(); } } }, _callee3); }))(); } }; } function DeviceManager(app) { var config = { mediaStreams: new MediaStreamManager(), streamsMetada: { audioInWatcherId: null }, permissionRequests: [], isProcessingPermissionRequests: false }; var deviceManager = { getInputDevicePermission: function getInputDevicePermission(_ref) { var _ref$audio = _ref.audio, audio = _ref$audio === void 0 ? false : _ref$audio, _ref$video = _ref.video, video = _ref$video === void 0 ? false : _ref$video; return new Promise(function (resolve, reject) { if (video && config.mediaStreams.getVideoInput()) { resolve(config.mediaStreams.getVideoInput()); return; } if (audio && config.mediaStreams.getAudioInput()) { resolve(config.mediaStreams.getAudioInput()); return; } navigator.mediaDevices.getUserMedia({ audio: audio, video: video }).then(function (stream) { if (audio) config.mediaStreams.setAudioInput(stream); if (video) config.mediaStreams.setVideoInput(stream); resolve(stream); })["catch"](function (error) { app.chatEvents.fireEvent('callEvents', { type: 'CALL_ERROR', code: audio ? 12401 : 12400, message: error // environmentDetails: getSDKCallDetails() }); reject(app.errorHandler.handleError(audio ? 12401 : 12400)); }); }); }, canChooseAudioOutputDevice: function canChooseAudioOutputDevice() { return !!navigator.mediaDevices.selectAudioOutput; }, changeAudioOutputDevice: function changeAudioOutputDevice() { if (!navigator.mediaDevices.selectAudioOutput) { console.warn("selectAudioOutput() not supported."); return; } //Display prompt and log selected device or error navigator.mediaDevices.selectAudioOutput().then(function (device) { console.log(device.kind + ": " + device.label + " id = " + device.deviceId); })["catch"](function (err) { console.log(err.name + ": " + err.message); }); }, replaceVideoStream: function replaceVideoStream(newStream, callback) { var call = app.call.currentCall(); if (call) { var user = app.call.currentCall().users().get(app.store.user.get().id); user.replaceVideoStream(newStream, callback); return; } else { config.mediaStreams.setVideoInput(newStream); } }, changeMediaDevice: function changeMediaDevice(params, callback) { var user = app.call.currentCall().users().get(app.store.user.get().id); var config = { deviceId: { exact: params.deviceId } }; if (params.deviceType === 'audioIn') { user.changeAudioStream(params.deviceId, callback); } else if (params.deviceType === 'audioOut') { app.call.currentCall().users().switchSpeakers(params.deviceId, callback); } else if (params.deviceType === 'videoIn') { config = Object.assign(config, { width: 320, framerate: 10 }); user.changeVideoStream(params.deviceId, callback); } // callback && callback({hasError: false, deviceId: params.deviceId}); }, getMediaDevices: function getMediaDevices(callback) { var _navigator$mediaDevic; if (!((_navigator$mediaDevic = navigator.mediaDevices) !== null && _navigator$mediaDevic !== void 0 && _navigator$mediaDevic.enumerateDevices)) { callback && callback({ hasError: true }); } else { navigator.mediaDevices.getUserMedia({ audio: true }).then(function (stream) { navigator.mediaDevices.enumerateDevices().then(function (devices) { var my_devices = { audioinput: [], videoinput: [], audiooutput: [] }; devices.forEach(function (device) { var _my_devices$kind; var kind = device.kind, label = device.label, deviceId = device.deviceId, groupId = device.groupId; var active; if (kind == 'videoinput') { active = deviceId == app.preferredMediaDevices.get('videoIn'); } else if (kind == 'audioinput') { active = deviceId == app.preferredMediaDevices.get('audioIn'); } else if (kind == 'audiooutput') { active = deviceId == app.preferredMediaDevices.get('audioOut'); } (_my_devices$kind = my_devices[kind]) === null || _my_devices$kind === void 0 ? void 0 : _my_devices$kind.push({ label: label, deviceId: deviceId, groupId: groupId, active: active }); }); // check browser is safari if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { var _my_devices$audiooutp; (_my_devices$audiooutp = my_devices['audiooutput']) === null || _my_devices$audiooutp === void 0 ? void 0 : _my_devices$audiooutp.push({ label: 'اسپیکر پیش فرض سیستم', deviceId: '', groupId: '', active: true }); } stream.getTracks().forEach(function (item) { return item.stop(); }); // deviceManager.mediaStreams.stopAudioInput(); callback && callback({ hasError: false, devices: my_devices }); })["catch"](function (err) { callback && callback({ hasError: false, message: err.message, devices: [] }); // reject(err) console.error("".concat(err.name, ": ").concat(err.message)); }); })["catch"](function (err) { callback && callback({ hasError: false, message: err.message, devices: [] }); // reject(err) console.error("".concat(err.name, ": ").concat(err.message)); }); if (!navigator.mediaDevices.ondevicechange) { navigator.mediaDevices.ondevicechange = deviceManager.handleDeviceChange; } } }, removeDuplicateGroupIds: function removeDuplicateGroupIds(input) { var repeated_group_id = ''; var hasDefault = { audioinput: false, videoinput: false, audiooutput: false }; var result = {}; var uniqueGroupIds = {}; var _loop = function _loop(key) { uniqueGroupIds[key] = new Set(); if (input.hasOwnProperty(key)) { result[key] = (0, _toConsumableArray2["default"])(input[key]).reverse().filter(function (item) { if (uniqueGroupIds[key].has(item.groupId)) { repeated_group_id = item.groupId; return false; } else { uniqueGroupIds[key].add(item.groupId); return true; } }); // change default value of object if groupId repeated var index = result[key].findIndex(function (data) { return data.groupId === repeated_group_id; }); if (index > -1) { hasDefault[key] = true; result[key][index]['default'] = true; } } // if no repeated groupId if (!hasDefault[key]) { result[key][result[key].length - 1]['default'] = true; } }; for (var key in input) { _loop(key); } return result; }, handleDeviceChange: function handleDeviceChange(event) { if (!deviceManager.deviceChangeFlag) { deviceManager.deviceChangeFlag = true; deviceManager.getMediaDevices(function (_ref2) { var hasError = _ref2.hasError, devices = _ref2.devices; app.chatEvents.fireEvent('callEvents', { type: 'USER_MEDIA_DEVICES_CHANGED', result: devices }); }); setTimeout(function () { deviceManager.deviceChangeFlag = false; }, 1000); } }, grantScreenSharePermission: function grantScreenSharePermission(_ref3) { var _ref3$closeStream = _ref3.closeStream, closeStream = _ref3$closeStream === void 0 ? false : _ref3$closeStream; var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; return new Promise(function (resolve, reject) { if (config.mediaStreams.getScreenShareInput()) { if (!config.mediaStreams.getScreenShareInput().active) { config.mediaStreams.stopScreenShareInput(); // resolve(config.mediaStreams.getScreenShareInput()); } else { // console.log("exists resolving") resolve(config.mediaStreams.getScreenShareInput()); return; } } navigator.mediaDevices.getDisplayMedia({ audio: false, video: true }).then(function (stream) { config.mediaStreams.setScreenShareInput(stream); if (closeStream) { config.mediaStreams.stopScreenShareInput(); } callback && callback({ hasError: false }); resolve(stream); })["catch"](function (e) { var error = app.errorHandler.raiseError(_errorHandler.errorList.SCREENSHARE_PERMISSION_ERROR, callback, true, { eventName: 'callEvents', eventType: 'CALL_ERROR' }); reject(error); }); }); }, executePermissionRequest: function executePermissionRequest(_ref4) { var video = _ref4.video, audio = _ref4.audio, closeStream = _ref4.closeStream, callback = _ref4.callback; config.isProcessingPermissionRequests = true; return new Promise( /*#__PURE__*/function () { var _ref5 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(resolve, reject) { var res, parsedError; return _regenerator["default"].wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.prev = 0; if (!audio) { _context4.next = 4; break; } _context4.next = 4; return deviceManager.getInputDevicePermission({ audio: audio }); case 4: if (!video) { _context4.next = 7; break; } _context4.next = 7; return deviceManager.getInputDevicePermission({ video: video }); case 7: if (closeStream) { if (audio) config.mediaStreams.stopAudioInput(); if (video) config.mediaStreams.stopVideoInput(); } if (callback) { res = { hasError: false }; if (video) { res.videoStream = config.mediaStreams.getVideoInput(); } if (audio) { res.audioStream = config.mediaStreams.getAudioInput(); } callback(res); } resolve({ hasError: false }); _context4.next = 17; break; case 12: _context4.prev = 12; _context4.t0 = _context4["catch"](0); parsedError = { hasError: true, errorCode: _context4.t0.code, errorMessage: _context4.t0.message }; if (callback) callback(parsedError); reject(parsedError); case 17: config.isProcessingPermissionRequests = false; return _context4.abrupt("return", deviceManager.maybeGoToNext()); case 19: case "end": return _context4.stop(); } } }, _callee4, null, [[0, 12]]); })); return function (_x, _x2) { return _ref5.apply(this, arguments); }; }()); }, maybeGoToNext: function maybeGoToNext() { if (!config.isProcessingPermissionRequests && config.permissionRequests.length) { deviceManager.executePermissionRequest(config.permissionRequests.shift()); } }, grantUserMediaDevicesPermissions: function grantUserMediaDevicesPermissions(_ref6) { var _ref6$video = _ref6.video, video = _ref6$video === void 0 ? false : _ref6$video, _ref6$audio = _ref6.audio, audio = _ref6$audio === void 0 ? false : _ref6$audio, _ref6$closeStream = _ref6.closeStream, closeStream = _ref6$closeStream === void 0 ? false : _ref6$closeStream; var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; if (app.preferredMediaDevices.get('videoIn')) { if (video) { if ((0, _typeof2["default"])(video) == 'object') { if (!video.deviceId) video.deviceId = { exact: app.preferredMediaDevices.get('videoIn') }; } else { video = { deviceId: { exact: app.preferredMediaDevices.get('videoIn') } }; } } } if (app.preferredMediaDevices.get('audioIn')) { if (audio) { if ((0, _typeof2["default"])(audio) == 'object') { if (!audio.deviceId) audio.deviceId = { exact: app.preferredMediaDevices.get('audioIn') }; } else { audio = { deviceId: { exact: app.preferredMediaDevices.get('audioIn') } }; } } } config.permissionRequests.push({ video: video, audio: audio, closeStream: closeStream, callback: callback }); deviceManager.maybeGoToNext(); }, mediaStreams: config.mediaStreams, watchAudioInputStream: function watchAudioInputStream(callErrorHandler) { config.streamsMetada.audioInWatcherId && clearInterval(config.streamsMetada.audioInWatcherId); config.streamsMetada.audioInWatcherId = setInterval(function () { var _config$mediaStreams$; if (!config.mediaStreams.getAudioInput()) { clearInterval(config.streamsMetada.audioInWatcherId); return; } var audioTracks = (_config$mediaStreams$ = config.mediaStreams.getAudioInput()) === null || _config$mediaStreams$ === void 0 ? void 0 : _config$mediaStreams$.getAudioTracks(); if (audioTracks.length === 0) { callErrorHandler(_errorHandler.errorList.NO_AUDIO_TRACKS_AVAILABLE, null, true, {}); clearInterval(config.streamsMetada.audioInWatcherId); // No audio from microphone has been captured return; } // We asked for the microphone so one track var track = audioTracks[0]; if (track.muted) { // Track is muted which means that the track is unable to provide media data. // When muted, a track can't be unmuted. // This track will no more provide data... callErrorHandler(_errorHandler.errorList.AUDIO_TRACK_MUTED, null, true, {}); clearInterval(config.streamsMetada.audioInWatcherId); } if (!track.enabled) { // Track is disabled (muted for telephonist) which means that the track provides silence instead of real data. // When disabled, a track can be enabled again. // When in that case, user can't be heard until track is enabled again. callErrorHandler(_errorHandler.errorList.AUDIO_TRACK_DISABLED, null, true, {}); } if (track.readyState === "ended") { // Possibly a disconnection of the device // When ended, a track can't be active again // This track will no more provide data callErrorHandler(_errorHandler.errorList.AUDIO_TRACK_ENDED, null, true, {}); clearInterval(config.streamsMetada.audioInWatcherId); } }, 10000); }, onCallEnd: function onCallEnd() { return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5() { return _regenerator["default"].wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: config.permissionRequests = []; config.isProcessingPermissionRequests = false; _context5.next = 4; return config.mediaStreams.stopAudioInput(); case 4: _context5.next = 6; return config.mediaStreams.stopVideoInput(); case 6: _context5.next = 8; return config.mediaStreams.stopScreenShareInput(); case 8: navigator.mediaDevices.ondevicechange = null; case 9: case "end": return _context5.stop(); } } }, _callee5); }))(); } }; return deviceManager; } ;