diff --git a/index.html b/index.html index 995d17b22..10530f8f8 100644 --- a/index.html +++ b/index.html @@ -19,7 +19,7 @@ - + diff --git a/libs/app.bundle.js b/libs/app.bundle.js index f2f27d49e..af1f9d130 100644 --- a/libs/app.bundle.js +++ b/libs/app.bundle.js @@ -285,7 +285,7 @@ var API = { }; module.exports = API; -},{"../../service/xmpp/XMPPEvents":86}],3:[function(require,module,exports){ +},{"../../service/xmpp/XMPPEvents":87}],3:[function(require,module,exports){ /* global Strophe, updateLargeVideo, focusedVideoSrc*/ // cache datachannels to avoid garbage collection @@ -607,7 +607,7 @@ LocalStream.prototype.getId = function () { module.exports = LocalStream; -},{"../../service/RTC/StreamEventTypes.js":81}],5:[function(require,module,exports){ +},{"../../service/RTC/StreamEventTypes.js":82}],5:[function(require,module,exports){ ////These lines should be uncommented when require works in app.js var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js"); var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); @@ -873,64 +873,56 @@ var RTC = { module.exports = RTC; -},{"../../service/RTC/MediaStreamTypes":78,"../../service/RTC/StreamEventTypes.js":81,"../../service/UI/UIEvents":82,"../../service/desktopsharing/DesktopSharingEventTypes":84,"../../service/xmpp/XMPPEvents":86,"./DataChannels":3,"./LocalStream.js":4,"./MediaStream.js":5,"./RTCUtils.js":7,"events":87}],7:[function(require,module,exports){ +},{"../../service/RTC/MediaStreamTypes":78,"../../service/RTC/StreamEventTypes.js":82,"../../service/UI/UIEvents":83,"../../service/desktopsharing/DesktopSharingEventTypes":85,"../../service/xmpp/XMPPEvents":87,"./DataChannels":3,"./LocalStream.js":4,"./MediaStream.js":5,"./RTCUtils.js":7,"events":88}],7:[function(require,module,exports){ var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js"); +var Resolutions = require("../../service/RTC/Resolutions"); + +var currentResolution = null; + +function getPreviousResolution(resolution) { + if(!Resolutions[resolution]) + return null; + var order = Resolutions[resolution].order; + var res = null; + var resName = null; + for(var i in Resolutions) + { + var tmp = Resolutions[i]; + if(res == null || (res.order < tmp.order && tmp.order < order)) + { + resName = i; + res = tmp; + } + } + return resName; +} function setResolutionConstraints(constraints, resolution, isAndroid) { if (resolution && !constraints.video || isAndroid) { constraints.video = { mandatory: {}, optional: [] };// same behaviour as true } - // see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions - switch (resolution) { - // 16:9 first - case '1080': - case 'fullhd': - constraints.video.mandatory.minWidth = 1920; - constraints.video.mandatory.minHeight = 1080; - break; - case '720': - case 'hd': - constraints.video.mandatory.minWidth = 1280; - constraints.video.mandatory.minHeight = 720; - break; - case '360': - constraints.video.mandatory.minWidth = 640; - constraints.video.mandatory.minHeight = 360; - break; - case '180': - constraints.video.mandatory.minWidth = 320; - constraints.video.mandatory.minHeight = 180; - break; - // 4:3 - case '960': - constraints.video.mandatory.minWidth = 960; - constraints.video.mandatory.minHeight = 720; - break; - case '640': - case 'vga': - constraints.video.mandatory.minWidth = 640; - constraints.video.mandatory.minHeight = 480; - break; - case '320': + + if(Resolutions[resolution]) + { + constraints.video.mandatory.minWidth = Resolutions[resolution].width; + constraints.video.mandatory.minHeight = Resolutions[resolution].height; + } + else + { + if (isAndroid) { constraints.video.mandatory.minWidth = 320; constraints.video.mandatory.minHeight = 240; - break; - default: - if (isAndroid) { - constraints.video.mandatory.minWidth = 320; - constraints.video.mandatory.minHeight = 240; - constraints.video.mandatory.maxFrameRate = 15; - } - break; + constraints.video.mandatory.maxFrameRate = 15; + } } + if (constraints.video.mandatory.minWidth) constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth; if (constraints.video.mandatory.minHeight) constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight; } - function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid) { var constraints = {audio: false, video: false}; @@ -1096,6 +1088,7 @@ RTCUtils.prototype.getUserMediaWithConstraints = function( um, success_callback, failure_callback, resolution,bandwidth, fps, desktopStream) { + currentResolution = resolution; // Check if we are running on Android device var isAndroid = navigator.userAgent.indexOf('Android') != -1; @@ -1154,28 +1147,58 @@ RTCUtils.prototype.getUserMediaWithConstraints = function( RTCUtils.prototype.obtainAudioAndVideoPermissions = function() { var self = this; // Get AV - var cb = function (stream) { - console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length); - self.handleLocalStream(stream); - }; - var self = this; + this.getUserMediaWithConstraints( ['audio', 'video'], - cb, - function (error) { - console.error('failed to obtain audio/video stream - trying audio only', error); - self.getUserMediaWithConstraints( - ['audio'], - cb, - function (error) { - console.error('failed to obtain audio/video stream - stop', error); - APP.UI.messageHandler.showError("Error", - "Failed to obtain permissions to use the local microphone" + - "and/or camera."); - } - ); + function (stream) { + self.successCallback(stream); }, - config.resolution || '360'); + function (error) { + self.errorCallback(error); + }, + config.resolution || '360'); +} + +RTCUtils.prototype.successCallback = function (stream) { + console.log('got', stream, stream.getAudioTracks().length, + stream.getVideoTracks().length); + this.handleLocalStream(stream); +}; + +RTCUtils.prototype.errorCallback = function (error) { + var self = this; + console.error('failed to obtain audio/video stream - trying audio only', error); + var resolution = getPreviousResolution(currentResolution); + if(typeof error == "object" && error.constraintName && error.name + && (error.name == "ConstraintNotSatisfiedError" || + error.name == "OverconstrainedError") && + (error.constraintName == "minWidth" || error.constraintName == "maxWidth" || + error.constraintName == "minHeight" || error.constraintName == "maxHeight") + && resolution != null) + { + self.getUserMediaWithConstraints(['audio', 'video'], + function (stream) { + return self.successCallback(stream); + }, function (error) { + return self.errorCallback(error); + }, resolution); + } + else + { + self.getUserMediaWithConstraints( + ['audio'], + function (stream) { + return self.successCallback(stream); + }, + function (error) { + console.error('failed to obtain audio/video stream - stop', error); + APP.UI.messageHandler.showError("Error", + "Failed to obtain permissions to use the local microphone" + + "and/or camera."); + } + ); + } + } RTCUtils.prototype.handleLocalStream = function(stream) @@ -1209,7 +1232,7 @@ RTCUtils.prototype.handleLocalStream = function(stream) module.exports = RTCUtils; -},{"../../service/RTC/RTCBrowserType.js":79}],8:[function(require,module,exports){ +},{"../../service/RTC/RTCBrowserType.js":79,"../../service/RTC/Resolutions":81}],8:[function(require,module,exports){ var UI = {}; var VideoLayout = require("./videolayout/VideoLayout.js"); @@ -1930,7 +1953,7 @@ UI.dockToolbar = function (isDock) { module.exports = UI; -},{"../../service/RTC/RTCEvents":80,"../../service/RTC/StreamEventTypes":81,"../../service/connectionquality/CQEvents":83,"../../service/desktopsharing/DesktopSharingEventTypes":84,"../../service/xmpp/XMPPEvents":86,"./audio_levels/AudioLevels.js":9,"./authentication/Authentication":11,"./avatar/Avatar":12,"./etherpad/Etherpad.js":13,"./prezi/Prezi.js":14,"./side_pannels/SidePanelToggler":16,"./side_pannels/chat/Chat.js":17,"./side_pannels/contactlist/ContactList":21,"./side_pannels/settings/Settings":22,"./side_pannels/settings/SettingsMenu":23,"./toolbars/BottomToolbar":24,"./toolbars/Toolbar":25,"./toolbars/ToolbarToggler":26,"./util/MessageHandler":28,"./util/NicknameHandler":29,"./util/UIUtil":30,"./videolayout/VideoLayout.js":32,"./welcome_page/RoomnameGenerator":33,"./welcome_page/WelcomePage":34,"events":87}],9:[function(require,module,exports){ +},{"../../service/RTC/RTCEvents":80,"../../service/RTC/StreamEventTypes":82,"../../service/connectionquality/CQEvents":84,"../../service/desktopsharing/DesktopSharingEventTypes":85,"../../service/xmpp/XMPPEvents":87,"./audio_levels/AudioLevels.js":9,"./authentication/Authentication":11,"./avatar/Avatar":12,"./etherpad/Etherpad.js":13,"./prezi/Prezi.js":14,"./side_pannels/SidePanelToggler":16,"./side_pannels/chat/Chat.js":17,"./side_pannels/contactlist/ContactList":21,"./side_pannels/settings/Settings":22,"./side_pannels/settings/SettingsMenu":23,"./toolbars/BottomToolbar":24,"./toolbars/Toolbar":25,"./toolbars/ToolbarToggler":26,"./util/MessageHandler":28,"./util/NicknameHandler":29,"./util/UIUtil":30,"./videolayout/VideoLayout.js":32,"./welcome_page/RoomnameGenerator":33,"./welcome_page/WelcomePage":34,"events":88}],9:[function(require,module,exports){ var CanvasUtil = require("./CanvasUtils"); var ASDrawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d'); @@ -4008,7 +4031,7 @@ var Chat = (function (my) { return my; }(Chat || {})); module.exports = Chat; -},{"../../../../service/UI/UIEvents":82,"../../toolbars/ToolbarToggler":26,"../../util/NicknameHandler":29,"../../util/UIUtil":30,"../SidePanelToggler":16,"./Commands":18,"./Replacement":19,"./smileys.json":20}],18:[function(require,module,exports){ +},{"../../../../service/UI/UIEvents":83,"../../toolbars/ToolbarToggler":26,"../../util/NicknameHandler":29,"../../util/UIUtil":30,"../SidePanelToggler":16,"./Commands":18,"./Replacement":19,"./smileys.json":20}],18:[function(require,module,exports){ var UIUtil = require("../../util/UIUtil"); /** @@ -4542,7 +4565,7 @@ var SettingsMenu = { module.exports = SettingsMenu; -},{"../../../../service/translation/languages":85,"../../avatar/Avatar":12,"../../util/UIUtil":30,"./Settings":22}],24:[function(require,module,exports){ +},{"../../../../service/translation/languages":86,"../../avatar/Avatar":12,"../../util/UIUtil":30,"./Settings":22}],24:[function(require,module,exports){ var PanelToggler = require("../side_pannels/SidePanelToggler"); var buttonHandlers = { @@ -5545,7 +5568,7 @@ var NickanameHandler = { }; module.exports = NickanameHandler; -},{"../../../service/UI/UIEvents":82}],30:[function(require,module,exports){ +},{"../../../service/UI/UIEvents":83}],30:[function(require,module,exports){ /** * Created by hristo on 12/22/14. */ @@ -8262,7 +8285,7 @@ var VideoLayout = (function (my) { }(VideoLayout || {})); module.exports = VideoLayout; -},{"../../../service/RTC/MediaStreamTypes":78,"../../../service/UI/UIEvents":82,"../audio_levels/AudioLevels":9,"../avatar/Avatar":12,"../etherpad/Etherpad":13,"../prezi/Prezi":14,"../side_pannels/chat/Chat":17,"../side_pannels/contactlist/ContactList":21,"../util/NicknameHandler":29,"../util/UIUtil":30,"./ConnectionIndicator":31}],33:[function(require,module,exports){ +},{"../../../service/RTC/MediaStreamTypes":78,"../../../service/UI/UIEvents":83,"../audio_levels/AudioLevels":9,"../avatar/Avatar":12,"../etherpad/Etherpad":13,"../prezi/Prezi":14,"../side_pannels/chat/Chat":17,"../side_pannels/contactlist/ContactList":21,"../util/NicknameHandler":29,"../util/UIUtil":30,"./ConnectionIndicator":31}],33:[function(require,module,exports){ //var nouns = [ //]; var pluralNouns = [ @@ -8680,7 +8703,7 @@ var ConnectionQuality = { }; module.exports = ConnectionQuality; -},{"../../service/connectionquality/CQEvents":83,"../../service/xmpp/XMPPEvents":86,"events":87}],36:[function(require,module,exports){ +},{"../../service/connectionquality/CQEvents":84,"../../service/xmpp/XMPPEvents":87,"events":88}],36:[function(require,module,exports){ /* global $, alert, changeLocalVideo, chrome, config, getConferenceHandler, getUserMediaWithConstraints */ /** * Indicates that desktop stream is currently in use(for toggle purpose). @@ -9005,7 +9028,7 @@ module.exports = { }; -},{"../../service/desktopsharing/DesktopSharingEventTypes":84,"events":87}],37:[function(require,module,exports){ +},{"../../service/desktopsharing/DesktopSharingEventTypes":85,"events":88}],37:[function(require,module,exports){ //maps keycode to character, id of popover for given function and function var shortcuts = { 67: { @@ -11335,7 +11358,7 @@ var statistics = module.exports = statistics; -},{"../../service/RTC/StreamEventTypes.js":81,"../../service/xmpp/XMPPEvents":86,"./LocalStatsCollector.js":43,"./RTPStatsCollector.js":44,"events":87}],46:[function(require,module,exports){ +},{"../../service/RTC/StreamEventTypes.js":82,"../../service/xmpp/XMPPEvents":87,"./LocalStatsCollector.js":43,"./RTPStatsCollector.js":44,"events":88}],46:[function(require,module,exports){ var i18n = require("i18next-client"); var languages = require("../../service/translation/languages"); var DEFAULT_LANG = languages.EN; @@ -11447,7 +11470,7 @@ module.exports = { } }; -},{"../../service/translation/languages":85,"i18next-client":61}],47:[function(require,module,exports){ +},{"../../service/translation/languages":86,"i18next-client":61}],47:[function(require,module,exports){ /* jshint -W117 */ var TraceablePeerConnection = require("./TraceablePeerConnection"); var SDPDiffer = require("./SDPDiffer"); @@ -14528,7 +14551,7 @@ module.exports = Moderator; -},{"../../service/xmpp/XMPPEvents":86}],53:[function(require,module,exports){ +},{"../../service/xmpp/XMPPEvents":87}],53:[function(require,module,exports){ /* global $, $iq, config, connection, focusMucJid, messageHandler, Moderator, Toolbar, Util */ var Moderator = require("./moderator"); @@ -15300,7 +15323,7 @@ module.exports = function(XMPP, eventEmitter) { }; -},{"../../service/xmpp/XMPPEvents":86,"./JingleSession":47,"./moderator":52}],55:[function(require,module,exports){ +},{"../../service/xmpp/XMPPEvents":87,"./JingleSession":47,"./moderator":52}],55:[function(require,module,exports){ /* jshint -W117 */ var JingleSession = require("./JingleSession"); @@ -15639,7 +15662,7 @@ module.exports = function(XMPP, eventEmitter) }; -},{"../../service/xmpp/XMPPEvents":86,"./JingleSession":47}],56:[function(require,module,exports){ +},{"../../service/xmpp/XMPPEvents":87,"./JingleSession":47}],56:[function(require,module,exports){ /* global Strophe */ module.exports = function () { @@ -16306,7 +16329,7 @@ var XMPP = { module.exports = XMPP; -},{"../../service/RTC/StreamEventTypes":81,"../../service/UI/UIEvents":82,"../../service/xmpp/XMPPEvents":86,"./SDP":48,"./moderator":52,"./recording":53,"./strophe.emuc":54,"./strophe.jingle":55,"./strophe.logger":56,"./strophe.moderate":57,"./strophe.rayo":58,"./strophe.util":59,"events":87,"pako":62}],61:[function(require,module,exports){ +},{"../../service/RTC/StreamEventTypes":82,"../../service/UI/UIEvents":83,"../../service/xmpp/XMPPEvents":87,"./SDP":48,"./moderator":52,"./recording":53,"./strophe.emuc":54,"./strophe.jingle":55,"./strophe.logger":56,"./strophe.moderate":57,"./strophe.rayo":58,"./strophe.util":59,"events":88,"pako":62}],61:[function(require,module,exports){ // i18next, v1.7.7 // Copyright (c)2014 Jan Mühlemann (jamuhl). // Distributed under MIT license @@ -24822,6 +24845,60 @@ var RTCEvents = { module.exports = RTCEvents; },{}],81:[function(require,module,exports){ +var Resolutions = { + "1080": { + width: 1920, + height: 1080, + order: 7 + }, + "fullhd": { + width: 1920, + height: 1080, + order: 7 + }, + "720": { + width: 1280, + height: 720, + order: 6 + }, + "hd": { + width: 1280, + height: 720, + order: 6 + }, + "960": { + width: 960, + height: 720, + order: 5 + }, + "640": { + width: 640, + height: 480, + order: 4 + }, + "vga": { + width: 640, + height: 480, + order: 4 + }, + "360": { + width: 640, + height: 360, + order: 3 + }, + "320": { + width: 320, + height: 240, + order: 2 + }, + "180": { + width: 320, + height: 180, + order: 1 + } +}; +module.exports = Resolutions; +},{}],82:[function(require,module,exports){ var StreamEventTypes = { EVENT_TYPE_LOCAL_CREATED: "stream.local_created", @@ -24835,14 +24912,14 @@ var StreamEventTypes = { }; module.exports = StreamEventTypes; -},{}],82:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ var UIEvents = { NICKNAME_CHANGED: "UI.nickname_changed", SELECTED_ENDPOINT: "UI.selected_endpoint", PINNED_ENDPOINT: "UI.pinned_endpoint" }; module.exports = UIEvents; -},{}],83:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ var CQEvents = { LOCALSTATS_UPDATED: "cq.localstats_updated", REMOTESTATS_UPDATED: "cq.remotestats_updated", @@ -24850,7 +24927,7 @@ var CQEvents = { }; module.exports = CQEvents; -},{}],84:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ var DesktopSharingEventTypes = { INIT: "ds.init", @@ -24860,7 +24937,7 @@ var DesktopSharingEventTypes = { }; module.exports = DesktopSharingEventTypes; -},{}],85:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ module.exports = { getLanguages : function () { var languages = []; @@ -24873,7 +24950,7 @@ module.exports = { }, EN: "en" } -},{}],86:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ var XMPPEvents = { CONFERENCE_CERATED: "xmpp.conferenceCreated.jingle", CALL_TERMINATED: "xmpp.callterminated.jingle", @@ -24900,7 +24977,7 @@ var XMPPEvents = { ETHERPAD: "xmpp.etherpad" }; module.exports = XMPPEvents; -},{}],87:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a diff --git a/modules/RTC/RTCUtils.js b/modules/RTC/RTCUtils.js index 31dd65001..addd4c965 100644 --- a/modules/RTC/RTCUtils.js +++ b/modules/RTC/RTCUtils.js @@ -1,60 +1,52 @@ var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js"); +var Resolutions = require("../../service/RTC/Resolutions"); + +var currentResolution = null; + +function getPreviousResolution(resolution) { + if(!Resolutions[resolution]) + return null; + var order = Resolutions[resolution].order; + var res = null; + var resName = null; + for(var i in Resolutions) + { + var tmp = Resolutions[i]; + if(res == null || (res.order < tmp.order && tmp.order < order)) + { + resName = i; + res = tmp; + } + } + return resName; +} function setResolutionConstraints(constraints, resolution, isAndroid) { if (resolution && !constraints.video || isAndroid) { constraints.video = { mandatory: {}, optional: [] };// same behaviour as true } - // see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions - switch (resolution) { - // 16:9 first - case '1080': - case 'fullhd': - constraints.video.mandatory.minWidth = 1920; - constraints.video.mandatory.minHeight = 1080; - break; - case '720': - case 'hd': - constraints.video.mandatory.minWidth = 1280; - constraints.video.mandatory.minHeight = 720; - break; - case '360': - constraints.video.mandatory.minWidth = 640; - constraints.video.mandatory.minHeight = 360; - break; - case '180': - constraints.video.mandatory.minWidth = 320; - constraints.video.mandatory.minHeight = 180; - break; - // 4:3 - case '960': - constraints.video.mandatory.minWidth = 960; - constraints.video.mandatory.minHeight = 720; - break; - case '640': - case 'vga': - constraints.video.mandatory.minWidth = 640; - constraints.video.mandatory.minHeight = 480; - break; - case '320': + + if(Resolutions[resolution]) + { + constraints.video.mandatory.minWidth = Resolutions[resolution].width; + constraints.video.mandatory.minHeight = Resolutions[resolution].height; + } + else + { + if (isAndroid) { constraints.video.mandatory.minWidth = 320; constraints.video.mandatory.minHeight = 240; - break; - default: - if (isAndroid) { - constraints.video.mandatory.minWidth = 320; - constraints.video.mandatory.minHeight = 240; - constraints.video.mandatory.maxFrameRate = 15; - } - break; + constraints.video.mandatory.maxFrameRate = 15; + } } + if (constraints.video.mandatory.minWidth) constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth; if (constraints.video.mandatory.minHeight) constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight; } - function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid) { var constraints = {audio: false, video: false}; @@ -220,6 +212,7 @@ RTCUtils.prototype.getUserMediaWithConstraints = function( um, success_callback, failure_callback, resolution,bandwidth, fps, desktopStream) { + currentResolution = resolution; // Check if we are running on Android device var isAndroid = navigator.userAgent.indexOf('Android') != -1; @@ -278,28 +271,58 @@ RTCUtils.prototype.getUserMediaWithConstraints = function( RTCUtils.prototype.obtainAudioAndVideoPermissions = function() { var self = this; // Get AV - var cb = function (stream) { - console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length); - self.handleLocalStream(stream); - }; - var self = this; + this.getUserMediaWithConstraints( ['audio', 'video'], - cb, - function (error) { - console.error('failed to obtain audio/video stream - trying audio only', error); - self.getUserMediaWithConstraints( - ['audio'], - cb, - function (error) { - console.error('failed to obtain audio/video stream - stop', error); - APP.UI.messageHandler.showError("Error", - "Failed to obtain permissions to use the local microphone" + - "and/or camera."); - } - ); + function (stream) { + self.successCallback(stream); }, - config.resolution || '360'); + function (error) { + self.errorCallback(error); + }, + config.resolution || '360'); +} + +RTCUtils.prototype.successCallback = function (stream) { + console.log('got', stream, stream.getAudioTracks().length, + stream.getVideoTracks().length); + this.handleLocalStream(stream); +}; + +RTCUtils.prototype.errorCallback = function (error) { + var self = this; + console.error('failed to obtain audio/video stream - trying audio only', error); + var resolution = getPreviousResolution(currentResolution); + if(typeof error == "object" && error.constraintName && error.name + && (error.name == "ConstraintNotSatisfiedError" || + error.name == "OverconstrainedError") && + (error.constraintName == "minWidth" || error.constraintName == "maxWidth" || + error.constraintName == "minHeight" || error.constraintName == "maxHeight") + && resolution != null) + { + self.getUserMediaWithConstraints(['audio', 'video'], + function (stream) { + return self.successCallback(stream); + }, function (error) { + return self.errorCallback(error); + }, resolution); + } + else + { + self.getUserMediaWithConstraints( + ['audio'], + function (stream) { + return self.successCallback(stream); + }, + function (error) { + console.error('failed to obtain audio/video stream - stop', error); + APP.UI.messageHandler.showError("Error", + "Failed to obtain permissions to use the local microphone" + + "and/or camera."); + } + ); + } + } RTCUtils.prototype.handleLocalStream = function(stream) diff --git a/service/RTC/Resolutions.js b/service/RTC/Resolutions.js new file mode 100644 index 000000000..877ffe96e --- /dev/null +++ b/service/RTC/Resolutions.js @@ -0,0 +1,53 @@ +var Resolutions = { + "1080": { + width: 1920, + height: 1080, + order: 7 + }, + "fullhd": { + width: 1920, + height: 1080, + order: 7 + }, + "720": { + width: 1280, + height: 720, + order: 6 + }, + "hd": { + width: 1280, + height: 720, + order: 6 + }, + "960": { + width: 960, + height: 720, + order: 5 + }, + "640": { + width: 640, + height: 480, + order: 4 + }, + "vga": { + width: 640, + height: 480, + order: 4 + }, + "360": { + width: 640, + height: 360, + order: 3 + }, + "320": { + width: 320, + height: 240, + order: 2 + }, + "180": { + width: 320, + height: 180, + order: 1 + } +}; +module.exports = Resolutions; \ No newline at end of file