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.

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