Exemplo n.º 1
0
        private static ISimpleAudioVolume GetVolumeObject(int pid)
        {
            // get the speakers (1st render + multimedia) device
            IMmDeviceEnumerator deviceEnumerator = (IMmDeviceEnumerator)(new MMDeviceEnumerator());
            IMmDevice           speakers;

            deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.ERender, ERole.EMultimedia, out speakers);

            string defaultDeviceId;

            speakers.GetId(out defaultDeviceId);

            ISimpleAudioVolume volumeControl = GetVolumeObject(pid, speakers);

            Marshal.ReleaseComObject(speakers);

            if (volumeControl == null)
            {
                // If volumeControl is null, then the process's volume object might be on a different device.
                // This happens if the process doesn't use the default device.
                //
                // As far as Spotify is concerned, if using the "--enable-audio-graph" command line argument,
                // a new option becomes available in the Settings that makes it possible to change the playback device.

                IMmDeviceCollection deviceCollection;
                deviceEnumerator.EnumAudioEndpoints(EDataFlow.ERender, EDeviceState.Active, out deviceCollection);

                int count;
                deviceCollection.GetCount(out count);
                for (int i = 0; i < count; i++)
                {
                    IMmDevice device;
                    deviceCollection.Item(i, out device);

                    string deviceId;
                    device.GetId(out deviceId);

                    try
                    {
                        if (deviceId == defaultDeviceId)
                        {
                            continue;
                        }

                        volumeControl = GetVolumeObject(pid, device);
                        if (volumeControl != null)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(device);
                    }
                }
            }

            Marshal.ReleaseComObject(deviceEnumerator);
            return(volumeControl);
        }
        private static ISimpleAudioVolume GetVolumeObject(int pid)
        {
            // get the speakers (1st render + multimedia) device
            IMmDeviceEnumerator deviceEnumerator = (IMmDeviceEnumerator)(new MMDeviceEnumerator());
            IMmDevice           speakers;

            deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.ERender, ERole.EMultimedia, out speakers);

            // activate the session manager. we need the enumerator
            Guid   iidIAudioSessionManager2 = typeof(IAudioSessionManager2).GUID;
            object o;

            speakers.Activate(ref iidIAudioSessionManager2, 0, IntPtr.Zero, out o);
            IAudioSessionManager2 mgr = (IAudioSessionManager2)o;

            // enumerate sessions for on this device
            IAudioSessionEnumerator sessionEnumerator;

            mgr.GetSessionEnumerator(out sessionEnumerator);
            int count;

            sessionEnumerator.GetCount(out count);

            // search for an audio session with the required name
            // NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2)
            ISimpleAudioVolume volumeControl = null;

            for (int i = 0; i < count; i++)
            {
                IAudioSessionControl2 ctl;
                sessionEnumerator.GetSession(i, out ctl);
                int cpid;
                ctl.GetProcessId(out cpid);

                if (cpid == pid)
                {
                    volumeControl = (ISimpleAudioVolume)ctl;
                    break;
                }
                Marshal.ReleaseComObject(ctl);
            }
            Marshal.ReleaseComObject(sessionEnumerator);
            Marshal.ReleaseComObject(mgr);
            Marshal.ReleaseComObject(speakers);
            Marshal.ReleaseComObject(deviceEnumerator);
            return(volumeControl);
        }