Quellcode durchsuchen

Changes getUserMedia implementation to try lower resolution if the configured one is not supported.

j8
hristoterezov vor 10 Jahren
Ursprung
Commit
2362770cce
4 geänderte Dateien mit 295 neuen und 142 gelöschten Zeilen
  1. 1
    1
      index.html
  2. 159
    82
      libs/app.bundle.js
  3. 82
    59
      modules/RTC/RTCUtils.js
  4. 53
    0
      service/RTC/Resolutions.js

+ 1
- 1
index.html Datei anzeigen

19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21
     <script src="interface_config.js?v=5"></script>
21
     <script src="interface_config.js?v=5"></script>
22
-    <script src="libs/app.bundle.js?v=9"></script>
22
+    <script src="libs/app.bundle.js?v=10"></script>
23
 
23
 
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
25
     <link rel="stylesheet" href="css/font.css?v=6"/>
25
     <link rel="stylesheet" href="css/font.css?v=6"/>

+ 159
- 82
libs/app.bundle.js Datei anzeigen

285
 };
285
 };
286
 
286
 
287
 module.exports = API;
287
 module.exports = API;
288
-},{"../../service/xmpp/XMPPEvents":86}],3:[function(require,module,exports){
288
+},{"../../service/xmpp/XMPPEvents":87}],3:[function(require,module,exports){
289
 /* global Strophe, updateLargeVideo, focusedVideoSrc*/
289
 /* global Strophe, updateLargeVideo, focusedVideoSrc*/
290
 
290
 
291
 // cache datachannels to avoid garbage collection
291
 // cache datachannels to avoid garbage collection
607
 
607
 
608
 module.exports = LocalStream;
608
 module.exports = LocalStream;
609
 
609
 
610
-},{"../../service/RTC/StreamEventTypes.js":81}],5:[function(require,module,exports){
610
+},{"../../service/RTC/StreamEventTypes.js":82}],5:[function(require,module,exports){
611
 ////These lines should be uncommented when require works in app.js
611
 ////These lines should be uncommented when require works in app.js
612
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
612
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
613
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
613
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
873
 
873
 
874
 module.exports = RTC;
874
 module.exports = RTC;
875
 
875
 
876
-},{"../../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){
876
+},{"../../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){
877
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
877
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
878
+var Resolutions = require("../../service/RTC/Resolutions");
879
+
880
+var currentResolution = null;
881
+
882
+function getPreviousResolution(resolution) {
883
+    if(!Resolutions[resolution])
884
+        return null;
885
+    var order = Resolutions[resolution].order;
886
+    var res = null;
887
+    var resName = null;
888
+    for(var i in Resolutions)
889
+    {
890
+        var tmp = Resolutions[i];
891
+        if(res == null || (res.order < tmp.order && tmp.order < order))
892
+        {
893
+            resName = i;
894
+            res = tmp;
895
+        }
896
+    }
897
+    return resName;
898
+}
878
 
899
 
879
 function setResolutionConstraints(constraints, resolution, isAndroid)
900
 function setResolutionConstraints(constraints, resolution, isAndroid)
880
 {
901
 {
881
     if (resolution && !constraints.video || isAndroid) {
902
     if (resolution && !constraints.video || isAndroid) {
882
         constraints.video = { mandatory: {}, optional: [] };// same behaviour as true
903
         constraints.video = { mandatory: {}, optional: [] };// same behaviour as true
883
     }
904
     }
884
-    // see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions
885
-    switch (resolution) {
886
-        // 16:9 first
887
-        case '1080':
888
-        case 'fullhd':
889
-            constraints.video.mandatory.minWidth = 1920;
890
-            constraints.video.mandatory.minHeight = 1080;
891
-            break;
892
-        case '720':
893
-        case 'hd':
894
-            constraints.video.mandatory.minWidth = 1280;
895
-            constraints.video.mandatory.minHeight = 720;
896
-            break;
897
-        case '360':
898
-            constraints.video.mandatory.minWidth = 640;
899
-            constraints.video.mandatory.minHeight = 360;
900
-            break;
901
-        case '180':
902
-            constraints.video.mandatory.minWidth = 320;
903
-            constraints.video.mandatory.minHeight = 180;
904
-            break;
905
-        // 4:3
906
-        case '960':
907
-            constraints.video.mandatory.minWidth = 960;
908
-            constraints.video.mandatory.minHeight = 720;
909
-            break;
910
-        case '640':
911
-        case 'vga':
912
-            constraints.video.mandatory.minWidth = 640;
913
-            constraints.video.mandatory.minHeight = 480;
914
-            break;
915
-        case '320':
905
+
906
+    if(Resolutions[resolution])
907
+    {
908
+        constraints.video.mandatory.minWidth = Resolutions[resolution].width;
909
+        constraints.video.mandatory.minHeight = Resolutions[resolution].height;
910
+    }
911
+    else
912
+    {
913
+        if (isAndroid) {
916
             constraints.video.mandatory.minWidth = 320;
914
             constraints.video.mandatory.minWidth = 320;
917
             constraints.video.mandatory.minHeight = 240;
915
             constraints.video.mandatory.minHeight = 240;
918
-            break;
919
-        default:
920
-            if (isAndroid) {
921
-                constraints.video.mandatory.minWidth = 320;
922
-                constraints.video.mandatory.minHeight = 240;
923
-                constraints.video.mandatory.maxFrameRate = 15;
924
-            }
925
-            break;
916
+            constraints.video.mandatory.maxFrameRate = 15;
917
+        }
926
     }
918
     }
919
+
927
     if (constraints.video.mandatory.minWidth)
920
     if (constraints.video.mandatory.minWidth)
928
         constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth;
921
         constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth;
929
     if (constraints.video.mandatory.minHeight)
922
     if (constraints.video.mandatory.minHeight)
930
         constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight;
923
         constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight;
931
 }
924
 }
932
 
925
 
933
-
934
 function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid)
926
 function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid)
