浏览代码

fix(video):Always show avatar if video is inactive

master
Hristo Terezov 4 年前
父节点
当前提交
87b1155180

+ 2
- 12
modules/UI/videolayout/LargeVideoManager.js 查看文件

@@ -218,21 +218,11 @@ export default class LargeVideoManager {
218 218
             // change the avatar url on large
219 219
             this.updateAvatar();
220 220
 
221
-            // If the user's connection is disrupted then the avatar will be
222
-            // displayed in case we have no video image cached. That is if
223
-            // there was a user switch (image is lost on stream detach) or if
224
-            // the video was not rendered, before the connection has failed.
225
-            const wasUsersImageCached
226
-                = !isUserSwitch && container.wasVideoRendered;
227 221
             const isVideoMuted = !stream || stream.isMuted();
228 222
             const participant = getParticipantById(APP.store.getState(), id);
229 223
             const connectionStatus = participant?.connectionStatus;
230
-            const isVideoRenderable
231
-                = !isVideoMuted
232
-                    && (APP.conference.isLocalId(id)
233
-                        || connectionStatus
234
-                                === JitsiParticipantConnectionStatus.ACTIVE
235
-                        || wasUsersImageCached);
224
+            const isVideoRenderable = !isVideoMuted
225
+                && (APP.conference.isLocalId(id) || connectionStatus === JitsiParticipantConnectionStatus.ACTIVE);
236 226
 
237 227
             const showAvatar
238 228
                 = isVideoContainer

+ 15
- 13
modules/UI/videolayout/RemoteVideo.js 查看文件

@@ -331,23 +331,20 @@ export default class RemoteVideo extends SmallVideo {
331 331
     }
332 332
 
333 333
     /**
334
-     * The remote video is considered "playable" once the can play event has been received. It will be allowed to
335
-     * display video also in {@link JitsiParticipantConnectionStatus.INTERRUPTED} if the video has received the canplay
336
-     * event and was not muted while not in ACTIVE state. This basically means that there is stalled video image cached
337
-     * that could be displayed. It's used to show "grey video image" in user's thumbnail when there are connectivity
338
-     * issues.
334
+     * The remote video is considered "playable" once the can play event has been received.
339 335
      *
340 336
      * @inheritdoc
341 337
      * @override
342 338
      */
343 339
     isVideoPlayable() {
344 340
         const participant = getParticipantById(APP.store.getState(), this.id);
345
-        const { connectionStatus, mutedWhileDisconnected } = participant || {};
341
+        const { connectionStatus } = participant || {};
346 342
 
347
-        return super.isVideoPlayable()
348
-            && this._canPlayEventReceived
349
-            && (connectionStatus === JitsiParticipantConnectionStatus.ACTIVE
350
-                || (connectionStatus === JitsiParticipantConnectionStatus.INTERRUPTED && !mutedWhileDisconnected));
343
+        return (
344
+            super.isVideoPlayable()
345
+                && this._canPlayEventReceived
346
+                && connectionStatus === JitsiParticipantConnectionStatus.ACTIVE
347
+        );
351 348
     }
352 349
 
353 350
     /**
@@ -373,6 +370,8 @@ export default class RemoteVideo extends SmallVideo {
373 370
      * @param {*} stream
374 371
      */
375 372
     waitForPlayback(streamElement, stream) {
373
+        $(streamElement).hide();
374
+
376 375
         const webRtcStream = stream.getOriginalStream();
377 376
         const isVideo = stream.isVideoTrack();
378 377
 
@@ -382,7 +381,12 @@ export default class RemoteVideo extends SmallVideo {
382 381
 
383 382
         const listener = () => {
384 383
             this._canPlayEventReceived = true;
385
-            this.VideoLayout.remoteVideoActive(streamElement, this.id);
384
+
385
+            logger.info(`${this.id} video is now active`, streamElement);
386
+            if (streamElement) {
387
+                $(streamElement).show();
388
+            }
389
+
386 390
             streamElement.removeEventListener('canplay', listener);
387 391
 
388 392
             // Refresh to show the video
@@ -422,8 +426,6 @@ export default class RemoteVideo extends SmallVideo {
422 426
         // Put new stream element always in front
423 427
         streamElement = UIUtils.prependChild(this.container, streamElement);
424 428
 
425
-        $(streamElement).hide();
426
-
427 429
         this.waitForPlayback(streamElement, stream);
428 430
         stream.attach(streamElement);
429 431
 

+ 1
- 3
modules/UI/videolayout/SmallVideo.js 查看文件

@@ -433,7 +433,7 @@ export default class SmallVideo {
433 433
      */
434 434
     computeDisplayModeInput() {
435 435
         let isScreenSharing = false;
436
-        let connectionStatus, mutedWhileDisconnected;
436
+        let connectionStatus;
437 437
         const state = APP.store.getState();
438 438
         const participant = getParticipantById(state, this.id);
439 439
 
@@ -443,7 +443,6 @@ export default class SmallVideo {
443 443
 
444 444
             isScreenSharing = typeof track !== 'undefined' && track.videoType === 'desktop';
445 445
             connectionStatus = participant.connectionStatus;
446
-            mutedWhileDisconnected = participant.mutedWhileDisconnected;
447 446
         }
448 447
 
449 448
         return {
@@ -454,7 +453,6 @@ export default class SmallVideo {
454 453
             isVideoPlayable: this.isVideoPlayable(),
455 454
             hasVideo: Boolean(this.selectVideoElement().length),
456 455
             connectionStatus,
457
-            mutedWhileDisconnected,
458 456
             canPlayEventReceived: this._canPlayEventReceived,
459 457
             videoStream: Boolean(this.videoStream),
460 458
             isScreenSharing,

+ 2
- 19
modules/UI/videolayout/VideoContainer.js 查看文件

@@ -233,14 +233,6 @@ export class VideoContainer extends LargeContainer {
233 233
 
234 234
         this.$remotePresenceMessage = $('#remotePresenceMessage');
235 235
 
236
-        /**
237
-         * Indicates whether or not the video stream attached to the video
238
-         * element has started(which means that there is any image rendered
239
-         * even if the video is stalled).
240
-         * @type {boolean}
241
-         */
242
-        this.wasVideoRendered = false;
243
-
244 236
         this.$wrapper = $('#largeVideoWrapper');
245 237
 
246 238
         /**
@@ -249,17 +241,12 @@ export class VideoContainer extends LargeContainer {
249 241
          * video anyway.
250 242
          */
251 243
         this.$wrapperParent = this.$wrapper.parent();
252
-
253 244
         this.avatarHeight = $('#dominantSpeakerAvatarContainer').height();
254
-
255
-        const onPlayingCallback = function(event) {
245
+        this.$video[0].onplaying = function(event) {
256 246
             if (typeof resizeContainer === 'function') {
257 247
                 resizeContainer(event);
258 248
             }
259
-            this.wasVideoRendered = true;
260
-        }.bind(this);
261
-
262
-        this.$video[0].onplaying = onPlayingCallback;
249
+        };
263 250
 
264 251
         /**
265 252
          * A Set of functions to invoke when the video element resizes.
@@ -491,10 +478,6 @@ export class VideoContainer extends LargeContainer {
491 478
             return;
492 479
         }
493 480
 
494
-        // The stream has changed, so the image will be lost on detach
495
-        this.wasVideoRendered = false;
496
-
497
-
498 481
         // detach old stream
499 482
         if (this.stream) {
500 483
             this.stream.detach(this.$video[0]);

+ 1
- 10
modules/UI/videolayout/VideoLayout.js 查看文件

@@ -1,4 +1,4 @@
1
-/* global APP, $  */
1
+/* global APP  */
2 2
 
3 3
 import Logger from 'jitsi-meet-logger';
4 4
 
@@ -314,15 +314,6 @@ const VideoLayout = {
314 314
         remoteVideo.updateView();
315 315
     },
316 316
 
317
-    // FIXME: what does this do???
318
-    remoteVideoActive(videoElement, resourceJid) {
319
-        logger.info(`${resourceJid} video is now active`, videoElement);
320
-        if (videoElement) {
321
-            $(videoElement).show();
322
-        }
323
-        this._updateLargeVideoIfDisplayed(resourceJid, true);
324
-    },
325
-
326 317
     /**
327 318
      * On video muted event.
328 319
      */

+ 7
- 11
react/features/base/participants/actions.js 查看文件

@@ -19,8 +19,7 @@ import {
19 19
 import {
20 20
     getLocalParticipant,
21 21
     getNormalizedDisplayName,
22
-    getParticipantDisplayName,
23
-    figureOutMutedWhileDisconnectedStatus
22
+    getParticipantDisplayName
24 23
 } from './functions';
25 24
 
26 25
 /**
@@ -217,15 +216,12 @@ export function muteRemoteParticipant(id) {
217 216
  * }}
218 217
  */
219 218
 export function participantConnectionStatusChanged(id, connectionStatus) {
220
-    return (dispatch, getState) => {
221
-        dispatch({
222
-            type: PARTICIPANT_UPDATED,
223
-            participant: {
224
-                connectionStatus,
225
-                id,
226
-                mutedWhileDisconnected: figureOutMutedWhileDisconnectedStatus(getState(), id, connectionStatus)
227
-            }
228
-        });
219
+    return {
220
+        type: PARTICIPANT_UPDATED,
221
+        participant: {
222
+            connectionStatus,
223
+            id
224
+        }
229 225
     };
230 226
 }
231 227
 

+ 1
- 40
react/features/base/participants/functions.js 查看文件

@@ -6,7 +6,7 @@ import type { Store } from 'redux';
6 6
 import { JitsiParticipantConnectionStatus } from '../lib-jitsi-meet';
7 7
 import { MEDIA_TYPE, shouldRenderVideoTrack } from '../media';
8 8
 import { toState } from '../redux';
9
-import { getTrackByMediaTypeAndParticipant, isRemoteTrackMuted } from '../tracks';
9
+import { getTrackByMediaTypeAndParticipant } from '../tracks';
10 10
 import { createDeferred } from '../util';
11 11
 
12 12
 import {
@@ -369,45 +369,6 @@ export function shouldRenderParticipantVideo(stateful: Object | Function, id: st
369 369
     return participantIsInLargeVideoWithScreen;
370 370
 }
371 371
 
372
-/**
373
- * Figures out the value of mutedWhileDisconnected status by taking into
374
- * account remote participant's network connectivity and video muted status.
375
- * The flag is set to <tt>true</tt> if remote participant's video gets muted
376
- * during his media connection disruption. This is to prevent black video
377
- * being render on the thumbnail, because even though once the video has
378
- * been played the image usually remains on the video element it seems that
379
- * after longer period of the video element being hidden this image can be
380
- * lost.
381
- *
382
- * @param {Object|Function} stateful - Object or function that can be resolved
383
- * to the Redux state.
384
- * @param {string} participantID - The ID of the participant.
385
- * @param {string} [connectionStatus] - A connection status to be used.
386
- * @returns {boolean} - The mutedWhileDisconnected value.
387
- */
388
-export function figureOutMutedWhileDisconnectedStatus(
389
-        stateful: Function | Object, participantID: string, connectionStatus: ?string) {
390
-    const state = toState(stateful);
391
-    const participant = getParticipantById(state, participantID);
392
-
393
-    if (!participant || participant.local) {
394
-        return undefined;
395
-    }
396
-
397
-    const isActive = (connectionStatus || participant.connectionStatus) === JitsiParticipantConnectionStatus.ACTIVE;
398
-    const isVideoMuted = isRemoteTrackMuted(state['features/base/tracks'], MEDIA_TYPE.VIDEO, participantID);
399
-    let mutedWhileDisconnected = participant.mutedWhileDisconnected || false;
400
-
401
-    if (!isActive && isVideoMuted) {
402
-        mutedWhileDisconnected = true;
403
-    } else if (isActive && !isVideoMuted) {
404
-        mutedWhileDisconnected = false;
405
-    }
406
-
407
-    return mutedWhileDisconnected;
408
-}
409
-
410
-
411 372
 /**
412 373
  * Resolves the first loadable avatar URL for a participant.
413 374
  *

+ 1
- 56
react/features/base/participants/middleware.js 查看文件

@@ -12,7 +12,6 @@ import {
12 12
 import { JitsiConferenceEvents } from '../lib-jitsi-meet';
13 13
 import { MiddlewareRegistry, StateListenerRegistry } from '../redux';
14 14
 import { playSound, registerSound, unregisterSound } from '../sounds';
15
-import { getTrackByJitsiTrack, TRACK_ADDED, TRACK_REMOVED, TRACK_UPDATED } from '../tracks';
16 15
 
17 16
 import {
18 17
     DOMINANT_SPEAKER_CHANGED,
@@ -42,8 +41,7 @@ import {
42 41
     getLocalParticipant,
43 42
     getParticipantById,
44 43
     getParticipantCount,
45
-    getParticipantDisplayName,
46
-    figureOutMutedWhileDisconnectedStatus
44
+    getParticipantDisplayName
47 45
 } from './functions';
48 46
 import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
49 47
 
@@ -137,10 +135,6 @@ MiddlewareRegistry.register(store => next => action => {
137 135
     case PARTICIPANT_UPDATED:
138 136
         return _participantJoinedOrUpdated(store, next, action);
139 137
 
140
-    case TRACK_ADDED:
141
-    case TRACK_REMOVED:
142
-    case TRACK_UPDATED:
143
-        return _trackChanged(store, next, action);
144 138
     }
145 139
 
146 140
     return next(action);
@@ -460,55 +454,6 @@ function _registerSounds({ dispatch }) {
460 454
     dispatch(registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE));
461 455
 }
462 456
 
463
-/**
464
- * Notifies the feature base/participants that the action there has been a change in the tracks of the participants.
465
- *
466
- * @param {Store} store - The redux store in which the specified {@code action} is being dispatched.
467
- * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the specified {@code action} in the
468
- * specified {@code store}.
469
- * @param {Action} action - The redux action {@code PARTICIPANT_JOINED} or {@code PARTICIPANT_UPDATED} which is being
470
- * dispatched in the specified {@code store}.
471
- * @private
472
- * @returns {Object} The value returned by {@code next(action)}.
473
- */
474
-function _trackChanged({ dispatch, getState }, next, action) {
475
-    const { jitsiTrack } = action.track;
476
-    let track;
477
-
478
-    if (action.type === TRACK_REMOVED) {
479
-        track = getTrackByJitsiTrack(getState()['features/base/tracks'], jitsiTrack);
480
-    }
481
-
482
-    const result = next(action);
483
-
484
-    if (action.type !== TRACK_REMOVED) {
485
-        track = getTrackByJitsiTrack(getState()['features/base/tracks'], jitsiTrack);
486
-    }
487
-
488
-    if (typeof track === 'undefined' || track.local) {
489
-        return result;
490
-    }
491
-
492
-    const { participantId } = track;
493
-    const state = getState();
494
-    const participant = getParticipantById(state, participantId);
495
-
496
-    if (!participant) {
497
-        return result;
498
-    }
499
-
500
-    const mutedWhileDisconnected = figureOutMutedWhileDisconnectedStatus(state, participantId);
501
-
502
-    if (participant.mutedWhileDisconnected !== mutedWhileDisconnected) {
503
-        dispatch(participantUpdated({
504
-            id: participantId,
505
-            mutedWhileDisconnected
506
-        }));
507
-    }
508
-
509
-    return result;
510
-}
511
-
512 457
 /**
513 458
  * Unregisters sounds related with the participants feature.
514 459
  *

+ 0
- 1
react/features/base/participants/reducer.js 查看文件

@@ -221,7 +221,6 @@ function _participantJoined({ participant }) {
221 221
         isJigasi,
222 222
         loadableAvatarUrl,
223 223
         local: local || false,
224
-        mutedWhileDisconnected: local ? undefined : false,
225 224
         name,
226 225
         pinned: pinned || false,
227 226
         presence,

正在加载...
取消
保存