ソースを参照

Changes the implementation to show availability of video and sound devices.

j8
hristoterezov 10年前
コミット
58cc21d417

+ 25
- 0
css/videolayout_default.css ファイルの表示

@@ -415,3 +415,28 @@
415 415
     left: 35px;
416 416
     border-radius: 200px;
417 417
 }
418
+
419
+.noMic {
420
+    position: absolute;
421
+    border-radius: 8px;
422
+    z-index: 1;
423
+    width: 100%;
424
+    height: 100%;
425
+    background-image: url("../images/noMic.png");
426
+    background-color: #000;
427
+    background-repeat: no-repeat;
428
+    background-position: center;
429
+}
430
+
431
+.noVideo {
432
+    position: absolute;
433
+    border-radius: 8px;
434
+    z-index: 1;
435
+    width: 100%;
436
+    height: 100%;
437
+    background-image: url("../images/noVideo.png");
438
+    background-color: #000;
439
+    background-repeat: no-repeat;
440
+    background-position: center;
441
+}
442
+

バイナリ
images/noMic.png ファイルの表示


バイナリ
images/noVideo.png ファイルの表示


+ 2
- 2
index.html ファイルの表示

@@ -19,12 +19,12 @@
19 19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20 20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21 21
     <script src="interface_config.js?v=5"></script>
22
-    <script src="libs/app.bundle.js?v=47"></script>
22
+    <script src="libs/app.bundle.js?v=48"></script>
23 23
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24 24
     <link rel="stylesheet" href="css/font.css?v=6"/>
25 25
     <link rel="stylesheet" href="css/toastr.css?v=1">
26 26
     <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
27
-    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=16" id="videolayout_default"/>
27
+    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=17" id="videolayout_default"/>
28 28
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
29 29
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
30 30
     <link rel="stylesheet" href="css/modaldialog.css?v=3">

+ 26233
- 26120
libs/app.bundle.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 11
- 0
modules/RTC/RTC.js ファイルの表示

@@ -7,6 +7,7 @@ var DesktopSharingEventTypes
7 7
     = require("../../service/desktopsharing/DesktopSharingEventTypes");
8 8
 var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
9 9
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
10
+var RTCEvents = require("../../service/RTC/RTCEvents.js");
10 11
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
11 12
 var UIEvents = require("../../service/UI/UIEvents");
12 13
 
@@ -14,6 +15,10 @@ var eventEmitter = new EventEmitter();
14 15
 
15 16
 var RTC = {
16 17
     rtcUtils: null,
18
+    devices: {
19
+        audio: false,
20
+        video: false
21
+    },
17 22
     localStreams: [],
18 23
     remoteStreams: {},
19 24
     localAudio: null,
@@ -37,6 +42,7 @@ var RTC = {
37 42
         if(this.localStreams.length == 0 ||
38 43
             this.localStreams[0].getOriginalStream() != stream)
39 44
             this.localStreams.push(localStream);
45
+
40 46
         if(type == "audio")
41 47
         {
42 48
             this.localAudio = localStream;
@@ -224,6 +230,11 @@ var RTC = {
224 230
                 callback,
225 231
                 options);
226 232
         }
233
+    },
234
+    setDeviceAvailability: function (devices) {
235
+        this.devices.audio = (devices && devices.audio === true);
236
+        this.devices.video = (devices && devices.video === true);
237
+        eventEmitter.emit(RTCEvents.AVAILABLE_DEVICES_CHANGED, this.devices);
227 238
     }
228 239
 };
229 240
 

+ 19
- 2
modules/RTC/RTCUtils.js ファイルの表示

@@ -225,6 +225,8 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
225 225
 
226 226
     var isFF = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
227 227
 
