import { Meta } from '@storybook/blocks';

<Meta title="SDK Hooks/useBackgroundReplacement" />

# useBackgroundReplacement

The `useBackgroundReplacement` hook returns a function transforming a normal video device to a `DefaultVideoTransformDevice`, and also a
state called `isBackgroundReplacementSupported` which indicates whether or not background replacement processor is fully loaded and ready to be used.

You should see either "processor is supported" or "processor is not supported" in your browser developer tools based on whether or not
background replacement is supported on your device and browser version. For more information on if background replacement is supported, refer
to [Amazon Chime SDK for JavaScript Background replacement Guide](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 `isBackgroundReplacementSupported`.
`createBackgroundReplacementDevice` 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 `isBackgroundReplacementSupported`
before calling `createBackgroundReplacementDevice`. Calling `createBackgroundReplacementDevice` will create a new processor. Users would also need to stop previously created `DeafultVideoTransformDevice` by calling `DefaultVideoTransformDevice.stop` when constructing a new
`DefaultVideoTransformDevice` with new video processors. 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);
Lastly, make sure to construct a new `DefaultVideoTransformDevice` using `createBackgroundReplacementDevice` and use it as input if the `Props` of the provider were changed.

You can access the current `backgroundReplacementProcessor` 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 BackgroundReplacementProcessor](https://github.com/aws/amazon-chime-sdk-js/blob/main/guides/15_Background_Filter_Video_Processor.md#observer-notifications)

Background replacement related logs can be found in the browser developer tools when the `BackgroundReplacementProvider` is used within the app component tree.

## Return Value

```typescript
{
  // Whether background replacement is finished loading the processor. The default value is undefined, then changes to true or false.
  isBackgroundReplacementSupported: boolean | undefined;

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

```

## Importing

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

## Usage

The hook depends on the `BackgroundReplacementProvider`. You can use it with `MeetingProvider`.

```jsx
import React from 'react';
import { VideoTransformDevice } from 'amazon-chime-sdk-js';
import {
  MeetingProvider,
  BackgroundReplacementProvider,
  useMeetingManager,
  useBackgroundReplacement,
  useVideoInputs,
} from 'amazon-chime-sdk-component-library-react';

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

const MyChild = () => {
  const meetingManager = useMeetingManager();
  const { selectedDevice } = useVideoInputs();
  const [isVideoTransformCheckBoxOn, setisVideoTransformCheckBoxOn] =
    useState(false);
  const {
    isBackgroundReplacementSupported,
    createBackgroundReplacementDevice,
  } = useBackgroundReplacement();

  useEffect(() => {
    async function toggleBackgroundReplacement() {
      try {
        let current = selectedDevice;
        if (isVideoTransformCheckBoxOn) {
          current = await createBackgroundReplacementDevice(selectedDevice);
        } else {
          if (isVideoTransformDevice(selectedDevice)) {
            let intrinsicDevice = await selectedDevice.intrinsicDevice();
            selectedDevice.stop();
            current = intrinsicDevice;
          }
        }
        await meetingManager.startVideoInputDevice(current);
      } catch (error) {
        // Handle device selection failure here
        console.error('Failed to toggle BackgroundReplacement');
      }
    }

    toggleBackgroundReplacement();
  }, [isVideoTransformCheckBoxOn]);

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

  return (
    <div>
      {isBackgroundReplacementSupported && (
        <button onClick={onClick}>
          {isVideoTranformDevice(selectedDevice)
            ? 'Background Replacement Enabled'
            : 'Enable Background Replacement'}
        </button>
      )}
    </div>
  );
};
```

### Dependencies

- `MeetingProvider`
- `BackgroundReplacementProvider`
