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

actions.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import 'image-capture';
  2. import { getCurrentConference } from '../base/conference';
  3. import { getLocalParticipant, getParticipantCount } from '../base/participants';
  4. import { getLocalVideoTrack } from '../base/tracks';
  5. import { getBaseUrl } from '../base/util';
  6. import '../facial-recognition/createImageBitmap';
  7. import {
  8. START_FACE_RECOGNITION,
  9. STOP_FACE_RECOGNITION,
  10. UPDATE_FACE_COORDINATES
  11. } from './actionTypes';
  12. import {
  13. FACE_BOX_MESSAGE,
  14. SEND_IMAGE_INTERVAL_MS
  15. } from './constants';
  16. import { sendDataToWorker, sendFaceBoxToParticipants } from './functions';
  17. import logger from './logger';
  18. /**
  19. * Interval object for sending new image data to worker.
  20. */
  21. let interval;
  22. /**
  23. * Object containing a image capture of the local track.
  24. */
  25. let imageCapture;
  26. /**
  27. * Object where the face centering worker is stored.
  28. */
  29. let worker;
  30. /**
  31. * Loads the worker.
  32. *
  33. * @returns {Function}
  34. */
  35. export function loadWorker() {
  36. return async function(dispatch: Function, getState: Function) {
  37. if (navigator.product === 'ReactNative') {
  38. logger.warn('Unsupported environment for face centering');
  39. return;
  40. }
  41. const baseUrl = getBaseUrl();
  42. let workerUrl = `${baseUrl}libs/face-centering-worker.min.js`;
  43. const workerBlob = new Blob([ `importScripts("${workerUrl}");` ], { type: 'application/javascript' });
  44. workerUrl = window.URL.createObjectURL(workerBlob);
  45. worker = new Worker(workerUrl, { name: 'Face Centering Worker' });
  46. worker.onmessage = function(e: Object) {
  47. const { type, value } = e.data;
  48. // receives a message with the face(s) bounding box.
  49. if (type === FACE_BOX_MESSAGE) {
  50. const state = getState();
  51. const conference = getCurrentConference(state);
  52. const localParticipant = getLocalParticipant(state);
  53. if (getParticipantCount(state) > 1) {
  54. sendFaceBoxToParticipants(conference, value);
  55. }
  56. dispatch({
  57. type: UPDATE_FACE_COORDINATES,
  58. faceBox: value,
  59. id: localParticipant.id
  60. });
  61. }
  62. };
  63. dispatch(startFaceRecognition());
  64. };
  65. }
  66. /**
  67. * Starts the recognition and detection of face position.
  68. *
  69. * @param {Track | undefined} track - Track for which to start detecting faces.
  70. *
  71. * @returns {Function}
  72. */
  73. export function startFaceRecognition(track) {
  74. return async function(dispatch: Function, getState: Function) {
  75. if (!worker) {
  76. return;
  77. }
  78. const state = getState();
  79. const { recognitionActive } = state['features/face-centering'];
  80. if (recognitionActive) {
  81. logger.log('Face centering already active.');
  82. return;
  83. }
  84. const localVideoTrack = track || getLocalVideoTrack(state['features/base/tracks']);
  85. if (!localVideoTrack) {
  86. logger.warn('Face centering is disabled due to missing local track.');
  87. return;
  88. }
  89. dispatch({ type: START_FACE_RECOGNITION });
  90. logger.log('Start face recognition');
  91. const stream = localVideoTrack.jitsiTrack.getOriginalStream();
  92. const firstVideoTrack = stream.getVideoTracks()[0];
  93. imageCapture = new ImageCapture(firstVideoTrack);
  94. const { disableLocalVideoFlip, faceCoordinatesSharing } = state['features/base/config'];
  95. interval = setInterval(() => {
  96. sendDataToWorker(worker, imageCapture, faceCoordinatesSharing?.threshold, !disableLocalVideoFlip);
  97. }, faceCoordinatesSharing?.captureInterval || SEND_IMAGE_INTERVAL_MS);
  98. };
  99. }
  100. /**
  101. * Stops the recognition and detection of face position.
  102. *
  103. * @returns {Function}
  104. */
  105. export function stopFaceRecognition() {
  106. return function(dispatch: Function) {
  107. clearInterval(interval);
  108. interval = null;
  109. imageCapture = null;
  110. dispatch({ type: STOP_FACE_RECOGNITION });
  111. logger.log('Stop face recognition');
  112. };
  113. }