windows 平台音频设备处理

windows 平台 mute 所有麦克风或者扬声器

win10测试平台

目前只在win10平台测试过,使用win32 api

#include <initguid.h>
#include <windows.h>
#include <cguid.h>
#include <atlbase.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <stdio.h>
#include <functiondiscoverykeys_devpkey.h>
#include <locale>

#define LOG(format, ...) wprintf(format L"\n", __VA_ARGS__)
struct CoUninitializeOnExit {
    CoUninitializeOnExit() {}

    ~CoUninitializeOnExit() {
        CoUninitialize();
    }
};

struct PropVariantClearOnExit {
    PROPVARIANT* m_p;

    PropVariantClearOnExit(PROPVARIANT* p) : m_p(p) {}

    ~PropVariantClearOnExit() {
        PropVariantClear(m_p);
    }
};

// eRender 所有扬声器设备
// eCapture 所有麦克风设备
// eAll 所有音频设备
int MuteAllDevices(EDataFlow dataFlow = eRender, BOOL muted = TRUE) {
    // local character encoding
    setlocale(LC_CTYPE, "chs");

    HRESULT hr = CoInitialize(nullptr);
    if (FAILED(hr)) {
        LOG(L"CoInitialize failed: hr = 0x%08x", hr);
        return -__LINE__;
    }
    CoUninitializeOnExit cuoe;

    CComPtr<IMMDeviceEnumerator> pMMDeviceEnumerator;
    hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator),
        nullptr,
        CLSCTX_ALL,
        __uuidof(IMMDeviceEnumerator),
        reinterpret_cast<void**>(&pMMDeviceEnumerator)
    );
    if (FAILED(hr)) {
        LOG(L"CoCreateInstance(IMMDeviceEnumerator) failed: hr = 0x%08x", hr);
        return -__LINE__;
    }

    CComPtr<IMMDeviceCollection> pMMDeviceCollection;
    hr = pMMDeviceEnumerator->EnumAudioEndpoints(
        dataFlow,
        DEVICE_STATE_ACTIVE,
        &pMMDeviceCollection
    );
    if (FAILED(hr)) {
        LOG(L"IMMDeviceEnumerator::EnumAudioEndpoints failed: hr = 0x%08x", hr);
        return -__LINE__;
    }

    UINT count;
    hr = pMMDeviceCollection->GetCount(&count);
    if (FAILED(hr)) {
        LOG(L"IMMDeviceCollection::GetCount failed: hr = 0x%08x", hr);
        return -__LINE__;
    }

    for (UINT i = 0; i < count; i++) {
        CComPtr<IMMDevice> pMMDevice;
        hr = pMMDeviceCollection->Item(i, &pMMDevice);
        if (FAILED(hr)) {
            LOG(L"IMMDeviceCollection::Item(%u) failed: hr = 0x%08x", i, hr);
            continue;
        }

        CComPtr<IAudioEndpointVolume> pAudioEndpointVolume;
        hr = pMMDevice->Activate(
            __uuidof(IAudioEndpointVolume),
            CLSCTX_ALL,
            nullptr,
            reinterpret_cast<void**>(&pAudioEndpointVolume)
        );
        if (FAILED(hr)) {
            LOG(L"IMMDevice(%u)::Activate(IAudioEndpointVolume) failed: hr = 0x%08x", i, hr);
            continue;
        }

        BOOL mute;
        hr = pAudioEndpointVolume->GetMute(&mute);
        if (FAILED(hr)) {
            LOG(L"IAudioEndpointVolume(%u)::GetMute failed: hr = 0x%08x", i, hr);
            continue;
        }

        if (muted == mute) {
            // device has the same status
            continue;
        }

        // get the name of the endpoint
        CComPtr<IPropertyStore> pPropertyStore;
        hr = pMMDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
        if (FAILED(hr)) {
            LOG(L"IMMDevice(%u)::OpenPropertyStore failed: hr = 0x%08x", i, hr);
            continue;
        }

        PROPVARIANT v; PropVariantInit(&v);
        PropVariantClearOnExit pvcoe(&v);
        hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &v);
        if (FAILED(hr)) {
            LOG(L"IPropertyStore(%u)::GetValue(PKEY_Device_FriendlyName) failed: hr = 0x%08x", i, hr);
            continue;
        }

        if (VT_LPWSTR != v.vt) {
            LOG(L"Device %u property PKEY_Device_FriendlyName has unexpected vartype %u", i, v.vt);
            continue;
        }

        // mute or unmute it
        hr = pAudioEndpointVolume->SetMute(muted, nullptr);
        if (FAILED(hr)) {
            LOG(L"IAudioEndpointVolume(%u)::SetMute failed: hr = 0x%08x", i, hr);
            continue;
        }

        LOG(muted ? L"Muted %s" : L"unMuted %s", v.pwszVal);
    }

    return 0;
}

int _cdecl wmain() {
    MuteAllDevices(eRender, FALSE);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值