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,27 +175,40 @@ function getDisplayName(id) {
175 175
  * result of user interaction
176 176
  */
177 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 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 202
  * Mute or unmute local video stream if it exists.
195 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 210
 function muteLocalVideo(muted) {
198
-    muteLocalMedia(localVideo, muted, 'Video');
211
+    return muteLocalMedia(localVideo, muted);
199 212
 }
200 213
 
201 214
 /**
@@ -739,6 +752,12 @@ export default {
739 752
             return;
740 753
         }
741 754
 
755
+        const maybeShowErrorDialog = (error) => {
756
+            if (showUI) {
757
+                APP.UI.showDeviceErrorDialog(null, error);
758
+            }
759
+        };
760
+
742 761
         if (!localVideo && this.videoMuted && !mute) {
743 762
             // Try to create local video if there wasn't any.
744 763
             // This handles the case when user joined with no video
@@ -752,22 +771,21 @@ export default {
752 771
                 .then(([videoTrack]) => videoTrack)
753 772
                 .catch(error => {
754 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 776
                     // Rollback the video muted status by using null track
759 777
                     return null;
760 778
                 })
761 779
                 .then(videoTrack => this.useVideoStream(videoTrack));
762 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