Browse Source

fix: video muted out of sync

When video is unmuted when toggling off the audio only mode it
dispatches video muted status, but does not roll it back in case it
fails. That was causing toolbar button on Web to display incorrect
video muted status.
j8
paweldomas 8 years ago
parent
commit
e08171f602
1 changed files with 37 additions and 19 deletions
  1. 37
    19
      conference.js

+ 37
- 19
conference.js View File

175
  * result of user interaction
175
  * result of user interaction
176
  */
176
  */
177
 function muteLocalAudio(muted) {
177
 function muteLocalAudio(muted) {
178
-    muteLocalMedia(localAudio, muted, 'Audio');
178
+    muteLocalMedia(localAudio, muted);
179
 }
179
 }
180
 
180
 
181
-function muteLocalMedia(localMedia, muted, localMediaTypeString) {
182
-    if (!localMedia) {
183
-        return;
181
+/**
182
+ * Mute or unmute local media stream if it exists.
183
+ * @param {JitsiLocalTrack} localTrack
184
+ * @param {boolean} muted
185
+ *
186
+ * @returns {Promise} resolved in case mute/unmute operations succeeds or
187
+ * rejected with an error if something goes wrong. It is expected that often
188
+ * the error will be of the {@link JitsiTrackError} type, but it's not
189
+ * guaranteed.
190
+ */
191
+function muteLocalMedia(localTrack, muted) {
192
+    if (!localTrack) {
193
+        return Promise.resolve();
184
     }
194
     }
185
 
195
 
186
     const method = muted ? 'mute' : 'unmute';
196
     const method = muted ? 'mute' : 'unmute';
187
 
197
 
188
-    localMedia[method]().catch(reason => {
189
-        logger.warn(`${localMediaTypeString} ${method} was rejected:`, reason);
190
-    });
198
+    return localTrack[method]();
191
 }
199
 }
192
 
200
 
193
 /**
201
 /**
194
  * Mute or unmute local video stream if it exists.
202
  * Mute or unmute local video stream if it exists.
195
  * @param {boolean} muted if video stream should be muted or unmuted.
203
  * @param {boolean} muted if video stream should be muted or unmuted.
204
+ *
205
+ * @returns {Promise} resolved in case mute/unmute operations succeeds or
206
+ * rejected with an error if something goes wrong. It is expected that often
207
+ * the error will be of the {@link JitsiTrackError} type, but it's not
208
+ * guaranteed.
196
  */
209
  */
197
 function muteLocalVideo(muted) {
210
 function muteLocalVideo(muted) {
198
-    muteLocalMedia(localVideo, muted, 'Video');
211
+    return muteLocalMedia(localVideo, muted);
199
 }
212
 }
200
 
213
 
201
 /**
214
 /**
739
             return;
752
             return;
740
         }
753
         }
741
 
754
 
755
+        const maybeShowErrorDialog = (error) => {
756
+            if (showUI) {
757
+                APP.UI.showDeviceErrorDialog(null, error);
758
+            }
759
+        };
760
+
742
         if (!localVideo && this.videoMuted && !mute) {
761
         if (!localVideo && this.videoMuted && !mute) {
743
             // Try to create local video if there wasn't any.
762
             // Try to create local video if there wasn't any.
744
             // This handles the case when user joined with no video
763
             // This handles the case when user joined with no video
752
                 .then(([videoTrack]) => videoTrack)
771
                 .then(([videoTrack]) => videoTrack)
753
                 .catch(error => {
772
                 .catch(error => {
754
                     // FIXME should send some feedback to the API on error ?
773
                     // FIXME should send some feedback to the API on error ?
755
-                    if (showUI) {
756
-                        APP.UI.showDeviceErrorDialog(null, error);
757
-                    }
774
+                    maybeShowErrorDialog(error);
775
+
758
                     // Rollback the video muted status by using null track
776
                     // Rollback the video muted status by using null track
759
                     return null;
777
                     return null;
760
                 })
778
                 })
761
                 .then(videoTrack => this.useVideoStream(videoTrack));
779
                 .then(videoTrack => this.useVideoStream(videoTrack));
762
         } else {
780
         } else {
763
-            // FIXME if localVideo exists and the permissions are blocked
764
-            // while video muted it will fail to unmute and UI will get out of
765
-            // sync (the toolbar will show unmuted even though unmute failed).
766
-            // But for some reason that only happens when toggling off from
767
-            // the audio only mode - the same scenario works fine from toolbar.
768
-            // This is very rare corner case and supposedly this will get fixed
769
-            // once everything goes to react/redux.
770
-            muteLocalVideo(mute);
781
+            const oldMutedStatus = this.videoMuted;
782
+
783
+            muteLocalVideo(mute)
784
+                .catch(error => {
785
+                    maybeShowErrorDialog(error);
786
+                    this.videoMuted = oldMutedStatus;
787
+                    APP.UI.setVideoMuted(this.getMyUserId(), this.videoMuted);
788
+                });
771
         }
789
         }
772
     },
790
     },
773
     /**
791
     /**

Loading…
Cancel
Save