您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

middleware.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* @flow */
  2. import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
  3. import { CONFERENCE_WILL_JOIN, getCurrentConference } from '../base/conference';
  4. import JitsiMeetJS, {
  5. JitsiConferenceEvents,
  6. JitsiRecordingConstants
  7. } from '../base/lib-jitsi-meet';
  8. import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
  9. import {
  10. playSound,
  11. registerSound,
  12. stopSound,
  13. unregisterSound
  14. } from '../base/sounds';
  15. import {
  16. clearRecordingSessions,
  17. hidePendingRecordingNotification,
  18. showPendingRecordingNotification,
  19. showRecordingError,
  20. showStoppedRecordingNotification,
  21. updateRecordingSessionData
  22. } from './actions';
  23. import { RECORDING_SESSION_UPDATED } from './actionTypes';
  24. import { RECORDING_OFF_SOUND_ID, RECORDING_ON_SOUND_ID } from './constants';
  25. import { getSessionById } from './functions';
  26. import {
  27. RECORDING_OFF_SOUND_FILE,
  28. RECORDING_ON_SOUND_FILE
  29. } from './sounds';
  30. /**
  31. * StateListenerRegistry provides a reliable way to detect the leaving of a
  32. * conference, where we need to clean up the recording sessions.
  33. */
  34. StateListenerRegistry.register(
  35. /* selector */ state => getCurrentConference(state),
  36. /* listener */ (conference, { dispatch }) => {
  37. if (!conference) {
  38. dispatch(clearRecordingSessions());
  39. }
  40. }
  41. );
  42. /**
  43. * The redux middleware to handle the recorder updates in a React way.
  44. *
  45. * @param {Store} store - The redux store.
  46. * @returns {Function}
  47. */
  48. MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
  49. let oldSessionData;
  50. if (action.type === RECORDING_SESSION_UPDATED) {
  51. oldSessionData
  52. = getSessionById(getState(), action.sessionData.id);
  53. }
  54. const result = next(action);
  55. switch (action.type) {
  56. case APP_WILL_MOUNT:
  57. dispatch(registerSound(
  58. RECORDING_OFF_SOUND_ID,
  59. RECORDING_OFF_SOUND_FILE));
  60. dispatch(registerSound(
  61. RECORDING_ON_SOUND_ID,
  62. RECORDING_ON_SOUND_FILE));
  63. break;
  64. case APP_WILL_UNMOUNT:
  65. dispatch(unregisterSound(RECORDING_OFF_SOUND_ID));
  66. dispatch(unregisterSound(RECORDING_ON_SOUND_ID));
  67. break;
  68. case CONFERENCE_WILL_JOIN: {
  69. const { conference } = action;
  70. conference.on(
  71. JitsiConferenceEvents.RECORDER_STATE_CHANGED,
  72. recorderSession => {
  73. if (recorderSession) {
  74. recorderSession.getID()
  75. && dispatch(
  76. updateRecordingSessionData(recorderSession));
  77. recorderSession.getError()
  78. && _showRecordingErrorNotification(
  79. recorderSession, dispatch);
  80. }
  81. return;
  82. });
  83. break;
  84. }
  85. case RECORDING_SESSION_UPDATED: {
  86. const updatedSessionData
  87. = getSessionById(getState(), action.sessionData.id);
  88. const { PENDING, OFF, ON } = JitsiRecordingConstants.status;
  89. if (updatedSessionData.status === PENDING
  90. && (!oldSessionData || oldSessionData.status !== PENDING)) {
  91. dispatch(
  92. showPendingRecordingNotification(updatedSessionData.mode));
  93. } else if (updatedSessionData.status !== PENDING) {
  94. dispatch(
  95. hidePendingRecordingNotification(updatedSessionData.mode));
  96. if (updatedSessionData.status === ON
  97. && (!oldSessionData || oldSessionData.status !== ON)
  98. && updatedSessionData.mode
  99. === JitsiRecordingConstants.mode.FILE) {
  100. dispatch(playSound(RECORDING_ON_SOUND_ID));
  101. } else if (updatedSessionData.status === OFF
  102. && (!oldSessionData || oldSessionData.status !== OFF)) {
  103. dispatch(
  104. showStoppedRecordingNotification(
  105. updatedSessionData.mode));
  106. if (updatedSessionData.mode
  107. === JitsiRecordingConstants.mode.FILE) {
  108. dispatch(stopSound(RECORDING_ON_SOUND_ID));
  109. dispatch(playSound(RECORDING_OFF_SOUND_ID));
  110. }
  111. }
  112. }
  113. break;
  114. }
  115. }
  116. return result;
  117. });
  118. /**
  119. * Shows a notification about an error in the recording session. A
  120. * default notification will display if no error is specified in the passed
  121. * in recording session.
  122. *
  123. * @private
  124. * @param {Object} recorderSession - The recorder session model from the
  125. * lib.
  126. * @param {Dispatch} dispatch - The Redux Dispatch function.
  127. * @returns {void}
  128. */
  129. function _showRecordingErrorNotification(recorderSession, dispatch) {
  130. const isStreamMode
  131. = recorderSession.getMode()
  132. === JitsiMeetJS.constants.recording.mode.STREAM;
  133. switch (recorderSession.getError()) {
  134. case JitsiMeetJS.constants.recording.error.SERVICE_UNAVAILABLE:
  135. dispatch(showRecordingError({
  136. descriptionKey: 'recording.unavailable',
  137. descriptionArguments: {
  138. serviceName: isStreamMode
  139. ? 'Live Streaming service'
  140. : 'Recording service'
  141. },
  142. titleKey: isStreamMode
  143. ? 'liveStreaming.unavailableTitle'
  144. : 'recording.unavailableTitle'
  145. }));
  146. break;
  147. case JitsiMeetJS.constants.recording.error.RESOURCE_CONSTRAINT:
  148. dispatch(showRecordingError({
  149. descriptionKey: isStreamMode
  150. ? 'liveStreaming.busy'
  151. : 'recording.busy',
  152. titleKey: isStreamMode
  153. ? 'liveStreaming.busyTitle'
  154. : 'recording.busyTitle'
  155. }));
  156. break;
  157. default:
  158. dispatch(showRecordingError({
  159. descriptionKey: isStreamMode
  160. ? 'liveStreaming.error'
  161. : 'recording.error',
  162. titleKey: isStreamMode
  163. ? 'liveStreaming.failedToStart'
  164. : 'recording.failedToStart'
  165. }));
  166. break;
  167. }
  168. }