935
 {
927
 {
936
     var constraints = {audio: false, video: false};
928
     var constraints = {audio: false, video: false};
1096
     um, success_callback, failure_callback, resolution,bandwidth, fps,
1088
     um, success_callback, failure_callback, resolution,bandwidth, fps,
1097
     desktopStream)
1089
     desktopStream)
1098
 {
1090
 {
1091
+    currentResolution = resolution;
1099
     // Check if we are running on Android device
1092
     // Check if we are running on Android device
1100
     var isAndroid = navigator.userAgent.indexOf('Android') != -1;
1093
     var isAndroid = navigator.userAgent.indexOf('Android') != -1;
1101
 
1094
 
1154
 RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
1147
 RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
1155
     var self = this;
1148
     var self = this;
1156
     // Get AV
1149
     // Get AV
1157
-    var cb = function (stream) {
1158
-        console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length);
1159
-        self.handleLocalStream(stream);
1160
-    };
1161
-    var self = this;
1150
+
1162
     this.getUserMediaWithConstraints(
1151
     this.getUserMediaWithConstraints(
1163
         ['audio', 'video'],
1152
         ['audio', 'video'],
1164
-        cb,
1153
+        function (stream) {
1154
+            self.successCallback(stream);
1155
+        },
1165
         function (error) {
1156
         function (error) {
1166
-            console.error('failed to obtain audio/video stream - trying audio only', error);
1167
-            self.getUserMediaWithConstraints(
1168
-                ['audio'],
1169
-                cb,
1170
-                function (error) {
1171
-                    console.error('failed to obtain audio/video stream - stop', error);
1172
-                    APP.UI.messageHandler.showError("Error",
1173
-                            "Failed to obtain permissions to use the local microphone" +
1174
-                            "and/or camera.");
1175
-                }
1176
-            );
1157
+            self.errorCallback(error);
1177
         },
1158
         },
1178
-            config.resolution || '360');
1159
+        config.resolution || '360');
1160
+}
1161
+
1162
+RTCUtils.prototype.successCallback = function (stream) {
1163
+    console.log('got', stream, stream.getAudioTracks().length,
1164
+        stream.getVideoTracks().length);
1165
+    this.handleLocalStream(stream);
1166
+};
1167
+
1168
+RTCUtils.prototype.errorCallback = function (error) {
1169
+    var self = this;
1170
+    console.error('failed to obtain audio/video stream - trying audio only', error);
1171
+    var resolution = getPreviousResolution(currentResolution);
1172
+    if(typeof error == "object" && error.constraintName && error.name
1173
+        && (error.name == "ConstraintNotSatisfiedError" ||
1174
+            error.name == "OverconstrainedError") &&
1175
+        (error.constraintName == "minWidth" || error.constraintName == "maxWidth" ||
1176
+            error.constraintName == "minHeight" || error.constraintName == "maxHeight")
1177
+        && resolution != null)
1178
+    {
1179
+        self.getUserMediaWithConstraints(['audio', 'video'],
1180
+            function (stream) {
1181
+                return self.successCallback(stream);
1182
+            }, function (error) {
1183
+                return self.errorCallback(error);
1184
+            }, resolution);
1185
+    }
1186
+    else
1187
+    {
1188
+        self.getUserMediaWithConstraints(
1189
+            ['audio'],
1190
+            function (stream) {
1191
+                return self.successCallback(stream);
1192
+            },
1193
+            function (error) {
1194
+                console.error('failed to obtain audio/video stream - stop', error);
1195
+                APP.UI.messageHandler.showError("Error",
1196
+                        "Failed to obtain permissions to use the local microphone" +
1197
+                        "and/or camera.");
1198
+            }
1199
+        );
1200
+    }
1201
+
1179
 }
