示例#1
0
        /// <summary>
        /// Fetch the spotify audio session.
        /// </summary>
        protected AudioSession? FetchAudioSession() {
            // Fetch sessions
            using var device = AudioDevice.GetDefaultAudioDevice(EDataFlow.eRender, ERole.eMultimedia);
            using var sessionManager = device.GetSessionManager();
            using var sessions = sessionManager.GetSessionCollection();

            // Check main process
            var sessionCount = sessions.Count;
            using var sessionCache = new DisposableList<AudioSession>(sessionCount);
            for (var i = 0; i < sessions.Count; i++) {
                var session = sessions[i];
                if (session.ProcessID == MainWindowProcess?.Id) {
                    Logger.LogInfo("SpotifyHook: Successfully fetched audio session using main window process.");
                    _audioSession = session;
                    return _audioSession;
                } else {
                    // Store non-spotify sessions in disposable list to make sure that they the underlying COM objects are disposed.
                    sessionCache.Add(session);
                }
            }

            Logger.LogWarning("SpotifyHook: Failed to fetch audio session using main window process.");

            // Try fetch through other "spotify" processes.
            var processes = FetchSpotifyProcesses();

            // Transfer the found sessions into a dictionary to speed up the search by process id.
            // (we do this here to avoid the overhead as most of the time we will find the session in the code above.)
            using var sessionMap = new ValueDisposableDictionary<uint, AudioSession>();
            foreach (var session in sessionCache)
                sessionMap.Add(session.ProcessID, session);
            sessionCache.Clear();

            foreach (var process in processes) {
                var processId = (uint)process.Id;

                // skip main process as we already checked it
                if (MainWindowProcess?.Id == processId)
                    continue;

                if (sessionMap.TryGetValue(processId, out AudioSession session)) {
                    _audioSession = session;
                    Logger.LogInfo("SpotifyHook: Successfully fetched audio session using secondary spotify processes.");

                    // remove from map to avoid disposal
                    sessionMap.Remove(processId);
                    return _audioSession;
                }
            }

            Logger.LogError("SpotifyHook: Failed to fetch audio session.");

            return null;
        }