发布 | 音频设备监听器

2020-03-19 18:07:58 浏览数 (2)

❝可监听音量变化和设备插拔状态变化。❞

对外接口

  • 简化代码:
代码语言:javascript复制
class AudioDeviceMonitor : public QObject
{
    Q_OBJECT
public:
    AudioDeviceMonitor();
    virtual ~AudioDeviceMonitor();

    static AudioDeviceMonitor *createAudioDeviceMonitor();

signals:
    void deviceStateChanged();
    void volumeStateChanged();

    ...
};
  • 创建监听器(AudioDeviceMonitor)有两种方式方式:
  1. 直接构造创建如:AudioDeviceMonitor monitor;
  2. 通过静态方法createAudioDeviceMonitor()创建,它会在独立的线程中创建资源,不会影响(冲突)主线程的COM资源创建。
  • deviceStateChanged为设备状态变更信号。
  • volumeStateChanged为音量状态变更信号。

音量监听实现

  • 通过实现IAudioEndpointVolumeCallback类并使用IAudioEndpointVolume的RegisterControlChangeNotify注册音量事件监听。
代码语言:javascript复制
class AudioEndpointVolumeCallback : public IAudioEndpointVolumeCallback
{
    ...
}

m_audioEndpointVolumeCallback = new AudioEndpointVolumeCallback();
m_audioEndpointVolumeCallback->setListener(this); /* 注册事件回调,用于Qt处理 */
m_endpoint->RegisterControlChangeNotify(m_audioEndpointVolumeCallback);
  • 当有音量变化时会触发OnNotify函数,并通过m_listener转发volumeStateChanged信号。
代码语言:javascript复制
HRESULT STDMETHODCALLTYPE AudioEndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
{
    Q_UNUSED(pNotify)
    if (m_listener) {
        m_listener->volumeStateChanged();
    }

    return S_OK;
}

设备监听实现

  • 通过实现IMMNotificationClient类并使用IAudioEndpointVolume的RegisterEndpointNotificationCallback注册设备状态变更事件。
代码语言:javascript复制
class DeviceNotificationClient : public IMMNotificationClient
{
    ...
}

m_deviceNotificationClient = new DeviceNotificationClient();
m_deviceNotificationClient->setListener(this);
m_enumerator->RegisterEndpointNotificationCallback(m_deviceNotificationClient);
  • 当设备变更时自动调用OnDeviceStateChanged函数,并通过m_listener转发volumeStateChanged信号。
代码语言:javascript复制
HRESULT DeviceNotificationClient::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
{
    Q_UNUSED(pwstrDeviceId)
    Q_UNUSED(dwNewState)

    if (m_listener) {
        m_listener->deviceStateChanged();
    }

    return S_OK;
}

使用

  使用Qt5风格的信号槽监听。

代码语言:javascript复制
AudioDeviceMonitor monitor;
QObject::connect(&monitor,
                 &AudioDeviceMonitor::volumeStateChanged,
                 [](){ qDebug() << "Volume changed!"; });

QObject::connect(&monitor,
                 &AudioDeviceMonitor::deviceStateChanged,
                 [](){ qDebug() << "Device status changed!"; });

0 人点赞