1202
 }
1180
 
1203
 
1181
 RTCUtils.prototype.handleLocalStream = function(stream)
1204
 RTCUtils.prototype.handleLocalStream = function(stream)
1209
 
1232
 
1210
 
1233
 
1211
 module.exports = RTCUtils;
1234
 module.exports = RTCUtils;
1212
-},{"../../service/RTC/RTCBrowserType.js":79}],8:[function(require,module,exports){
1235
+},{"../../service/RTC/RTCBrowserType.js":79,"../../service/RTC/Resolutions":81}],8:[function(require,module,exports){
1213
 var UI = {};
1236
 var UI = {};
1214
 
1237
 
1215
 var VideoLayout = require("./videolayout/VideoLayout.js");
1238
 var VideoLayout = require("./videolayout/VideoLayout.js");
1930
 module.exports = UI;
1953
 module.exports = UI;
1931
 
1954
 
1932
 
1955
 
1933
-},{"../../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){
1956
+},{"../../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){
1934
 var CanvasUtil = require("./CanvasUtils");
1957
 var CanvasUtil = require("./CanvasUtils");
1935
 
1958
 
1936
 var ASDrawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
1959
 var ASDrawContext = $('#activeSpeakerAudioLevel')[0].getContext('2d');
4008
     return my;
4031
     return my;
4009
 }(Chat || {}));
4032
 }(Chat || {}));
4010
 module.exports = Chat;
4033
 module.exports = Chat;
4011
-},{"../../../../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){
4034
+},{"../../../../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){
4012
 var UIUtil = require("../../util/UIUtil");
4035
 var UIUtil = require("../../util/UIUtil");
4013
 
4036
 
4014
 /**
4037
 /**
4542
 
4565
 
4543
 
4566
 
4544
 module.exports = SettingsMenu;
4567
 module.exports = SettingsMenu;
4545
-},{"../../../../service/translation/languages":85,"../../avatar/Avatar":12,"../../util/UIUtil":30,"./Settings":22}],24:[function(require,module,exports){
4568
+},{"../../../../service/translation/languages":86,"../../avatar/Avatar":12,"../../util/UIUtil":30,"./Settings":22}],24:[function(require,module,exports){
4546
 var PanelToggler = require("../side_pannels/SidePanelToggler");
4569
 var PanelToggler = require("../side_pannels/SidePanelToggler");
4547
 
4570
 
4548
 var buttonHandlers = {
4571
 var buttonHandlers = {
5545
 };
5568
 };
5546
 
5569
 
5547
 module.exports = NickanameHandler;
5570
 module.exports = NickanameHandler;
5548
-},{"../../../service/UI/UIEvents":82}],30:[function(require,module,exports){
5571
+},{"../../../service/UI/UIEvents":83}],30:[function(require,module,exports){
5549
 /**
5572
 /**
5550
  * Created by hristo on 12/22/14.
5573
  * Created by hristo on 12/22/14.
5551
  */
5574
  */
8262
 }(VideoLayout || {}));
