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.

functions.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // @flow
  2. import { JitsiTrackEvents } from '../base/lib-jitsi-meet';
  3. import { updateSettings } from '../base/settings';
  4. import { toggleBackgroundEffect } from './actions';
  5. let filterSupport;
  6. /**
  7. * Checks context filter support.
  8. *
  9. * @returns {boolean} True if the filter is supported and false if the filter is not supported by the browser.
  10. */
  11. export function checkBlurSupport() {
  12. if (typeof filterSupport === 'undefined') {
  13. const canvas = document.createElement('canvas');
  14. const ctx = canvas.getContext('2d');
  15. filterSupport = typeof ctx.filter !== 'undefined';
  16. canvas.remove();
  17. }
  18. return filterSupport;
  19. }
  20. /**
  21. * Convert blob to base64.
  22. *
  23. * @param {Blob} blob - The link to add info with.
  24. * @returns {Promise<string>}
  25. */
  26. export const blobToData = (blob: Blob): Promise<string> =>
  27. new Promise(resolve => {
  28. const reader = new FileReader();
  29. reader.onloadend = () => resolve(reader.result.toString());
  30. reader.readAsDataURL(blob);
  31. });
  32. /**
  33. * Convert blob to base64.
  34. *
  35. * @param {string} url - The image url.
  36. * @returns {Object} - Returns the converted blob to base64.
  37. */
  38. export const toDataURL = async (url: string) => {
  39. const response = await fetch(url);
  40. const blob = await response.blob();
  41. const resData = await blobToData(blob);
  42. return resData;
  43. };
  44. /**
  45. * Resize image and adjust original aspect ratio.
  46. *
  47. * @param {Object} base64image - Base64 image extraction.
  48. * @param {number} width - Value for resizing the image width.
  49. * @param {number} height - Value for resizing the image height.
  50. * @returns {Promise<string>}
  51. *
  52. */
  53. export function resizeImage(base64image: any, width: number = 1920, height: number = 1080): Promise<string> {
  54. // In order to work on Firefox browser we need to handle the asynchronous nature of image loading; We need to use
  55. // a promise mechanism. The reason why it 'works' without this mechanism in Chrome is actually 'by accident' because
  56. // the image happens to be in the cache and the browser is able to deliver the uncompressed/decoded image
  57. // before using the image in the drawImage call.
  58. return new Promise(resolve => {
  59. const img = document.createElement('img');
  60. img.onload = function() {
  61. // Create an off-screen canvas.
  62. const canvas = document.createElement('canvas');
  63. // Set its dimension to target size.
  64. const context = canvas.getContext('2d');
  65. canvas.width = width;
  66. canvas.height = height;
  67. // Draw source image into the off-screen canvas.
  68. // TODO: keep aspect ratio and implement object-fit: cover.
  69. context.drawImage(img, 0, 0, width, height);
  70. // Encode image to data-uri with base64 version of compressed image.
  71. resolve(canvas.toDataURL('image/jpeg', 0.5));
  72. };
  73. img.src = base64image;
  74. });
  75. }
  76. /**
  77. * Check if the local desktop track was stopped and apply none option on virtual background.
  78. *
  79. * @param {Function} dispatch - The Redux dispatch function.
  80. * @param {Object} desktopTrack - The desktop track that needs to be checked if it was stopped.
  81. * @param {Object} currentLocalTrack - The current local track where we apply none virtual
  82. * background option if the desktop track was stopped.
  83. * @returns {Promise}
  84. */
  85. export function localTrackStopped(dispatch: Function, desktopTrack: Object, currentLocalTrack: Object) {
  86. const noneOptions = {
  87. enabled: false,
  88. backgroundType: 'none',
  89. selectedThumbnail: 'none',
  90. backgroundEffectEnabled: false
  91. };
  92. desktopTrack
  93. && desktopTrack.on(JitsiTrackEvents.LOCAL_TRACK_STOPPED, () => {
  94. dispatch(toggleBackgroundEffect(noneOptions, currentLocalTrack));
  95. // Set x scale to default value.
  96. dispatch(updateSettings({
  97. localFlipX: true
  98. }));
  99. });
  100. }
  101. /**
  102. * Creating a wrapper for promises on a specific time interval.
  103. *
  104. * @param {number} milliseconds - The number of milliseconds to wait the specified
  105. * {@code promise} to settle before automatically rejecting the returned
  106. * {@code Promise}.
  107. * @param {Promise} promise - The {@code Promise} for which automatic rejecting
  108. * after the specified timeout is to be implemented.
  109. * @returns {Promise}
  110. */
  111. export function timeout(milliseconds: number, promise: Promise<*>): Promise<Object> {
  112. return new Promise((resolve, reject) => {
  113. setTimeout(() => {
  114. reject(new Error('408'));
  115. return;
  116. }, milliseconds);
  117. promise.then(resolve, reject);
  118. });
  119. }