You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

subscriber.ts 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import _ from 'lodash';
  2. import { IStore } from '../../app/types';
  3. import { getCurrentConference } from '../conference/functions';
  4. import {
  5. getMultipleVideoSendingSupportFeatureFlag,
  6. getSsrcRewritingFeatureFlag
  7. } from '../config/functions.any';
  8. import { VIDEO_TYPE } from '../media/constants';
  9. import StateListenerRegistry from '../redux/StateListenerRegistry';
  10. import { createVirtualScreenshareParticipant, participantLeft } from './actions';
  11. import { getRemoteScreensharesBasedOnPresence } from './functions';
  12. import { FakeParticipant } from './types';
  13. StateListenerRegistry.register(
  14. /* selector */ state => state['features/base/tracks'],
  15. /* listener */(tracks, store) => _updateScreenshareParticipants(store)
  16. );
  17. StateListenerRegistry.register(
  18. /* selector */ state => state['features/base/participants'].remoteVideoSources,
  19. /* listener */(remoteVideoSources, store) => getSsrcRewritingFeatureFlag(store.getState())
  20. && _updateScreenshareParticipantsBasedOnPresence(store)
  21. );
  22. /**
  23. * Compares the old and new screenshare lists provided and creates/removes the virtual screenshare participant
  24. * tiles accodingly.
  25. *
  26. * @param {Array<string>} oldScreenshareSourceNames - List of old screenshare source names.
  27. * @param {Array<string>} newScreenshareSourceNames - Current list of screenshare source names.
  28. * @param {Object} store - The redux store.
  29. * @returns {void}
  30. */
  31. function _createOrRemoveVirtualParticipants(
  32. oldScreenshareSourceNames: string[],
  33. newScreenshareSourceNames: string[],
  34. store: IStore): void {
  35. const { dispatch, getState } = store;
  36. const conference = getCurrentConference(getState());
  37. const removedScreenshareSourceNames = _.difference(oldScreenshareSourceNames, newScreenshareSourceNames);
  38. const addedScreenshareSourceNames = _.difference(newScreenshareSourceNames, oldScreenshareSourceNames);
  39. if (removedScreenshareSourceNames.length) {
  40. removedScreenshareSourceNames.forEach(id => dispatch(participantLeft(id, conference, {
  41. fakeParticipant: FakeParticipant.RemoteScreenShare
  42. })));
  43. }
  44. if (addedScreenshareSourceNames.length) {
  45. addedScreenshareSourceNames.forEach(id => dispatch(
  46. createVirtualScreenshareParticipant(id, false, conference)));
  47. }
  48. }
  49. /**
  50. * Handles creating and removing virtual screenshare participants.
  51. *
  52. * @param {*} store - The redux store.
  53. * @returns {void}
  54. */
  55. function _updateScreenshareParticipants(store: IStore): void {
  56. const { dispatch, getState } = store;
  57. const state = getState();
  58. const conference = getCurrentConference(state);
  59. const tracks = state['features/base/tracks'];
  60. const { sortedRemoteVirtualScreenshareParticipants, localScreenShare } = state['features/base/participants'];
  61. const previousScreenshareSourceNames = [ ...sortedRemoteVirtualScreenshareParticipants.keys() ];
  62. let newLocalSceenshareSourceName;
  63. const currentScreenshareSourceNames = tracks.reduce((acc: string[], track) => {
  64. if (track.videoType === VIDEO_TYPE.DESKTOP && !track.jitsiTrack.isMuted()) {
  65. const sourceName: string = track.jitsiTrack.getSourceName();
  66. if (track.local) {
  67. newLocalSceenshareSourceName = sourceName;
  68. } else {
  69. acc.push(sourceName);
  70. }
  71. }
  72. return acc;
  73. }, []);
  74. if (getMultipleVideoSendingSupportFeatureFlag(state)) {
  75. if (!localScreenShare && newLocalSceenshareSourceName) {
  76. dispatch(createVirtualScreenshareParticipant(newLocalSceenshareSourceName, true, conference));
  77. }
  78. if (localScreenShare && !newLocalSceenshareSourceName) {
  79. dispatch(participantLeft(localScreenShare.id, conference, {
  80. fakeParticipant: FakeParticipant.LocalScreenShare
  81. }));
  82. }
  83. }
  84. if (getSsrcRewritingFeatureFlag(state)) {
  85. return;
  86. }
  87. _createOrRemoveVirtualParticipants(previousScreenshareSourceNames, currentScreenshareSourceNames, store);
  88. }
  89. /**
  90. * Handles the creation and removal of remote virtual screenshare participants when ssrc-rewriting is enabled.
  91. *
  92. * @param {Object} store - The redux store.
  93. * @returns {void}
  94. */
  95. function _updateScreenshareParticipantsBasedOnPresence(store: IStore): void {
  96. const { getState } = store;
  97. const state = getState();
  98. const { sortedRemoteVirtualScreenshareParticipants } = state['features/base/participants'];
  99. const previousScreenshareSourceNames = [ ...sortedRemoteVirtualScreenshareParticipants.keys() ];
  100. const currentScreenshareSourceNames = getRemoteScreensharesBasedOnPresence(state);
  101. _createOrRemoveVirtualParticipants(previousScreenshareSourceNames, currentScreenshareSourceNames, store);
  102. }