我想知道当我将耳机或其他输出设备插入(或拔出)声卡插孔时如何处理该事件。
在这里和谷歌上搜索为我提供了有关“naudio”库的信息,但它的文档非常差,而且该项目的协调员之一告诉我,他甚至不确定在他们的库中是否有可能。
我的最终目的是自动控制不同设备的音量,例如当耳机处于活动状态时 - 设置 10% 音量,当扬声器处于活动状态时 - 设置 100%。
您可以使用 NAudio 的 MMDeviceEnumerator 和 IMMNotificationClient 来完成此操作。但是,您将 RegisterEndpointNotificationCallback 和 UnRegisterEndpointNotificationCallback 的实现添加到 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);
}
然后创建一个实现 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());
}
}
那么你所要做的就是
样品:
private NAudio.CoreAudioApi.MMDeviceEnumerator deviceEnum = new NAudio.CoreAudioApi.MMDeviceEnumerator();
private NotificationClientImplementation notificationClient;
private NAudio.CoreAudioApi.Interfaces.IMMNotificationClient notifyClient;
样品:
notificationClient = new NotificationClientImplementation();
notifyClient = (NAudio.CoreAudioApi.Interfaces.IMMNotificationClient)notificationClient;
deviceEnum.RegisterEndpointNotificationCallback(notifyClient);
希望这对一些人有帮助。感谢 MSDN 论坛,特别是 Michael Taylor http://msmvps.com/blogs/p3net帮助我解决这个问题。
谢谢与干杯。
您将能够确定设备何时插入系统,您必须通过 COM 互操作来实现
IMMNotificationClient
。基本上,您必须定义以下方法的实现:
请注意,在上述内容中,您最感兴趣的是:
OnDefaultDeviceChanged
OnDeviceAdded
OnDeviceStateChanged
但是,您应该注意底层硬件必须支持此功能,并且此功能仅在 Windows Vista 和 Windows Server 2008 上可用。
我修改了上面的 @randall-deetz 代码以使其自包含,您可以将其放入使用 NAudio 的任何应用程序中。感谢您提供了一个很棒的示例,它对我的项目确实有帮助!
internal class AudioDeviceChangeNotifier : NAudio.CoreAudioApi.Interfaces.IMMNotificationClient, IDisposable
{
private NAudio.CoreAudioApi.MMDeviceEnumerator _deviceEnum = new NAudio.CoreAudioApi.MMDeviceEnumerator();
public AudioDeviceChangeNotifier()
{
if (System.Environment.OSVersion.Version.Major < 6)
throw new NotSupportedException("This functionality is only supported on Windows Vista or newer.");
_deviceEnum.RegisterEndpointNotificationCallback(this);
}
public delegate void DefaultDeviceChangedHandler(DataFlow dataFlow, Role deviceRole, string defaultDeviceId);
/// <summary>
/// Raised when the default audio device is changed.
/// </summary>
public event DefaultDeviceChangedHandler DefaultDeviceChanged;
/// <summary>
/// Triggered by NAudio.CoreAudioApi.MMDeviceEnumerator when the default device changes.
/// </summary>
/// <param name="dataFlow"></param>
/// <param name="deviceRole"></param>
/// <param name="defaultDeviceId"></param>
public void OnDefaultDeviceChanged(DataFlow dataFlow, Role deviceRole, string defaultDeviceId)
{
Debug.WriteLine($"AudioDeviceChangeNotifier::OnDefaultDeviceChanged - dataFlow: {dataFlow}, deviceRole: {deviceRole}, defaultDeviceId: {defaultDeviceId}");
if (DefaultDeviceChanged != null)
DefaultDeviceChanged(dataFlow, deviceRole, defaultDeviceId);
}
public delegate void DeviceAddedHandler(string deviceId);
/// <summary>
/// Raised when a new audio device is added.
/// </summary>
public event DeviceAddedHandler DeviceAdded;
/// <summary>
/// Triggered by NAudio.CoreAudioApi.MMDeviceEnumerator when an audio device is added.
/// </summary>
/// <param name="deviceId"></param>
public void OnDeviceAdded(string deviceId)
{
Debug.WriteLine($"AudioDeviceChangeNotifier::OnDeviceAdded - deviceId: {deviceId}");
if (DeviceAdded != null)
DeviceAdded(deviceId);
}
public delegate void DeviceRemovedHandler(string deviceId);
/// <summary>
/// Raised when an audio device is removed.
/// </summary>
public event DeviceRemovedHandler DeviceRemoved;
/// <summary>
/// Triggered by NAudio.CoreAudioApi.MMDeviceEnumerator when an audio device is removed.
/// </summary>
/// <param name="deviceId"></param>
public void OnDeviceRemoved(string deviceId)
{
Debug.WriteLine($"AudioDeviceChangeNotifier::OnDeviceRemoved - deviceId: {deviceId}");
if (DeviceAdded != null)
DeviceAdded(deviceId);
}
public delegate void DeviceStateChangedHandler(string deviceId, DeviceState newState);
/// <summary>
/// Raised when an audio device's state is changed.
/// </summary>
public event DeviceStateChangedHandler DeviceStateChanged;
/// <summary>
/// Triggered by NAudio.CoreAudioApi.MMDeviceEnumerator when an audio device's state is changed.
/// </summary>
/// <param name="deviceId"></param>
/// <param name="newState"></param>
public void OnDeviceStateChanged(string deviceId, DeviceState newState)
{
Debug.WriteLine($"AudioDeviceChangeNotifier::OnDeviceStateChanged - deviceId: {deviceId}, newState: {newState}");
if (DeviceStateChanged != null)
DeviceStateChanged(deviceId, newState);
}
public delegate void PropertyValueChangedHandler(string deviceId);
/// <summary>
/// Raised when a property value is changed.
/// </summary>
public event PropertyValueChangedHandler PropertyValueChanged;
/// <summary>
/// Triggered by NAudio.CoreAudioApi.MMDeviceEnumerator when an audio device's property is changed.
/// </summary>
/// <param name="deviceId"></param>
/// <param name="propertyKey"></param>
public void OnPropertyValueChanged(string deviceId, PropertyKey propertyKey)
{
Debug.WriteLine($"AudioDeviceChangeNotifier::OnPropertyValueChanged - deviceId: {deviceId}, propertyKey: {propertyKey}");
if (PropertyValueChanged != null)
PropertyValueChanged(deviceId);
}
public void Dispose()
{
_deviceEnum.UnregisterEndpointNotificationCallback(this);
}
}
我非常确定插入/拔出耳机或声卡中的其他任何东西不会生成任何系统事件