8285
 }(VideoLayout || {}));
8263
 
8286
 
8264
 module.exports = VideoLayout;
8287
 module.exports = VideoLayout;
8265
-},{"../../../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){
8288
+},{"../../../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){
8266
 //var nouns = [
8289
 //var nouns = [
8267
 //];
8290
 //];
8268
 var pluralNouns = [
8291
 var pluralNouns = [
8680
 };
8703
 };
8681
 
8704
 
8682
 module.exports = ConnectionQuality;
8705
 module.exports = ConnectionQuality;
8683
-},{"../../service/connectionquality/CQEvents":83,"../../service/xmpp/XMPPEvents":86,"events":87}],36:[function(require,module,exports){
8706
+},{"../../service/connectionquality/CQEvents":84,"../../service/xmpp/XMPPEvents":87,"events":88}],36:[function(require,module,exports){
8684
 /* global $, alert, changeLocalVideo, chrome, config, getConferenceHandler, getUserMediaWithConstraints */
8707
 /* global $, alert, changeLocalVideo, chrome, config, getConferenceHandler, getUserMediaWithConstraints */
8685
 /**
8708
 /**
8686
  * Indicates that desktop stream is currently in use(for toggle purpose).
8709
  * Indicates that desktop stream is currently in use(for toggle purpose).
9005
 };
9028
 };
9006
 
9029
 
9007
 
9030
 
9008
-},{"../../service/desktopsharing/DesktopSharingEventTypes":84,"events":87}],37:[function(require,module,exports){
9031
+},{"../../service/desktopsharing/DesktopSharingEventTypes":85,"events":88}],37:[function(require,module,exports){
9009
 //maps keycode to character, id of popover for given function and function
9032
 //maps keycode to character, id of popover for given function and function
9010
 var shortcuts = {
9033
 var shortcuts = {
9011
     67: {
9034
     67: {
11335
 
11358
 
11336
 
11359
 
11337
 module.exports = statistics;
11360
 module.exports = statistics;
11338
-},{"../../service/RTC/StreamEventTypes.js":81,"../../service/xmpp/XMPPEvents":86,"./LocalStatsCollector.js":43,"./RTPStatsCollector.js":44,"events":87}],46:[function(require,module,exports){
11361
+},{"../../service/RTC/StreamEventTypes.js":82,"../../service/xmpp/XMPPEvents":87,"./LocalStatsCollector.js":43,"./RTPStatsCollector.js":44,"events":88}],46:[function(require,module,exports){
11339
 var i18n = require("i18next-client");
11362
 var i18n = require("i18next-client");
11340
 var languages = require("../../service/translation/languages");
11363
 var languages = require("../../service/translation/languages");
11341
 var DEFAULT_LANG = languages.EN;
11364
 var DEFAULT_LANG = languages.EN;
11447
     }
11470
     }
11448
 };
11471
 };
11449
 
11472
 
11450
-},{"../../service/translation/languages":85,"i18next-client":61}],47:[function(require,module,exports){
11473
+},{"../../service/translation/languages":86,"i18next-client":61}],47:[function(require,module,exports){
11451
 /* jshint -W117 */
11474
 /* jshint -W117 */
11452
 var TraceablePeerConnection = require("./TraceablePeerConnection");
11475
 var TraceablePeerConnection = require("./TraceablePeerConnection");
11453
 var SDPDiffer = require("./SDPDiffer");
11476
 var SDPDiffer = require("./SDPDiffer");
14528
 
14551
 
14529
 
14552
 
14530
 
14553
 
14531
-},{"../../service/xmpp/XMPPEvents":86}],53:[function(require,module,exports){
14554
+},{"../../service/xmpp/XMPPEvents":87}],53:[function(require,module,exports){
14532
 /* global $, $iq, config, connection, focusMucJid, messageHandler, Moderator,
14555
 /* global $, $iq, config, connection, focusMucJid, messageHandler, Moderator,
14533
    Toolbar, Util */
14556
    Toolbar, Util */
14534
 var Moderator = require("./moderator");
14557
 var Moderator = require("./moderator");
15300
 };
15323
 };
