Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

middleware.ts 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { AnyAction } from 'redux';
  2. import { IStore } from '../app/types';
  3. import {
  4. CONFERENCE_JOINED,
  5. CONFERENCE_WILL_LEAVE
  6. } from '../base/conference/actionTypes';
  7. import { getCurrentConference } from '../base/conference/functions';
  8. import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
  9. import { getLocalParticipant, getParticipantCount } from '../base/participants/functions';
  10. import { IParticipant } from '../base/participants/types';
  11. import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
  12. import { TRACK_ADDED, TRACK_REMOVED, TRACK_UPDATED } from '../base/tracks/actionTypes';
  13. import FaceLandmarksDetector from './FaceLandmarksDetector';
  14. import { ADD_FACE_LANDMARKS, NEW_FACE_COORDINATES, UPDATE_FACE_COORDINATES } from './actionTypes';
  15. import { FACE_BOX_EVENT_TYPE } from './constants';
  16. import { sendFaceBoxToParticipants, sendFaceExpressionToParticipants, sendFaceExpressionToServer } from './functions';
  17. MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: AnyAction) => {
  18. const { dispatch, getState } = store;
  19. const { faceLandmarks: faceLandmarksConfig } = getState()['features/base/config'];
  20. const isEnabled = faceLandmarksConfig?.enableFaceCentering || faceLandmarksConfig?.enableFaceExpressionsDetection;
  21. if (action.type === CONFERENCE_JOINED) {
  22. if (isEnabled) {
  23. FaceLandmarksDetector.init(store);
  24. }
  25. // allow using remote face centering data when local face centering is not enabled
  26. action.conference.on(
  27. JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
  28. (participant: IParticipant | undefined, eventData: any) => {
  29. if (!participant || !eventData || !participant.getId) {
  30. return;
  31. }
  32. if (eventData.type === FACE_BOX_EVENT_TYPE) {
  33. dispatch({
  34. type: UPDATE_FACE_COORDINATES,
  35. faceBox: eventData.faceBox,
  36. id: participant.getId()
  37. });
  38. }
  39. });
  40. return next(action);
  41. }
  42. if (!isEnabled) {
  43. return next(action);
  44. }
  45. switch (action.type) {
  46. case CONFERENCE_WILL_LEAVE : {
  47. FaceLandmarksDetector.stopDetection(store);
  48. return next(action);
  49. }
  50. case TRACK_ADDED: {
  51. const { jitsiTrack: { isLocal, videoType }, muted } = action.track;
  52. if (videoType === 'camera' && isLocal() && !muted) {
  53. // need to pass this since the track is not yet added in the store
  54. FaceLandmarksDetector.startDetection(store, action.track);
  55. }
  56. return next(action);
  57. }
  58. case TRACK_UPDATED: {
  59. const { jitsiTrack: { isLocal, videoType } } = action.track;
  60. if (videoType !== 'camera' || !isLocal()) {
  61. return next(action);
  62. }
  63. const { muted } = action.track;
  64. if (muted !== undefined) {
  65. // addresses video mute state changes
  66. if (muted) {
  67. FaceLandmarksDetector.stopDetection(store);
  68. } else {
  69. FaceLandmarksDetector.startDetection(store);
  70. }
  71. }
  72. return next(action);
  73. }
  74. case TRACK_REMOVED: {
  75. const { jitsiTrack: { isLocal, videoType } } = action.track;
  76. if (videoType === 'camera' && isLocal()) {
  77. FaceLandmarksDetector.stopDetection(store);
  78. }
  79. return next(action);
  80. }
  81. case ADD_FACE_LANDMARKS: {
  82. const state = getState();
  83. const { faceLandmarks } = action;
  84. const conference = getCurrentConference(state);
  85. if (getParticipantCount(state) > 1) {
  86. sendFaceExpressionToParticipants(conference, faceLandmarks);
  87. }
  88. sendFaceExpressionToServer(conference, faceLandmarks);
  89. return next(action);
  90. }
  91. case NEW_FACE_COORDINATES: {
  92. const state = getState();
  93. const { faceBox } = action;
  94. const conference = getCurrentConference(state);
  95. const localParticipant = getLocalParticipant(state);
  96. if (getParticipantCount(state) > 1) {
  97. sendFaceBoxToParticipants(conference, faceBox);
  98. }
  99. dispatch({
  100. type: UPDATE_FACE_COORDINATES,
  101. faceBox,
  102. id: localParticipant?.id
  103. });
  104. }
  105. }
  106. return next(action);
  107. });