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 5.0KB

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