// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 import { Device, isVideoTransformDevice } from 'amazon-chime-sdk-js'; import React, { ChangeEvent, useState, useEffect } from 'react'; import { useBackgroundBlur, useBackgroundReplacement, FormField, Select, useVideoInputs, useMeetingManager, } from 'amazon-chime-sdk-component-library-react'; import { VideoTransformOptions, VideoTransformDropdownOptionType } from '../../../types/index'; interface Props { /* Title for the dropdown, defaults to `Video Transform Dropdown` */ label?: string; } export const VideoTransformDropdown: React.FC = ({ label = 'Video Transform Dropdown', }) => { const [transformOption, setTransformOption] = useState(VideoTransformOptions.None); // Both hooks are needed because this component uses both blur and replacement filters. const { isBackgroundBlurSupported, createBackgroundBlurDevice } = useBackgroundBlur(); const { isBackgroundReplacementSupported, createBackgroundReplacementDevice } = useBackgroundReplacement(); const [isLoading, setIsLoading] = useState(false); const meetingManager = useMeetingManager(); const { selectedDevice } = useVideoInputs(); // useEffect to listen on selected video input device if changed by other components useEffect(() => { if (!isVideoTransformDevice(selectedDevice) && transformOption !== VideoTransformOptions.None) { setTransformOption(VideoTransformOptions.None); } }, [selectedDevice]); // Available background filter options based off if Background Blur and Replacement ware offered/supported. const options: VideoTransformDropdownOptionType[] = [ { label: VideoTransformOptions.None, value: VideoTransformOptions.None, }, { label: VideoTransformOptions.Blur, value: isBackgroundBlurSupported === undefined || isBackgroundBlurSupported === false ? 'Background Blur not supported' : VideoTransformOptions.Blur, }, { label: VideoTransformOptions.Replacement, value: isBackgroundReplacementSupported === undefined || isBackgroundReplacementSupported === false ? 'Background Replacement not supported' : VideoTransformOptions.Replacement, }, ]; // Creates a device based on the selections (None, Blur, Replacement) and uses it as input. const selectTransform = async (e: ChangeEvent) => { const selectedTransform = e.target.value; let currentDevice = selectedDevice; if (isLoading || currentDevice === undefined) { return; } try { setIsLoading(true); // If current selectedDevice is a transform device (blur or replacement) then store currentDevice as the intrinsic device for now. if (isVideoTransformDevice(currentDevice)) { const intrinsicDevice = await currentDevice.intrinsicDevice(); await currentDevice.stop(); currentDevice = intrinsicDevice; } // If the new selection is `Background Blur` then create a blur device. Else if the new selected transform is replacement then create // a replacement device. Otherwise, the user selected `None` therefore do nothing because currentDevice is the intrinsic from the above logic. if (selectedTransform === VideoTransformOptions.Blur && isBackgroundBlurSupported) { currentDevice = await createBackgroundBlurDevice(currentDevice as Device); } else if (selectedTransform === VideoTransformOptions.Replacement && isBackgroundReplacementSupported) { currentDevice = await createBackgroundReplacementDevice(currentDevice as Device); } // Select the newly created device from the above logic as the video input device. await meetingManager.startVideoInputDevice(currentDevice); // Update the current selected transform. setTransformOption(selectedTransform); } catch (e) { console.error('Error trying to apply', selectTransform, e); } finally { setIsLoading(false); } }; return ( ); }; export default VideoTransformDropdown;