15301
 
15324
 
15302
 
15325
 
15303
-},{"../../service/xmpp/XMPPEvents":86,"./JingleSession":47,"./moderator":52}],55:[function(require,module,exports){
15326
+},{"../../service/xmpp/XMPPEvents":87,"./JingleSession":47,"./moderator":52}],55:[function(require,module,exports){
15304
 /* jshint -W117 */
15327
 /* jshint -W117 */
15305
 
15328
 
15306
 var JingleSession = require("./JingleSession");
15329
 var JingleSession = require("./JingleSession");
15639
 };
15662
 };
15640
 
15663
 
15641
 
15664
 
15642
-},{"../../service/xmpp/XMPPEvents":86,"./JingleSession":47}],56:[function(require,module,exports){
15665
+},{"../../service/xmpp/XMPPEvents":87,"./JingleSession":47}],56:[function(require,module,exports){
15643
 /* global Strophe */
15666
 /* global Strophe */
15644
 module.exports = function () {
15667
 module.exports = function () {
15645
 
15668
 
16306
 
16329
 
16307
 module.exports = XMPP;
16330
 module.exports = XMPP;
16308
 
16331
 
16309
-},{"../../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){
16332
+},{"../../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){
16310
 // i18next, v1.7.7
16333
 // i18next, v1.7.7
16311
 // Copyright (c)2014 Jan Mühlemann (jamuhl).
16334
 // Copyright (c)2014 Jan Mühlemann (jamuhl).
16312
 // Distributed under MIT license
16335
 // Distributed under MIT license
24822
 
24845
 
24823
 module.exports = RTCEvents;
24846
 module.exports = RTCEvents;
24824
 },{}],81:[function(require,module,exports){
24847
 },{}],81:[function(require,module,exports){
24848
+var Resolutions = {
24849
+    "1080": {
24850
+        width: 1920,
24851
+        height: 1080,
24852
+        order: 7
24853
+    },
24854
+    "fullhd": {
24855
+        width: 1920,
24856
+        height: 1080,
24857
+        order: 7
24858
+    },
24859
+    "720": {
24860
+        width: 1280,
24861
+        height: 720,
24862
+        order: 6
24863
+    },
24864
+    "hd": {
24865
+        width: 1280,
24866
+        height: 720,
24867
+        order: 6
24868
+    },
24869
+    "960": {
24870
+        width: 960,
24871
+        height: 720,
24872
+        order: 5
24873
+    },
24874
+    "640": {
24875
+        width: 640,
24876
+        height: 480,
24877
+        order: 4
24878
+    },
24879
+    "vga": {
24880
+        width: 640,
24881
+        height: 480,
24882
+        order: 4
24883
+    },
24884
+    "360": {
24885
+        width: 640,
24886
+        height: 360,
24887
+        order: 3
24888
+    },
24889
+    "320": {
24890
+        width: 320,
24891
+        height: 240,
24892
+        order: 2
24893
+    },
24894
+    "180": {
24895
+        width: 320,
24896
+        height: 180,
24897
+        order: 1
24898
+    }
24899
+};
24900
+module.exports = Resolutions;
24901
+},{}],82:[function(require,module,exports){
24825
 var StreamEventTypes = {
24902
 var StreamEventTypes = {
24826
     EVENT_TYPE_LOCAL_CREATED: "stream.local_created",
24903
     EVENT_TYPE_LOCAL_CREATED: "stream.local_created",
24827
 
24904
 
24835
 };
24912
 };
24836
 
24913
 
24837
 module.exports = StreamEventTypes;
24914
 module.exports = StreamEventTypes;
24838
-},{}],82:[function(require,module,exports){
24915
+},{}],83:[function(require,module,exports){
24839
 var UIEvents = {
24916
 var UIEvents = {
24840
     NICKNAME_CHANGED: "UI.nickname_changed",
24917
     NICKNAME_CHANGED: "UI.nickname_changed",
24841
     SELECTED_ENDPOINT: "UI.selected_endpoint",
24918
     SELECTED_ENDPOINT: "UI.selected_endpoint",
24842
     PINNED_ENDPOINT: "UI.pinned_endpoint"
24919
     PINNED_ENDPOINT: "UI.pinned_endpoint"
24843
 };
24920
 };
24844
 module.exports = UIEvents;
24921
 module.exports = UIEvents;
24845
-},{}],83:[function(require,module,exports){
24922
+},{}],84:[function(require,module,exports){
24846
 var CQEvents = {
24923
 var CQEvents = {
24847
     LOCALSTATS_UPDATED: "cq.localstats_updated",
24924
     LOCALSTATS_UPDATED: "cq.localstats_updated",
24848
     REMOTESTATS_UPDATED: "cq.remotestats_updated",
24925
     REMOTESTATS_UPDATED: "cq.remotestats_updated",
24850
 };
24927
 };
24851
 
24928
 
24852
 module.exports = CQEvents;
24929
 module.exports = CQEvents;
24853
-},{}],84:[function(require,module,exports){
24930
+},{}],85:[function(require,module,exports){
24854
 var DesktopSharingEventTypes = {
24931
 var DesktopSharingEventTypes = {
24855
     INIT: "ds.init",
24932
     INIT: "ds.init",
24856
 
24933
 
24860
 };
24937
 };
24861
 
24938
 
24862
 module.exports = DesktopSharingEventTypes;
24939
 module.exports = DesktopSharingEventTypes;
24863
-},{}],85:[function(require,module,exports){
24940
+},{}],86:[function(require,module,exports){
24864
 module.exports = {
24941
 module.exports = {
24865
     getLanguages : function () {
24942
     getLanguages : function () {
24866
         var languages = [];
24943
         var languages = [];
24873
     },
24950
     },
24874
     EN: "en"
24951
     EN: "en"
24875
 }
24952
 }
24876
-},{}],86:[function(require,module,exports){
24953
+},{}],87:[function(require,module,exports){
24877
 var XMPPEvents = {
24954
 var XMPPEvents = {
24878
     CONFERENCE_CERATED: "xmpp.conferenceCreated.jingle",
24955
     CONFERENCE_CERATED: "xmpp.conferenceCreated.jingle",
24879
     CALL_TERMINATED: "xmpp.callterminated.jingle",
24956
     CALL_TERMINATED: "xmpp.callterminated.jingle",
24900
     ETHERPAD: "xmpp.etherpad"
24977
     ETHERPAD: "xmpp.etherpad"
24901
 };
24978
 };
24902
 module.exports = XMPPEvents;
24979
 module.exports = XMPPEvents;
24903
-},{}],87:[function(require,module,exports){
24980
+},{}],88:[function(require,module,exports){
24904
 // Copyright Joyent, Inc. and other Node contributors.
24981
 // Copyright Joyent, Inc. and other Node contributors.
24905
 //
24982
 //
24906
 // Permission is hereby granted, free of charge, to any person obtaining a
24983
 // Permission is hereby granted, free of charge, to any person obtaining a

+ 82
- 59
modules/RTC/RTCUtils.js Datei anzeigen

1
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
1
 var RTCBrowserType = require("../../service/RTC/RTCBrowserType.js");
2
+var Resolutions = require("../../service/RTC/Resolutions");
3
+
4
+var currentResolution = null;
5
+
6
+function getPreviousResolution(resolution) {
7
+    if(!Resolutions[resolution])
8
+        return null;
9
+    var order = Resolutions[resolution].order;
10
+    var res = null;
11
+    var resName = null;
12
+    for(var i in Resolutions)
13
+    {
14
+        var tmp = Resolutions[i];
15
+        if(res == null || (res.order < tmp.order && tmp.order < order))
16
+        {
17
+            resName = i;
18
+            res = tmp;
19
+        }
20
+    }
21
+    return resName;
22
+}
2
 
23
 
3
 function setResolutionConstraints(constraints, resolution, isAndroid)
24
 function setResolutionConstraints(constraints, resolution, isAndroid)
4
 {
25
 {
5
     if (resolution && !constraints.video || isAndroid) {
26
     if (resolution && !constraints.video || isAndroid) {
6
         constraints.video = { mandatory: {}, optional: [] };// same behaviour as true
27
         constraints.video = { mandatory: {}, optional: [] };// same behaviour as true
7
     }
28
     }
8
-    // see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions
9
-    switch (resolution) {
10
-        // 16:9 first
11
-        case '1080':
12
-        case 'fullhd':
13
-            constraints.video.mandatory.minWidth = 1920;
14
-            constraints.video.mandatory.minHeight = 1080;
15
-            break;
16
-        case '720':
17
-        case 'hd':
18
-            constraints.video.mandatory.minWidth = 1280;
19
-            constraints.video.mandatory.minHeight = 720;
20
-            break;
21
-        case '360':
22
-            constraints.video.mandatory.minWidth = 640;
23
-            constraints.video.mandatory.minHeight = 360;
24
-            break;
25
-        case '180':
26
-            constraints.video.mandatory.minWidth = 320;
27
-            constraints.video.mandatory.minHeight = 180;
28
-            break;
29
-        // 4:3
30
-        case '960':
31
-            constraints.video.mandatory.minWidth = 960;
32
-            constraints.video.mandatory.minHeight = 720;
33
-            break;
34
-        case '640':
35
-        case 'vga':
36
-            constraints.video.mandatory.minWidth = 640;
37
-            constraints.video.mandatory.minHeight = 480;
38
-            break;
39
-        case '320':
29
+
30
+    if(Resolutions[resolution])
31
+    {
32
+        constraints.video.mandatory.minWidth = Resolutions[resolution].width;
33
+        constraints.video.mandatory.minHeight = Resolutions[resolution].height;
34
+    }
35
+    else
36
+    {
37
+        if (isAndroid) {
40
             constraints.video.mandatory.minWidth = 320;
38
             constraints.video.mandatory.minWidth = 320;
41
             constraints.video.mandatory.minHeight = 240;
39
             constraints.video.mandatory.minHeight = 240;
42
-            break;
43
-        default:
44
-            if (isAndroid) {
45
-                constraints.video.mandatory.minWidth = 320;
46
-                constraints.video.mandatory.minHeight = 240;
47
-                constraints.video.mandatory.maxFrameRate = 15;
48
-            }
49
-            break;
40
+            constraints.video.mandatory.maxFrameRate = 15;
41
+        }
50
     }
42
     }
43
+
51
     if (constraints.video.mandatory.minWidth)
44
     if (constraints.video.mandatory.minWidth)
52
         constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth;
45
         constraints.video.mandatory.maxWidth = constraints.video.mandatory.minWidth;
53
     if (constraints.video.mandatory.minHeight)
46
     if (constraints.video.mandatory.minHeight)
54
         constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight;
47
         constraints.video.mandatory.maxHeight = constraints.video.mandatory.minHeight;
55
 }
48
 }
56
 
49
 
57
-
58
 function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid)
50
 function getConstraints(um, resolution, bandwidth, fps, desktopStream, isAndroid)
59
 {
51
 {
60
     var constraints = {audio: false, video: false};
52
     var constraints = {audio: false, video: false};
220
     um, success_callback, failure_callback, resolution,bandwidth, fps,
212
     um, success_callback, failure_callback, resolution,bandwidth, fps,
221
     desktopStream)
213
     desktopStream)
222
 {
214
 {
215
+    currentResolution = resolution;
223
     // Check if we are running on Android device
216
     // Check if we are running on Android device
224
     var isAndroid = navigator.userAgent.indexOf('Android') != -1;
217
     var isAndroid = navigator.userAgent.indexOf('Android') != -1;
225
 
218
 
278
 RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
271
 RTCUtils.prototype.obtainAudioAndVideoPermissions = function() {
279
     var self = this;
272
     var self = this;
280
     // Get AV
273
     // Get AV
281
-    var cb = function (stream) {
282
-        console.log('got', stream, stream.getAudioTracks().length, stream.getVideoTracks().length);
283
-        self.handleLocalStream(stream);
284
-    };
285
-    var self = this;
274
+
286
     this.getUserMediaWithConstraints(
275
     this.getUserMediaWithConstraints(
287
         ['audio', 'video'],
276
         ['audio', 'video'],
288
-        cb,
277
+        function (stream) {
278
+            self.successCallback(stream);
279
+        },
289
         function (error) {
280
         function (error) {
290
-            console.error('failed to obtain audio/video stream - trying audio only', error);
291
-            self.getUserMediaWithConstraints(
292
-                ['audio'],
293
-                cb,
294
-                function (error) {
295
-                    console.error('failed to obtain audio/video stream - stop', error);
296
-                    APP.UI.messageHandler.showError("Error",
297
-                            "Failed to obtain permissions to use the local microphone" +
298
-                            "and/or camera.");
299
-                }
300
-            );
281
+            self.errorCallback(error);
301
         },
282
         },
302
-            config.resolution || '360');
283
+        config.resolution || '360');
284
+}
285
+
286
+RTCUtils.prototype.successCallback = function (stream) {
287
+    console.log('got', stream, stream.getAudioTracks().length,
288
+        stream.getVideoTracks().length);
289
+    this.handleLocalStream(stream);
290
+};
291
+
292
+RTCUtils.prototype.errorCallback = function (error) {
293
+    var self = this;
294
+    console.error('failed to obtain audio/video stream - trying audio only', error);
295
+    var resolution = getPreviousResolution(currentResolution);
296
+    if(typeof error == "object" && error.constraintName && error.name
297
+        && (error.name == "ConstraintNotSatisfiedError" ||
298
+            error.name == "OverconstrainedError") &&
299
+        (error.constraintName == "minWidth" || error.constraintName == "maxWidth" ||
300
+            error.constraintName == "minHeight" || error.constraintName == "maxHeight")
301
+        && resolution != null)
302
+    {
303
+        self.getUserMediaWithConstraints(['audio', 'video'],
304
+            function (stream) {
305
+                return self.successCallback(stream);
306
+            }, function (error) {
307
+                return self.errorCallback(error);
308
+            }, resolution);
309
+    }
310
+    else
311
+    {
312
+        self.getUserMediaWithConstraints(
313
+            ['audio'],
314
+            function (stream) {
315
+                return self.successCallback(stream);
316
+            },
317
+            function (error) {
318
+                console.error('failed to obtain audio/video stream - stop', error);
319
+                APP.UI.messageHandler.showError("Error",
320
+                        "Failed to obtain permissions to use the local microphone" +
321
+                        "and/or camera.");
322
+            }
323
+        );
324
+    }
325
+
303
 }
326
 }
304
 
327
 
305
 RTCUtils.prototype.handleLocalStream = function(stream)
328
 RTCUtils.prototype.handleLocalStream = function(stream)

+ 53
- 0
service/RTC/Resolutions.js Datei anzeigen

1
+var Resolutions = {
2
+    "1080": {
3
+        width: 1920,
4
+        height: 1080,
5
+        order: 7
6
+    },
7
+    "fullhd": {
8
+        width: 1920,
9
+        height: 1080,
10
+        order: 7
11
+    },
12
+    "720": {
13
+        width: 1280,
14
+        height: 720,
15
+        order: 6
16
+    },
17
+    "hd": {
18
+        width: 1280,
19
+        height: 720,
20
+        order: 6
21
+    },
22
+    "960": {
23
+        width: 960,
24
+        height: 720,
25
+        order: 5
26
+    },
27
+    "640": {
28
+        width: 640,
29
+        height: 480,
30
+        order: 4
31
+    },
32
+    "vga": {
33
+        width: 640,
34
+        height: 480,
35
+        order: 4
36
+    },
37
+    "360": {
38
+        width: 640,
39
+        height: 360,
40
+        order: 3
41
+    },
42
+    "320": {
43
+        width: 320,
44
+        height: 240,
45
+        order: 2
46
+    },
47
+    "180": {
48
+        width: 320,
49
+        height: 180,
50
+        order: 1
51
+    }
52
+};
53
+module.exports = Resolutions;

Laden…
Abbrechen
Speichern