import React, { useEffect, useRef, useState } from 'react'; import { useMedia } from 'react-use'; import { HMSMediaStreamPlugin, selectAppData, selectEffectsKey, selectIsEffectsEnabled, selectLocalPeerRole, } from '@100mslive/hms-video-store'; // Open issue with eslint-plugin-import https://github.com/import-js/eslint-plugin-import/issues/1810 // eslint-disable-next-line import { HMSVBPlugin, HMSVirtualBackgroundTypes } from '@100mslive/hms-virtual-background/hmsvbplugin'; import { VirtualBackgroundMedia } from '@100mslive/types-prebuilt/elements/virtual_background'; import { HMSRoomState, selectIsLargeRoom, selectIsLocalVideoEnabled, selectIsLocalVideoPluginPresent, selectLocalPeer, selectRoomState, selectVideoTrackByID, useHMSActions, useHMSStore, } from '@100mslive/react-sdk'; import { BlurPersonHighIcon, CrossCircleIcon, CrossIcon } from '@100mslive/react-icons'; import { Box, config as cssConfig, Flex, Loading, Slider, Video } from '../../../index'; import { Text } from '../../../Text'; import { VBCollection } from './VBCollection'; import { VBHandler } from './VBHandler'; // @ts-ignore import { useSidepaneToggle } from '../AppData/useSidepane'; import { useSidepaneResetOnLayoutUpdate } from '../AppData/useSidepaneResetOnLayoutUpdate'; // @ts-ignore import { useSetAppDataByKey, useUISettings } from '../AppData/useUISettings'; import { APP_DATA, SIDE_PANE_OPTIONS, UI_SETTINGS } from '../../common/constants'; const iconDims = { height: '40px', width: '40px' }; export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBackgroundMedia[] }) => { const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB); const hmsActions = useHMSActions(); const localPeer = useHMSStore(selectLocalPeer); const role = useHMSStore(selectLocalPeerRole); const isVideoOn = useHMSStore(selectIsLocalVideoEnabled); const mirrorLocalVideo = useUISettings(UI_SETTINGS.mirrorLocalVideo); const trackSelector = selectVideoTrackByID(localPeer?.videoTrack); const track = useHMSStore(trackSelector); const [blurAmount, setBlurAmount] = useState(VBHandler.getBlurAmount() || 0.5); const roomState = useHMSStore(selectRoomState); const isLargeRoom = useHMSStore(selectIsLargeRoom); const isEffectsSupported = VBHandler.isEffectsSupported(); const isEffectsEnabled = useHMSStore(selectIsEffectsEnabled); const effectsKey = useHMSStore(selectEffectsKey); const isMobile = useMedia(cssConfig.media.md); const [loadingEffects, setLoadingEffects] = useSetAppDataByKey(APP_DATA.loadingEffects); const isPluginAdded = useHMSStore(selectIsLocalVideoPluginPresent(VBHandler?.getName() || '')); const background = useHMSStore(selectAppData(APP_DATA.background)); const mediaList = backgroundMedia.map((media: VirtualBackgroundMedia) => media.url || ''); const pluginLoadingRef = useRef(false); const isBlurSupported = VBHandler?.isBlurSupported(); const inPreview = roomState === HMSRoomState.Preview; // Hidden in preview as the effect will be visible in the preview tile const showVideoTile = isVideoOn && isLargeRoom && !inPreview; useEffect(() => { const addHMSVBPlugin = async () => { setLoadingEffects(false); if (!role) { return; } await VBHandler.initialisePlugin(); await hmsActions.addPluginToVideoTrack( VBHandler.getVBObject() as HMSVBPlugin, Math.floor(role.publishParams.video.frameRate / 2), ); }; const initializeVirtualBackground = async () => { if (!track?.id || pluginLoadingRef.current || isPluginAdded) { return; } try { pluginLoadingRef.current = true; if (isEffectsEnabled && isEffectsSupported && effectsKey) { setLoadingEffects(true); await VBHandler.initialisePlugin(effectsKey, () => { setLoadingEffects(false); }); const vbInstance = VBHandler.getVBObject(); if (vbInstance.getName() === 'HMSEffects') { hmsActions.addPluginsToVideoStream([VBHandler.getVBObject() as HMSMediaStreamPlugin]); } else { await addHMSVBPlugin(); } } else { await addHMSVBPlugin(); } const handleDefaultBackground = async () => { switch (background) { case HMSVirtualBackgroundTypes.NONE: break; case HMSVirtualBackgroundTypes.BLUR: await VBHandler.setBlur(blurAmount); break; default: await VBHandler.setBackground(background); } }; await handleDefaultBackground(); } catch (error) { console.error('Error initializing virtual background:', error); setLoadingEffects(false); } }; initializeVirtualBackground(); }, [ hmsActions, role, isPluginAdded, isEffectsEnabled, isEffectsSupported, effectsKey, track?.id, background, blurAmount, setLoadingEffects, ]); useEffect(() => { if (!isVideoOn) { toggleVB(); } return () => setLoadingEffects(false); }, [isVideoOn, setLoadingEffects, toggleVB]); useSidepaneResetOnLayoutUpdate('virtual_background', SIDE_PANE_OPTIONS.VB); return ( Virtual Background {isMobile && loadingEffects ? : ''} {showVideoTile ? ( ); };