Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

functions.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // @flow
  2. import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
  3. import { getLocalParticipant } from '../base/participants';
  4. import { isEnabled as isDropboxEnabled } from '../dropbox';
  5. import { extractFqnFromPath } from '../dynamic-branding';
  6. import { RECORDING_STATUS_PRIORITIES, RECORDING_TYPES } from './constants';
  7. import logger from './logger';
  8. /**
  9. * Searches in the passed in redux state for an active recording session of the
  10. * passed in mode.
  11. *
  12. * @param {Object} state - The redux state to search in.
  13. * @param {string} mode - Find an active recording session of the given mode.
  14. * @returns {Object|undefined}
  15. */
  16. export function getActiveSession(state: Object, mode: string) {
  17. const { sessionDatas } = state['features/recording'];
  18. const { status: statusConstants } = JitsiRecordingConstants;
  19. return sessionDatas.find(sessionData => sessionData.mode === mode
  20. && (sessionData.status === statusConstants.ON
  21. || sessionData.status === statusConstants.PENDING));
  22. }
  23. /**
  24. * Returns an estimated recording duration based on the size of the video file
  25. * in MB. The estimate is calculated under the assumption that 1 min of recorded
  26. * video needs 10MB of storage on average.
  27. *
  28. * @param {number} size - The size in MB of the recorded video.
  29. * @returns {number} - The estimated duration in minutes.
  30. */
  31. export function getRecordingDurationEstimation(size: ?number) {
  32. return Math.floor((size || 0) / 10);
  33. }
  34. /**
  35. * Searches in the passed in redux state for a recording session that matches
  36. * the passed in recording session ID.
  37. *
  38. * @param {Object} state - The redux state to search in.
  39. * @param {string} id - The ID of the recording session to find.
  40. * @returns {Object|undefined}
  41. */
  42. export function getSessionById(state: Object, id: string) {
  43. return state['features/recording'].sessionDatas.find(
  44. sessionData => sessionData.id === id);
  45. }
  46. /**
  47. * Fetches the recording link from the server.
  48. *
  49. * @param {string} url - The base url.
  50. * @param {string} recordingSessionId - The ID of the recording session to find.
  51. * @param {string} region - The meeting region.
  52. * @param {string} tenant - The meeting tenant.
  53. * @returns {Promise<any>}
  54. */
  55. export async function getRecordingLink(url: string, recordingSessionId: string, region: string, tenant: string) {
  56. const fullUrl = `${url}?recordingSessionId=${recordingSessionId}&region=${region}&tenant=${tenant}`;
  57. const res = await fetch(fullUrl, {
  58. headers: {
  59. 'Content-Type': 'application/json'
  60. }
  61. });
  62. const json = await res.json();
  63. return res.ok ? json : Promise.reject(json);
  64. }
  65. /**
  66. * Selector used for determining if recording is saved on dropbox.
  67. *
  68. * @param {Object} state - The redux state to search in.
  69. * @returns {string}
  70. */
  71. export function isSavingRecordingOnDropbox(state: Object) {
  72. return isDropboxEnabled(state)
  73. && state['features/recording'].selectedRecordingService === RECORDING_TYPES.DROPBOX;
  74. }
  75. /**
  76. * Selector used for determining disable state for the meeting highlight button.
  77. *
  78. * @param {Object} state - The redux state to search in.
  79. * @returns {string}
  80. */
  81. export function isHighlightMeetingMomentDisabled(state: Object) {
  82. return state['features/recording'].disableHighlightMeetingMoment;
  83. }
  84. /**
  85. * Returns the recording session status that is to be shown in a label. E.g. If
  86. * there is a session with the status OFF and one with PENDING, then the PENDING
  87. * one will be shown, because that is likely more important for the user to see.
  88. *
  89. * @param {Object} state - The redux state to search in.
  90. * @param {string} mode - The recording mode to get status for.
  91. * @returns {string|undefined}
  92. */
  93. export function getSessionStatusToShow(state: Object, mode: string): ?string {
  94. const recordingSessions = state['features/recording'].sessionDatas;
  95. let status;
  96. if (Array.isArray(recordingSessions)) {
  97. for (const session of recordingSessions) {
  98. if (session.mode === mode
  99. && (!status
  100. || (RECORDING_STATUS_PRIORITIES.indexOf(session.status)
  101. > RECORDING_STATUS_PRIORITIES.indexOf(status)))) {
  102. status = session.status;
  103. }
  104. }
  105. }
  106. return status;
  107. }
  108. /**
  109. * Returns the resource id.
  110. *
  111. * @param {Object | string} recorder - A participant or it's resource.
  112. * @returns {string|undefined}
  113. */
  114. export function getResourceId(recorder: string | Object) {
  115. if (recorder) {
  116. return typeof recorder === 'string'
  117. ? recorder
  118. : recorder.getId();
  119. }
  120. }
  121. /**
  122. * Sends a meeting highlight to backend.
  123. *
  124. * @param {Object} state - Redux state.
  125. * @returns {boolean} - True if sent, false otherwise.
  126. */
  127. export async function sendMeetingHighlight(state: Object) {
  128. const { webhookProxyUrl: url } = state['features/base/config'];
  129. const { conference } = state['features/base/conference'];
  130. const { jwt } = state['features/base/jwt'];
  131. const { connection } = state['features/base/connection'];
  132. const jid = connection.getJid();
  133. const localParticipant = getLocalParticipant(state);
  134. const headers = {
  135. ...jwt ? { 'Authorization': `Bearer ${jwt}` } : {},
  136. 'Content-Type': 'application/json'
  137. };
  138. const reqBody = {
  139. meetingFqn: extractFqnFromPath(state),
  140. sessionId: conference.sessionId,
  141. submitted: Date.now(),
  142. participantId: localParticipant.jwtId,
  143. participantName: localParticipant.name,
  144. participantJid: jid
  145. };
  146. if (url) {
  147. try {
  148. const res = await fetch(`${url}/v2/highlights`, {
  149. method: 'POST',
  150. headers,
  151. body: JSON.stringify(reqBody)
  152. });
  153. if (res.ok) {
  154. return true;
  155. }
  156. logger.error('Status error:', res.status);
  157. } catch (err) {
  158. logger.error('Could not send request', err);
  159. }
  160. }
  161. return false;
  162. }