diff --git a/app/components-react/editor/elements/Mixer.tsx b/app/components-react/editor/elements/Mixer.tsx index 1aece143acc4..a3df93ffad50 100644 --- a/app/components-react/editor/elements/Mixer.tsx +++ b/app/components-react/editor/elements/Mixer.tsx @@ -9,9 +9,31 @@ import { Services } from 'components-react/service-provider'; import { Menu } from 'util/menus/Menu'; import { $t } from 'services/i18n'; import { useRealmObject } from 'components-react/hooks/realm'; +import { getDefined } from 'util/properties-type-guards'; const mins = { x: 150, y: 120 }; +export function getVisibleAudioSourcesIds() { + const { ScenesService, AudioService } = Services; + const activeScene = getDefined(ScenesService.views.activeScene); + + // Get sources ids for visible scene items + // using the Set to avoid duplicates and improve performance + const visibleSourcesIds = new Set( + activeScene.items.filter(item => item.visible).map(item => item.sourceId), + ); + + return AudioService.views.sourcesForCurrentScene + .filter(source => { + return ( + !source.mixerHidden && + source.isControlledViaObs && + (visibleSourcesIds.has(source.sourceId) || source.isGlobal()) + ); + }) + .map(source => source.sourceId); +} + export function Mixer() { const { EditorCommandsService, AudioService, CustomizationService } = Services; @@ -26,11 +48,7 @@ export function Mixer() { }, []); const performanceMode = useRealmObject(CustomizationService.state).performanceMode; - const { audioSourceIds } = useVuex(() => ({ - audioSourceIds: AudioService.views.sourcesForCurrentScene - .filter(source => !source.mixerHidden && source.isControlledViaObs) - .map(source => source.sourceId), - })); + const audioSourceIds = useVuex(getVisibleAudioSourcesIds); function showAdvancedSettings() { AudioService.actions.showAdvancedSettings(); diff --git a/app/components-react/editor/elements/mixer/GLVolmeters.tsx b/app/components-react/editor/elements/mixer/GLVolmeters.tsx index 9d95c7ab7ff5..38a92fc8effa 100644 --- a/app/components-react/editor/elements/mixer/GLVolmeters.tsx +++ b/app/components-react/editor/elements/mixer/GLVolmeters.tsx @@ -7,6 +7,7 @@ import vShaderSrc from 'util/webgl/shaders/volmeter.vert'; import fShaderSrc from 'util/webgl/shaders/volmeter.frag'; import { Services } from 'components-react/service-provider'; import { assertIsDefined, getDefined } from 'util/properties-type-guards'; +import { getVisibleAudioSourcesIds } from '../Mixer'; // Configuration const CHANNEL_HEIGHT = 3; @@ -133,9 +134,10 @@ class GLVolmetersController { // TODO: refactor into a single source of truth between Mixer and Volmeters get audioSources() { - return this.audioService.views.sourcesForCurrentScene.filter(source => { - return !source.mixerHidden && source.isControlledViaObs; - }); + const vidibleSourceIds = getVisibleAudioSourcesIds(); + return this.audioService.views.sourcesForCurrentScene.filter(source => + vidibleSourceIds.includes(source.sourceId), + ); } /** diff --git a/app/services/audio/audio.ts b/app/services/audio/audio.ts index b35425771499..7c9523c1aa1f 100644 --- a/app/services/audio/audio.ts +++ b/app/services/audio/audio.ts @@ -388,6 +388,10 @@ export class AudioSource implements IAudioSourceApi { return { ...this.source.state, ...this.audioSourceState }; } + isGlobal() { + return this.source.channel !== void 0; + } + get monitoringOptions() { return [ { value: obs.EMonitoringType.None, label: $t('Monitor Off') },