You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.3 KiB
86 lines
3.3 KiB
// Author: Gockner, Simon
|
|
// 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<IControllable> Controllables => CreateControllables();
|
|
private List<IControllable> CreateControllables()
|
|
{
|
|
MMDeviceEnumerator deviceEnumerator = new();
|
|
MMDeviceCollection? audioDevices = deviceEnumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active);
|
|
|
|
List<IControllable> controllables = new();
|
|
controllables.AddRange(audioDevices.Select(a => _controllableFactory.Create(a.AudioSessionManager.AudioSessionControl, a.FriendlyName)));
|
|
|
|
Dictionary<string, List<AudioSessionControl>> 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<AudioSessionControl>();
|
|
|
|
sessionsById[searchIdentifier].Add(session);
|
|
}
|
|
}
|
|
|
|
foreach (var id in sessionsById.Keys.ToList())
|
|
{
|
|
List<AudioSessionControl> 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<AudioSessionControl> sessions)
|
|
{
|
|
try
|
|
{
|
|
foreach (var session in sessions)
|
|
return (Process.GetProcessById((int) session.GetProcessID), session);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
}
|
|
|
|
return (null, null);
|
|
}
|
|
}
|
|
} |