diff --git a/Lib.Audio/Controllable.cs b/Lib.Audio/Controllable.cs index 3426504..c85d598 100644 --- a/Lib.Audio/Controllable.cs +++ b/Lib.Audio/Controllable.cs @@ -10,11 +10,18 @@ namespace Lib.Audio public class Controllable : IControllable { private readonly AudioSessionControl _audioSessionControl; + private readonly string _name; - public Controllable(AudioSessionControl audioSessionControl) => _audioSessionControl = audioSessionControl; + public Controllable(AudioSessionControl audioSessionControl, string name) + { + _audioSessionControl = audioSessionControl; + _name = name; + } public void SetVolume(float volume) => _audioSessionControl.SimpleAudioVolume.Volume = volume; public void Mute() => _audioSessionControl.SimpleAudioVolume.Mute = true; public void UnMute() => _audioSessionControl.SimpleAudioVolume.Mute = false; + + public override string ToString() => _name; } } \ No newline at end of file diff --git a/Lib.Audio/ControllableCollector.cs b/Lib.Audio/ControllableCollector.cs index 95f524c..5c1a955 100644 --- a/Lib.Audio/ControllableCollector.cs +++ b/Lib.Audio/ControllableCollector.cs @@ -2,18 +2,21 @@ // Created: 2021-04-08 // Copyright(c) 2021 SimonG. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using Lib.Audio.Factories; using Lib.Audio.Interfaces; using NAudio.CoreAudioApi; +using NAudio.CoreAudioApi.Interfaces; namespace Lib.Audio { public class ControllableCollector : IControllableCollector { private readonly IControllableFactory _controllableFactory; - + public ControllableCollector(IControllableFactory controllableFactory) => _controllableFactory = controllableFactory; public List Controllables => CreateControllables(); @@ -22,7 +25,62 @@ namespace Lib.Audio MMDeviceEnumerator deviceEnumerator = new(); MMDeviceCollection? audioDevices = deviceEnumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active); - return audioDevices.Select(a => _controllableFactory.Create(a.AudioSessionManager.AudioSessionControl)).ToList(); + List controllables = new(); + controllables.AddRange(audioDevices.Select(a => _controllableFactory.Create(a.AudioSessionManager.AudioSessionControl, a.FriendlyName))); + + Dictionary> sessionsById = new(); + foreach (var audioDevice in audioDevices) + { + SessionCollection sessions = audioDevice.AudioSessionManager.Sessions; + for (int i = 0; i < sessions.Count; i++) + { + AudioSessionControl session = sessions[i]; + if (session.State == AudioSessionState.AudioSessionStateExpired) + continue; + + string searchIdentifier = session.GetSessionIdentifier[(session.GetSessionIdentifier.IndexOf("|", StringComparison.Ordinal) + 1)..]; + + if (!sessionsById.ContainsKey(searchIdentifier)) + sessionsById[searchIdentifier] = new List(); + + sessionsById[searchIdentifier].Add(session); + } + } + + foreach (var id in sessionsById.Keys.ToList()) + { + List idSessions = sessionsById[id]; + + (Process? process, AudioSessionControl? audioSessionControl) = FindProcess(idSessions); + if (audioSessionControl == null || process == default && !idSessions.Any(s => s.IsSystemSoundsSession)) + continue; + + string name; + if (idSessions.Any(s => s.IsSystemSoundsSession)) + name = "System Sounds"; + else if (process != null) + name = process.ProcessName; + else + name = id; + + controllables.Add(_controllableFactory.Create(audioSessionControl, name)); + } + + return controllables; + } + + private (Process? process, AudioSessionControl? session) FindProcess(List sessions) + { + try + { + foreach (var session in sessions) + return (Process.GetProcessById((int) session.GetProcessID), session); + } + catch (ArgumentException) + { + } + + return (null, null); } } } \ No newline at end of file diff --git a/Lib.Audio/Factories/IControllableFactory.cs b/Lib.Audio/Factories/IControllableFactory.cs index 432064e..bc07f70 100644 --- a/Lib.Audio/Factories/IControllableFactory.cs +++ b/Lib.Audio/Factories/IControllableFactory.cs @@ -9,6 +9,6 @@ namespace Lib.Audio.Factories { public interface IControllableFactory { - IControllable Create(AudioSessionControl audioSessionControl); + IControllable Create(AudioSessionControl audioSessionControl, string name); } } \ No newline at end of file