228
+    var self = this;
229
+
228 230
     try {
229 231
         if (config.enableSimulcast
230 232
             && constraints.video
@@ -236,10 +238,12 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
236 238
             && !isFF) {
237 239
             APP.simulcast.getUserMedia(constraints, function (stream) {
238 240
                     console.log('onUserMediaSuccess');
241
+                    self.setAvailableDevices(um, true);
239 242
                     success_callback(stream);
240 243
                 },
241 244
                 function (error) {
242 245
                     console.warn('Failed to get access to local media. Error ', error);
246
+                    self.setAvailableDevices(um, false);
243 247
                     if (failure_callback) {
244 248
                         failure_callback(error);
245 249
                     }
@@ -249,9 +253,11 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
249 253
             this.getUserMedia(constraints,
250 254
                 function (stream) {
251 255
                     console.log('onUserMediaSuccess');
256
+                    self.setAvailableDevices(um, true);
252 257
                     success_callback(stream);
253 258
                 },
254 259
                 function (error) {
260
+                    self.setAvailableDevices(um, false);
255 261
                     console.warn('Failed to get access to local media. Error ',
256 262
                         error, constraints);
257 263
                     if (failure_callback) {
@@ -268,6 +274,19 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
268 274
     }
269 275
 };
270 276
 
277
+RTCUtils.prototype.setAvailableDevices = function (um, available) {
278
+    var devices = {};
279
+    if(um.indexOf("video") != -1)
280
+    {
281
+        devices.video = available;
282
+    }
283
+    if(um.indexOf("audio") != -1)
284
+    {
285
+        devices.audio = available;
286
+    }
287
+    this.service.setDeviceAvailability(devices);
288
+}
289
+
271 290
 /**
272 291
  * We ask for audio and video combined stream in order to get permissions and
273 292
  * not to ask twice.
@@ -328,8 +347,6 @@ RTCUtils.prototype.errorCallback = function (error) {
328 347
             function (error) {
329 348
                 console.error('failed to obtain audio/video stream - stop',
330 349
                     error);
331
-//                APP.UI.messageHandler.showError("dialog.error",
332
-//                    "dialog.failedpermissions");
333 350
                 return self.successCallback(null);
334 351
             }
335 352
         );

+ 10
- 3
modules/UI/UI.js ファイルの表示

@@ -105,7 +105,10 @@ function registerListeners() {
105 105
         function (endpointSimulcastLayers) {
106 106
             VideoLayout.onSimulcastLayersChanging(endpointSimulcastLayers);
107 107
         });
108
-
108
+    APP.RTC.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED,
109
+        function (devices) {
110
+            VideoLayout.setDeviceAvailabilityIcons(null, devices);
111
+        })
109 112
     APP.statistics.addAudioLevelListener(function(jid, audioLevel)
110 113
     {
111 114
         var resourceJid;
@@ -214,8 +217,12 @@ function registerListeners() {
214 217
     APP.xmpp.addListener(XMPPEvents.PASSWORD_REQUIRED, onPasswordReqiured);
215 218
     APP.xmpp.addListener(XMPPEvents.CHAT_ERROR_RECEIVED, chatAddError);
216 219
     APP.xmpp.addListener(XMPPEvents.ETHERPAD, initEtherpad);
217
-    APP.xmpp.addListener(XMPPEvents.AUTHENTICATION_REQUIRED, onAuthenticationRequired);
218
-
220
+    APP.xmpp.addListener(XMPPEvents.AUTHENTICATION_REQUIRED,
221
+        onAuthenticationRequired);
222
+    APP.xmpp.addListener(XMPPEvents.DEVICE_AVAILABLE,
223
+        function (resource, devices) {
224
+            VideoLayout.setDeviceAvailabilityIcons(resource, devices);
225
+        });
219 226
 
220 227
 }
221 228
 

+ 42
- 0
modules/UI/videolayout/VideoLayout.js ファイルの表示

@@ -639,6 +639,48 @@ var VideoLayout = (function (my) {
639 639
 
640 640
     };
641 641
 
642
+    /**
643
+     * Adds or removes icons for not available camera and microphone.
644
+     * @param resourceJid the jid of user
645
+     * @param devices available devices
646
+     */
647
+    my.setDeviceAvailabilityIcons = function (resourceJid, devices) {
648
+        if(!devices)
649
+            return;
650
+
651
+        var container = null
652
+        if(!resourceJid)
653
+        {
654
+            container = $("#localVideoContainer")[0];
655
+        }
656
+        else
657
+        {
658
+            container = $("#participant_" + resourceJid)[0];
659
+        }
660
+
661
+        if(!container)
662
+            return;
663
+
664
+        $("#" + container.id + " > .noMic").remove();
665
+        $("#" + container.id + " > .noVideo").remove();
666
+        if(!devices.audio)
667
+        {
668
+            container.appendChild(document.createElement("div")).setAttribute("class","noMic");
669
+        }
670
+
671
+        if(!devices.video)
672
+        {
673
+            container.appendChild(document.createElement("div")).setAttribute("class","noVideo");
674
+        }
675
+
676
+        if(!devices.audio && !devices.video)
677
+        {
678
+            $("#" + container.id + " > .noMic").css("background-position", "75%");
679
+            $("#" + container.id + " > .noVideo").css("background-position", "25%");
680
+            $("#" + container.id + " > .noVideo").css("background-color", "transparent");
681
+        }
682
+    }
683
+
642 684
     /**
643 685
      * Checks if removed video is currently displayed and tries to display
644 686
      * another one instead.

+ 27
- 0
modules/xmpp/strophe.emuc.js ファイルの表示

@@ -143,6 +143,25 @@ module.exports = function(XMPP, eventEmitter) {
143 143
                 $(document).trigger('videomuted.muc', [from, videoMuted.text()]);
144 144
             }
145 145
 
146
+            var devices = $(pres).find('>devices');
147
+            if(devices.length)
148
+            {
149
+                var audio = devices.find('>audio');
150
+                var video = devices.find('>video');
151
+                var devicesValues = {audio: false, video: false};
152
+                if(audio.length && audio.text() === "true")
153
+                {
154
+                    devicesValues.audio = true;
155
+                }
156
+
157
+                if(video.length && video.text() === "true")
158
+                {
159
+                    devicesValues.video = true;
160
+                }
161
+                eventEmitter.emit(XMPPEvents.DEVICE_AVAILABLE,
162
+                    Strophe.getResourceFromJid(from), devicesValues);
163
+            }
164
+
146 165
             var stats = $(pres).find('>stats');
147 166
             if (stats.length) {
148 167
                 var statsObj = {};
@@ -422,6 +441,11 @@ module.exports = function(XMPP, eventEmitter) {
422 441
                     .t(this.presMap['displayName']).up();
423 442
             }
424 443
 
444
+            if(this.presMap["devices"])
445
+            {
446
+                pres.c('devices').c('audio').t(this.presMap['devices'].audio).up()
447
+                    .c('video').t(this.presMap['devices'].video).up().up();
448
+            }
425 449
             if (this.presMap['audions']) {
426 450
                 pres.c('audiomuted', {xmlns: this.presMap['audions']})
427 451
                     .t(this.presMap['audiomuted']).up();
@@ -485,6 +509,9 @@ module.exports = function(XMPP, eventEmitter) {
485 509
             this.presMap['source' + sourceNumber + '_ssrc'] = ssrcs;
486 510
             this.presMap['source' + sourceNumber + '_direction'] = direction;
487 511
         },
512
+        addDevicesToPresence: function (devices) {
513
+            this.presMap['devices'] = devices;
514
+        },
488 515
         clearPresenceMedia: function () {
489 516
             var self = this;
490 517
             Object.keys(this.presMap).forEach(function (key) {

+ 7
- 0
modules/xmpp/xmpp.js ファイルの表示

@@ -6,6 +6,7 @@ var SDP = require("./SDP");
6 6
 var Settings = require("../settings/Settings");
7 7
 var Pako = require("pako");
8 8
 var StreamEventTypes = require("../../service/RTC/StreamEventTypes");
9
+var RTCEvents = require("../../service/RTC/RTCEvents");
9 10
 var UIEvents = require("../../service/UI/UIEvents");
10 11
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
11 12
 
@@ -102,6 +103,9 @@ function initStrophePlugins()
102 103
 function registerListeners() {
103 104
     APP.RTC.addStreamListener(maybeDoJoin,
104 105
         StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
106
+    APP.RTC.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
107
+        XMPP.addToPresence("devices", devices);
108
+    })
105 109
     APP.UI.addListener(UIEvents.NICKNAME_CHANGED, function (nickname) {
106 110
         XMPP.addToPresence("displayName", nickname);
107 111
     });
@@ -385,6 +389,9 @@ var XMPP = {
385 389
             case "email":
386 390
                 connection.emuc.addEmailToPresence(value);
387 391
                 break;
392
+            case "devices":
393
+                connection.emuc.addDevicesToPresence(value);
394
+                break;
388 395
             default :
389 396
                 console.log("Unknown tag for presence: " + name);
390 397
                 return;

+ 2
- 1
service/RTC/RTCEvents.js ファイルの表示

@@ -5,7 +5,8 @@ var RTCEvents = {
5 5
     SIMULCAST_LAYER_CHANGED: "rtc.simulcast_layer_changed",
6 6
     SIMULCAST_LAYER_CHANGING: "rtc.simulcast_layer_changing",
7 7
     SIMULCAST_START: "rtc.simlcast_start",
8
-    SIMULCAST_STOP: "rtc.simlcast_stop"
8
+    SIMULCAST_STOP: "rtc.simlcast_stop",
9
+    AVAILABLE_DEVICES_CHANGED: "rtc.available_devices_changed"
9 10
 };
10 11
 
11 12
 module.exports = RTCEvents;

+ 2
- 1
service/xmpp/XMPPEvents.js ファイルの表示

@@ -24,6 +24,7 @@ var XMPPEvents = {
24 24
     PASSWORD_REQUIRED: "xmpp.password_required",
25 25
     AUTHENTICATION_REQUIRED: "xmpp.authentication_required",
26 26
     CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
27
-    ETHERPAD: "xmpp.etherpad"
27
+    ETHERPAD: "xmpp.etherpad",
28
+    DEVICE_AVAILABLE: "xmpp.device_available"
28 29
 };
29 30
 module.exports = XMPPEvents;

読み込み中…
キャンセル
保存