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.

index.js 3.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // @flow
  2. import { showWarningNotification } from '../../notifications/actions';
  3. import { timeout } from '../../virtual-background/functions';
  4. import logger from '../../virtual-background/logger';
  5. import JitsiStreamBackgroundEffect from './JitsiStreamBackgroundEffect';
  6. import createTFLiteModule from './vendor/tflite/tflite';
  7. import createTFLiteSIMDModule from './vendor/tflite/tflite-simd';
  8. const models = {
  9. model96: 'libs/segm_lite_v681.tflite',
  10. model144: 'libs/segm_full_v679.tflite'
  11. };
  12. let tflite;
  13. let wasmCheck;
  14. let isWasmDisabled = false;
  15. const segmentationDimensions = {
  16. model96: {
  17. height: 96,
  18. width: 160
  19. },
  20. model144: {
  21. height: 144,
  22. width: 256
  23. }
  24. };
  25. /**
  26. * Creates a new instance of JitsiStreamBackgroundEffect. This loads the Meet background model that is used to
  27. * extract person segmentation.
  28. *
  29. * @param {Object} virtualBackground - The virtual object that contains the background image source and
  30. * the isVirtualBackground flag that indicates if virtual image is activated.
  31. * @param {Function} dispatch - The Redux dispatch function.
  32. * @returns {Promise<JitsiStreamBackgroundEffect>}
  33. */
  34. export async function createVirtualBackgroundEffect(virtualBackground: Object, dispatch: Function) {
  35. if (!MediaStreamTrack.prototype.getSettings && !MediaStreamTrack.prototype.getConstraints) {
  36. throw new Error('JitsiStreamBackgroundEffect not supported!');
  37. }
  38. // Checks if WebAssembly feature is supported or enabled by/in the browser.
  39. // Conditional import of wasm-check package is done to prevent
  40. // the browser from crashing when the user opens the app.
  41. if (!tflite && !isWasmDisabled) {
  42. try {
  43. wasmCheck = require('wasm-check');
  44. const tfliteTimeout = 10000;
  45. if (wasmCheck?.feature?.simd) {
  46. tflite = await timeout(tfliteTimeout, createTFLiteSIMDModule());
  47. } else {
  48. tflite = await timeout(tfliteTimeout, createTFLiteModule());
  49. }
  50. } catch (err) {
  51. isWasmDisabled = true;
  52. if (err?.message === '408') {
  53. logger.error('Failed to download tflite model!');
  54. dispatch(showWarningNotification({
  55. titleKey: 'virtualBackground.backgroundEffectError'
  56. }));
  57. } else {
  58. logger.error('Looks like WebAssembly is disabled or not supported on this browser');
  59. dispatch(showWarningNotification({
  60. titleKey: 'virtualBackground.webAssemblyWarning',
  61. description: 'WebAssembly disabled or not supported by this browser'
  62. }));
  63. }
  64. return;
  65. }
  66. }
  67. const modelBufferOffset = tflite._getModelBufferMemoryOffset();
  68. const modelResponse = await fetch(wasmCheck.feature.simd ? models.model144 : models.model96);
  69. if (!modelResponse.ok) {
  70. throw new Error('Failed to download tflite model!');
  71. }
  72. const model = await modelResponse.arrayBuffer();
  73. tflite.HEAPU8.set(new Uint8Array(model), modelBufferOffset);
  74. tflite._loadModel(model.byteLength);
  75. const options = {
  76. ...wasmCheck.feature.simd ? segmentationDimensions.model144 : segmentationDimensions.model96,
  77. virtualBackground
  78. };
  79. return new JitsiStreamBackgroundEffect(tflite, options);
  80. }