import { Meta, ArgTypes } from '@storybook/blocks';
import { BackgroundBlurProvider } from '../';

<Meta title="SDK Providers/BackgroundBlurProvider" />

# BackgroundBlurProvider

The `BackgroundBlurProvider` provides a function transforming a normal video device to a `DefaultVideoTransformDevice`, and also whether or not the background blur feature is supported.
Background blur related logs can be found in the browser developer tools when the `BackgroundBlurProvider` is used within the app component tree.

This provider is independent from `MeetingProvider`. You can put `BackgroundBlurProvider` wherever you want in the component tree so long as any component that relies on
`BackgroundBlurProvider` is nested within `BackgroundBlurProvider`. The `BackgroundBlurProvider` loads the required worker assets
when mounted, which may impact performance.

## State

```typescript
{
  // Whether background blur is supported. The default value is undefined, then changes to true or false.
  isBackgroundBlurSupported: boolean | undefined;

  // A function to transform a video input device to a `DefaultVideoTransformDevice`.
  createBackgroundBlurDevice: (device: Device) => Promise<DefaultVideoTransformDevice>;
}

```

You should see either "processor is supported" or "processor is not supported" in your browser developer tools based on whether or not
background blur is supported on your device and browser version. For more information on if background blur is supported, refer
to [Integrating background filters into your Amazon Chime SDK for JavaScript application](https://github.com/aws/amazon-chime-sdk-js/blob/main/guides/15_Background_Filter_Video_Processor.md#integrating-background-filters-into-your-amazon-chime-sdk-for-javascript-application).

You can check whether or not the processor has been loaded correctly by checking the state of `isBackgroundBlurSupported`.
`createBackgroundBlurDevice` may throw an error if the processor was not loaded. You should check whether or not the processor has been loaded correctly by checking the state of `isBackgroundBlurSupported`
before calling `createBackgroundBlurDevice`. Calling `createBackgroundBlurDevice` will create a new `DefaultVideoTransformDevice`. Users would also need to call `DefaultVideoTransformDevice.stop` when constructing a new
`DefaultVideoTransformDevice` with `createBackgroundBlurDevice` in order to destroy the processors running previously. Once you call `DefaultVideoTransformDevice.stop`, you should discard the old `DefaultVideoTransformDevice`.
For more information, refer to [Video Processing APIs](https://github.com/aws/amazon-chime-sdk-js/blob/main/guides/10_Video_Processor.md#stopping-videotransformdevice).

You can access the current `backgroundBlurProcessor` applied to the video device that is generated when you call `createBackgroundBlurDevice`. You can apply observer notifications to the processor. Refer to [the guide for adding observer notifications to a BackgroundBlurProcessor](https://github.com/aws/amazon-chime-sdk-js/blob/main/guides/15_Background_Filter_Video_Processor.md#observer-notifications)

One thing to note is that calling `meetingManager.startVideoInputDevice()` with a `Device` type while the current selected video input device is a `VideoTransformDevice`
will automatically stop any video processor that was previously running. Lastly, make sure to construct a new `DefaultVideoTransformDevice` using `createBackgroundBlurDevice`.
if the Props of the provider were changed.

You can access the state by using the [useBackgroundBlur](/docs/sdk-hooks-usebackgroundblur--page) hook.

## Props

<ArgTypes of={BackgroundBlurProvider} />

## Importing

```javascript
import { BackgroundBlurProvider } from 'amazon-chime-sdk-component-library-react';
```

## Usage

```jsx
import React from 'react';
import {
  isVideoTranformDevice,
  VideoTransformDevice,
} from 'amazon-chime-sdk-js';
import {
  MeetingProvider,
  BackgroundBlurProvider,
  useMeetingManager,
  useBackgroundBlur,
} from 'amazon-chime-sdk-component-library-react';

const App = () => (
  <BackgroundBlurProvider>
    <MeetingProvider>
      <MyChild />
    </MeetingProvider>
  </BackgroundBlurProvider>
);

const MyChild = () => {
  const meetingManager = useMeetingManager();
  const [isVideoTransformChecked, setIsVideoTransformCheckOn] = useState(false);
  const { selectedDevice } = useVideoInputs();
  const { isBackgroundBlurSupported, createBackgroundBlurDevice } =
    useBackgroundBlur();

  useEffect(() => {
    async function toggleBackgroundBlur() {
      if (!selectedDevice) {
        return;
      }

      try {
        let current = selectedDevice;
        if (isVideoTransformChecked) {
          current = await createBackgroundBlurDevice(selectedDevice);
        } else {
          if (isVideoTransformDevice(selectedDevice)) {
            current = await selectedDevice.intrinsicDevice();
          }
        }
        await meetingManager.startVideoInputDevice(current);
      } catch (error) {
        // Handle device selection failure here
        console.error('Failed to toggle BackgroundBlur');
      }
    }

    toggleBackgroundBlur();
  }, [isVideoTransformChecked]);

  const onClick = () => {
    setisVideoTransformCheckOn((current) => !current);
  };

  return (
    <div>
      {isBackgroundBlurSupported && (
        <button onClick={onClick}>
          {isVideoTranformDevice(device)
            ? 'Background Blur Enabled'
            : 'Enable Background Blur'}
        </button>
      )}
    </div>
  );
};
```

### Dependencies

- `MeetingProvider`
- `BackgroundBlurProvider`
