11import * as React from 'react' ;
22import { useEffect } from 'react' ;
33
4- import { BbbPluginSdk , ExternalVideoVolumeEventsNames , PluginApi } from 'bigbluebutton-html-plugin-sdk' ;
4+ import { BbbPluginSdk , ExternalVideoVolumeUiDataNames , PluginApi } from 'bigbluebutton-html-plugin-sdk' ;
55import { DecreaseVolumeOnSpeakProps , ExternalVideoMeetingSubscription } from './types' ;
66import MEETING_SUBSCRIPTION from './subscription' ;
77
8+ const intervalBetweenIteration = 100 ; // In milliseconds
9+ const totalIterationsToDecrease = 10 ;
10+ const finalVolumeTarget = 0.2 ;
11+
812function DecreaseVolumeOnSpeak (
913 { pluginUuid : uuid } : DecreaseVolumeOnSpeakProps ,
1014) : React . ReactElement {
1115 BbbPluginSdk . initialize ( uuid ) ;
1216
1317 const pluginApi : PluginApi = BbbPluginSdk . getPluginApi ( uuid ) ;
14- const intervalId = React . useRef < NodeJS . Timeout > ( null ) ;
18+ const [ isDecreasingVolume , setIsDecreasingVolume ] = React . useState ( false ) ;
1519 const volumeSetByUser = React . useRef ( 1 ) ;
16- const volumeSetByMachine = React . useRef ( 1 ) ;
20+ const lastVolumeSetByMachine = React . useRef < number > ( null ) ;
21+ const volumeSetByMachine = React . useRef < number [ ] > ( [ ] ) ;
1722 const externalVideoData = pluginApi . useCustomSubscription < ExternalVideoMeetingSubscription > (
1823 MEETING_SUBSCRIPTION ,
1924 ) ;
25+ const { value : isMuted } = pluginApi . useUiData ( ExternalVideoVolumeUiDataNames . IS_VOLUME_MUTED , {
26+ value : false ,
27+ } ) ;
2028
2129 const setVolume = ( volume : number ) => {
2230 pluginApi . uiCommands . externalVideo . volume . set ( {
2331 volume,
2432 } ) ;
25- volumeSetByMachine . current = volume ;
33+ volumeSetByMachine . current . push ( volume ) ;
2634 } ;
2735
2836 const [ isSomeoneTalking , setIsSomeoneTalking ] = React . useState ( false ) ;
@@ -31,14 +39,18 @@ function DecreaseVolumeOnSpeak(
3139
3240 const talkingIndicatorList = talkingIndicatorResult . data ;
3341
34- pluginApi . useUiEvent (
35- ExternalVideoVolumeEventsNames . VOLUME_VALUE_CHANGED ,
36- ( value ) => {
37- if ( value . detail . value * 100 !== volumeSetByMachine . current * 100 ) {
38- volumeSetByUser . current = value . detail . value ;
39- }
40- } ,
41- ) ;
42+ const volumeFromUiDataHook = pluginApi . useUiData ( ExternalVideoVolumeUiDataNames
43+ . CURRENT_VOLUME_VALUE , { value : 1 } ) ;
44+
45+ useEffect ( ( ) => {
46+ if (
47+ volumeSetByMachine . current . findIndex (
48+ ( vol ) => volumeFromUiDataHook . value * 100 !== vol * 100 ,
49+ ) === - 1
50+ ) {
51+ volumeSetByUser . current = volumeFromUiDataHook . value ;
52+ }
53+ } , [ volumeFromUiDataHook ] ) ;
4254
4355 useEffect ( ( ) => {
4456 if ( talkingIndicatorList ?. some ( ( userVoice ) => userVoice . talking ) !== isSomeoneTalking ) {
@@ -47,27 +59,33 @@ function DecreaseVolumeOnSpeak(
4759 } , [ talkingIndicatorResult ] ) ;
4860
4961 useEffect ( ( ) => {
50- if ( isSomeoneTalking && ! intervalId . current
51- && externalVideoData . data ?. meeting [ 0 ] ?. externalVideo ?. playerPlaying ) {
52- let counter = 1 ;
53- const total = 10 ;
54- const finalVolume = 0.2 ;
55- const partToSubtract = (
56- volumeSetByUser . current - volumeSetByUser . current * finalVolume ) / total ;
57- intervalId . current = setInterval ( ( ) => {
58- const volumeToSet = Math . floor ( ( volumeSetByUser . current - counter * partToSubtract ) * 100 ) ;
59- setVolume ( volumeToSet / 100 ) ;
60- if ( counter === total ) {
61- clearInterval ( intervalId . current ) ;
62- intervalId . current = null ;
63- }
64- counter += 1 ;
65- } , 100 ) ;
66- } else if (
67- ! isSomeoneTalking && ! intervalId . current ) {
68- setVolume ( volumeSetByUser . current ) ;
62+ if ( isSomeoneTalking && ! isDecreasingVolume
63+ && volumeSetByMachine . current . length < totalIterationsToDecrease
64+ && externalVideoData . data ?. meeting [ 0 ] ?. externalVideo ?. playerPlaying
65+ && ! isMuted ) {
66+ setIsDecreasingVolume ( true ) ;
67+ const currentVolumeSetByUser = volumeSetByUser . current ;
68+ const partToSubtract = ( currentVolumeSetByUser * (
69+ 1 - finalVolumeTarget ) ) / totalIterationsToDecrease ;
70+ for ( let i = 0 ; i < totalIterationsToDecrease ; i += 1 ) {
71+ const vol = currentVolumeSetByUser - partToSubtract * i ;
72+ const volumeToSet = Math . floor ( ( vol ) * 100 ) ;
73+ setTimeout ( ( ) => {
74+ setVolume ( volumeToSet / 100 ) ;
75+ if ( i === totalIterationsToDecrease - 1 ) {
76+ lastVolumeSetByMachine . current = volumeToSet / 100 ;
77+ setIsDecreasingVolume ( false ) ;
78+ }
79+ } , intervalBetweenIteration * i ) ;
80+ }
81+ } else if ( ! isDecreasingVolume
82+ && ! isSomeoneTalking && volumeSetByMachine . current . length >= totalIterationsToDecrease ) {
83+ volumeSetByMachine . current = [ ] ;
84+ pluginApi . uiCommands . externalVideo . volume . set ( {
85+ volume : volumeSetByUser . current ,
86+ } ) ;
6987 }
70- } , [ isSomeoneTalking ] ) ;
88+ } , [ isSomeoneTalking , isDecreasingVolume ] ) ;
7189
7290 return null ;
7391}
0 commit comments