From 9b136cef0bb4612a4e5ef65357a3775c86a035d9 Mon Sep 17 00:00:00 2001 From: bxg Date: Mon, 18 Nov 2024 16:20:28 +0800 Subject: [PATCH] add mic volume indication (#204) --- src/components/volume/MicVolume.tsx | 46 +++++++++++++++++++++++++++++ src/views/join/Join.tsx | 2 ++ 2 files changed, 48 insertions(+) create mode 100644 src/components/volume/MicVolume.tsx diff --git a/src/components/volume/MicVolume.tsx b/src/components/volume/MicVolume.tsx new file mode 100644 index 00000000..b02a27c1 --- /dev/null +++ b/src/components/volume/MicVolume.tsx @@ -0,0 +1,46 @@ +import LinearProgress from '@mui/material/LinearProgress'; +import { useContext, useEffect, useState } from 'react'; +import { ServiceContext } from '../../store/store'; +import { VolumeWatcher } from '../../utils/volumeWatcher'; +import hark from 'hark'; + +const MicVolume = (): JSX.Element => { + const { mediaService } = useContext(ServiceContext); + const [ volumeLevel, setVolume ] = useState(0); + + useEffect(() => { + let volumeWatcher: VolumeWatcher | undefined; + + // Add hark for mic + if (mediaService.previewMicTrack) { + const harkStream = new MediaStream(); + + harkStream.addTrack(mediaService.previewMicTrack.clone()); + + const micHark = hark(harkStream, { + play: false, + interval: 100, + threshold: -60, + history: 100 + }); + + volumeWatcher = new VolumeWatcher({ hark: micHark }); + } + + const onVolumeChange = ({ scaledVolume }: { scaledVolume: number }): void => { + setVolume(scaledVolume*10); // Range: 0-100 + }; + + volumeWatcher?.on('volumeChange', onVolumeChange); + + return () => { + volumeWatcher?.off('volumeChange', onVolumeChange); + }; + }, [ mediaService.previewMicTrack ]); + + return ( + + ); +}; + +export default MicVolume; diff --git a/src/views/join/Join.tsx b/src/views/join/Join.tsx index 535b13ce..7e2b81a1 100644 --- a/src/views/join/Join.tsx +++ b/src/views/join/Join.tsx @@ -19,6 +19,7 @@ import AudioOutputChooser from '../../components/devicechooser/AudioOutputChoose import { canSelectAudioOutput } from '../../store/selectors'; import TestAudioOutputButton from '../../components/audiooutputtest/AudioOutputTest'; import ImpressumButton from '../../components/controlbuttons/ImpressumButton'; +import MicVolume from '../../components/volume/MicVolume'; interface JoinProps { roomId: string; @@ -70,6 +71,7 @@ const Join = ({ roomId }: JoinProps): React.JSX.Element => { { showAudioOutputChooser && } +