在c#中处理已更改的音频设备事件

Ant*_*yev 5 .net c# audio events device

当我将耳机或其他输出设备插入(或提取)到声卡插孔时,我想知道如何处理事件.

在这里和谷歌上搜索给了我关于"naudio"库的信息,但是它的文档很难检查,而且这个项目的协调员之一告诉我他甚至不确定在他们的库中.

我的最终目的是自动控制不同设备的音量,例如当耳机处于活动状态时 - 设置10%音量,当扬声器处于活动状态时 - 设置为100%.

小智 8

您可以使用NAudio的MMDeviceEnumerator和IMMNotificationClient来完成.但是,您将RegisterEndpointNotificationCallbackUnRegisterEndpointNotificationCallback的实现添加到MMDeviceEnumerator类

实现是

 /// <summary>
       /// Registers a call back for Device Events
       /// </summary>
        /// <param name="client">Object implementing IMMNotificationClient type casted as IMMNotificationClient interface</param>
       /// <returns></returns>
        public int RegisterEndpointNotificationCallback([In] [MarshalAs(UnmanagedType.Interface)] IMMNotificationClient client)
        {
            //DeviceEnum declared below
            return deviceEnum.RegisterEndpointNotificationCallback(client);
        }

        /// <summary>
        /// UnRegisters a call back for Device Events
        /// </summary>
        /// <param name="client">Object implementing IMMNotificationClient type casted as IMMNotificationClient interface </param>
        /// <returns></returns>
        public int UnRegisterEndpointNotificationCallback([In] [MarshalAs(UnmanagedType.Interface)] IMMNotificationClient client)
        {
            //DeviceEnum declared below
            return deviceEnum.UnregisterEndpointNotificationCallback(client);
        } 
Run Code Online (Sandbox Code Playgroud)

然后创建一个实现IMMNotificationClient的类

样品:

class NotificationClientImplementation : NAudio.CoreAudioApi.Interfaces.IMMNotificationClient
    {

        public void OnDefaultDeviceChanged(DataFlow dataFlow, Role deviceRole, string defaultDeviceId)
        {
            //Do some Work
            Console.WriteLine("OnDefaultDeviceChanged --> {0}", dataFlow.ToString());
        }

        public void OnDeviceAdded(string deviceId)
        {
             //Do some Work
            Console.WriteLine("OnDeviceAdded -->");
        }

        public void OnDeviceRemoved(string deviceId)
        {

            Console.WriteLine("OnDeviceRemoved -->");
             //Do some Work
        }

        public void OnDeviceStateChanged(string deviceId, DeviceState newState)
        {
            Console.WriteLine("OnDeviceStateChanged\n Device Id -->{0} : Device State {1}", deviceId, newState);
             //Do some Work
        }

        public NotificationClientImplementation()
        {
            //_realEnumerator.RegisterEndpointNotificationCallback();
            if (System.Environment.OSVersion.Version.Major < 6)
            {
                throw new NotSupportedException("This functionality is only supported on Windows Vista or newer.");
            }
        }

        public void OnPropertyValueChanged(string deviceId, PropertyKey propertyKey)
        {
             //Do some Work
             //fmtid & pid are changed to formatId and propertyId in the latest version NAudio
            Console.WriteLine("OnPropertyValueChanged: formatId --> {0}  propertyId --> {1}", propertyKey.formatId.ToString(), propertyKey.propertyId.ToString());
        }

    }
Run Code Online (Sandbox Code Playgroud)

那么你所要做的就是

  1. 声明以下NAudio对象和您的IMMNotificationClient实现

样品:

private NAudio.CoreAudioApi.MMDeviceEnumerator deviceEnum = new NAudio.CoreAudioApi.MMDeviceEnumerator();
private NotificationClientImplementation notificationClient;
private NAudio.CoreAudioApi.Interfaces.IMMNotificationClient notifyClient;
Run Code Online (Sandbox Code Playgroud)
  1. 然后键入cast notificationClient作为IMMNotificationClient并将其作为参数传递给MMDeviceEnumerator

样品:

notificationClient = new NotificationClientImplementation();
notifyClient = (NAudio.CoreAudioApi.Interfaces.IMMNotificationClient)notificationClient;
deviceEnum.RegisterEndpointNotificationCallback(notifyClient);
Run Code Online (Sandbox Code Playgroud)

希望这有助于一些身体.感谢MSDN论坛,特别是Michael Taylor http://msmvps.com/blogs/p3net,帮助我解决这个问题.

谢谢和欢呼.