#c# #.net #events #audio #device
#c# #.net #Мероприятия #Аудио #устройство
Вопрос:
Мне интересно, как обработать событие, когда я вставляю (или извлекаю) свои наушники или другое устройство вывода в разъем звуковой карты.
Поиск здесь и в Google дает мне информацию о библиотеке «naudio», но у нее очень плохая документация для изучения, а также один из координаторов этого проекта сказал мне, что он не уверен, что это вообще возможно в их библиотеке.
Моя конечная цель — автоматическое регулирование громкости для разных устройств, например, когда наушники активны — установите 10% громкости, а когда динамики активны — установите 100%.
Ответ №1:
Вы можете сделать это с помощью MMDeviceEnumerator от NAudio и 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("OnDeviceStateChangedn 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 amp; 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());
}
}
Затем все, что вам нужно сделать, это
- Объявите следующие объекты NAudio и вашу реализацию IMMNotificationClient
Пример:
private NAudio.CoreAudioApi.MMDeviceEnumerator deviceEnum = new NAudio.CoreAudioApi.MMDeviceEnumerator();
private NotificationClientImplementation notificationClient;
private NAudio.CoreAudioApi.Interfaces.IMMNotificationClient notifyClient;
- Затем введите приведенное значение notificationClient как IMMNotificationClient и передайте его в качестве параметра в MMDeviceEnumerator
Пример:
notificationClient = new NotificationClientImplementation();
notifyClient = (NAudio.CoreAudioApi.Interfaces.IMMNotificationClient)notificationClient;
deviceEnum.RegisterEndpointNotificationCallback(notifyClient);
Надеюсь, это поможет какому-нибудь органу. Спасибо форумам MSDN и, в частности, Майклу Тейлору
http://msmvps.com/blogs/p3net за помощь мне в этом.
Спасибо и приветствия.
Комментарии:
1. Большое вам спасибо за ответ! К сожалению, прошло 3 года с тех пор, как я задавал этот вопрос, и я давно прекратил исследовать эту тему. Но я надеюсь, что это поможет другим решить ту же проблему.
2. @Mohtashim Огромное вам спасибо! Я часами искал пример реализации! Я бы 100 раз поднял этот вопрос за подробный ответ с примерами!!
3. Я использую тот же способ, описанный здесь, я вижу только запуск события onProperyChange, когда я подключаю разъем для наушников, я ничего не вижу, когда я отключаю его, какая-либо причина для этого?
Ответ №2:
Чтобы вы могли определить, когда устройство подключено к системе, вам нужно будет реализовать IMMNotificationClient
взаимодействие через COM. В принципе, вам нужно будет определить реализации следующих методов:
Обратите внимание, что из вышеперечисленных вас больше всего интересуют:
OnDefaultDeviceChanged
OnDeviceAdded
OnDeviceStateChanged
Однако вы должны знать, что базовое оборудование должно поддерживать эту функциональность, и что это доступно только в Windows Vista и Windows Server 2008.
Комментарии:
1. Хорошо, мне будет достаточно получить сообщение о том, что «что-то» подключено или отключено. Как это возможно? Я также попробовал другой способ — выполнить поиск этого события в Windows event Viewer, но у меня ничего не вышло — возможно, я искал не так хорошо, или, возможно, это событие просто не записывается там.
2. @xapon: К сожалению, я сказал, что «в лучшем случае» вы сможете получить эту информацию. Если вы это сделаете, это будет зависеть от звуковой карты или материнской платы (если разъем встроен); Я не уверен, что существует стандартное событие, предоставляемое уровнем аппаратной абстракции, на которое вы можете отреагировать.
3. Я думаю, что это можно решить на низком уровне; например, вот интерфейс Windows для отслеживания звуковых событий msdn.microsoft.com/en-us/library/dd371417 (v =против 85).aspx . Итак, если я углублюсь, я найду способ сделать это. Но я надеялся, что уже существует какая-то абстракция, такая как библиотека или класс, которая могла бы мне помочь. В любом случае спасибо за объяснение.
4. @xapon — Расширил мой ответ, в конечном счете, вы должны использовать COM interop для реализации этого устройства, а затем зарегистрировать свою реализацию.
Ответ №3:
Я был почти уверен, что подключение / отсоединение наушников или чего-либо еще в audiocard не генерирует никакого системного события вообще