如果我转到 Windows 10 (1803) 计算机上的“设置”,我可以访问一个页面(“应用程序音量和设备首选项”),可让我为正在运行的应用程序设置默认输入和输出设备。
如何以编程方式设置这些选项?
相关:
IAudioSessionControl2
及相关系列这里可以枚举所有的播放设备
#include <windows.h>
#include <mmsystem.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "Winmm.lib")
int main()
{
int nSoundCardCount = waveOutGetNumDevs();
for (int i = 0; i < nSoundCardCount; i++)
{
WAVEOUTCAPS woc;
waveOutGetDevCaps(i, &woc, sizeof(woc));
cout << woc.szPname << endl;
}
system("pause");
return 0;
}
这里需要使用PolicyConfig.h和SetDefaultAudioPlaybackDevice添加.h文件和接口。参考这个项目
1.添加头文件PolicyConfig.h
2.添加头文件和接口。
#include "Mmdeviceapi.h"
#include "PolicyConfig.h"
#include "Propidl.h"
#include "Functiondiscoverykeys_devpkey.h"
HRESULT SetDefaultAudioPlaybackDevice( LPCWSTR devID )
{
IPolicyConfigVista *pPolicyConfig;
ERole reserved = eConsole;
HRESULT hr = CoCreateInstance(__uuidof(CPolicyConfigVistaClient),
NULL, CLSCTX_ALL, __uuidof(IPolicyConfigVista), (LPVOID *)&pPolicyConfig);
if (SUCCEEDED(hr))
{
hr = pPolicyConfig->SetDefaultEndpoint(devID, reserved);
pPolicyConfig->Release();
}
return hr;
}
3.使用上面的接口编写一个函数来设置默认输出设备。
这是MFC项目。也许你需要改变。
需要设置哪个输出设备,可以自己修改宏的内容。 我使用
waveOutGetDevCaps()
获取输出设备的名称
//Set the default audio playback device
#define DEF_AUDIO_NAME _T("Speakers (2- Logitech USB Heads") //modify it, my device is Speakers (2- Logitech USB Heads
void InitDefaultAudioDevice()
{
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
IMMDeviceEnumerator *pEnum = NULL;
// Create a multimedia device enumerator.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum);
if (SUCCEEDED(hr))
{
//Determine if it is the default audio device
bool bExit = false;
IMMDevice *pDefDevice = NULL;
hr = pEnum->GetDefaultAudioEndpoint(eRender, eMultimedia,&pDefDevice);
if (SUCCEEDED(hr))
{
IPropertyStore *pStore;
hr = pDefDevice->OpenPropertyStore(STGM_READ, &pStore);
if (SUCCEEDED(hr))
{
PROPVARIANT friendlyName;
PropVariantInit(&friendlyName);
hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
if (SUCCEEDED(hr))
{
CString strTmp = friendlyName.pwszVal;
if (strTmp.Find(DEF_AUDIO_NAME) != -1)
{
bExit = true;
}
PropVariantClear(&friendlyName);
}
pStore->Release();
}
pDefDevice->Release();
}
if (bExit)
{
pEnum->Release();
return;
}
IMMDeviceCollection *pDevices;
// Enumerate the output devices.
hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
if (SUCCEEDED(hr))
{
UINT count;
pDevices->GetCount(&count);
if (SUCCEEDED(hr))
{
for (int i = 0; i < count; i++)
{
bool bFind = false;
IMMDevice *pDevice;
hr = pDevices->Item(i, &pDevice);
if (SUCCEEDED(hr))
{
LPWSTR wstrID = NULL;
hr = pDevice->GetId(&wstrID);
if (SUCCEEDED(hr))
{
IPropertyStore *pStore;
hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
if (SUCCEEDED(hr))
{
PROPVARIANT friendlyName;
PropVariantInit(&friendlyName);
hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
if (SUCCEEDED(hr))
{
// if no options, print the device
// otherwise, find the selected device and set it to be default
CString strTmp = friendlyName.pwszVal;
if (strTmp.Find(DEF_AUDIO_NAME) != -1)
{
SetDefaultAudioPlaybackDevice(wstrID);
bFind = true;
}
PropVariantClear(&friendlyName);
}
pStore->Release();
}
}
pDevice->Release();
}
if (bFind)
{
break;
}
}
}
pDevices->Release();
}
pEnum->Release();
}
}
CoUninitialize();
}
此示例只能更改主音量的输出。不知道能否满足您的要求?如果需要换其他app,还得摸索一段时间。
所以我已经使用 SoundVolumeView 一段时间了,它让我可以通过命令行将麦克风静音和取消静音,而且我最近发现(由于 OBS 和监控音频)它还可以更改应用程序的设备或全局默认设备
并使用 /SetDefault 和 /SetAppDefault,如页面底部的文档示例所示
我已将其放入批处理脚本中并将宏绑定到我的键盘,到目前为止效果很好:)
@slhad 的回答救了我!我对这个主题进行了大量的挖掘,但无法在 C# 或基本的 powershell 中实现它。然而,使用 SoundVolumeView 我能够实现它。
这是我的 Powershell 脚本,您可以使用它来开始。我的用例是在耳机和扬声器之间切换 Spotify。
# paths
$root = "F:\Programs\Sound Volume View"
$soundVolumeViewPath = "$root\SoundVolumeView.exe"
$deviceFilePath = "$root\current_device"
# audio device root paths
$deviceID1 = "Scarlett Solo USB"
$deviceID2 = "2- High Definition Audio Device"
$currentDeviceID = Get-Content $deviceFilePath
if ($currentDeviceID -eq $deviceID1) {
$setDeviceID = $deviceID2
} else {
$setDeviceID = $deviceID1
}
$setDeviceID | Out-File $deviceFilePath
& $soundVolumeViewPath /SetAppDefault "$setDeviceID\Device\Speakers\Render" all "Spotify.exe"
对于我的用例来说,一切都是硬编码的,因此任何未来的漫游者都需要进行一些定制。我的实现从文件中读取,获取“当前”设备,并将 Spotify 的默认音频设备交换到另一个设备。效果很好。
通过使用自动热键我能够将其设置为按键绑定(Win + J):
#Requires AutoHotkey v2.0
#j::Run 'powershell.exe -windowstyle hidden -ExecutionPolicy Bypass -File "F:\Programs\Sound Volume View\spotify.ps1"' ,, "Hide"
我建议将其编译为 exe(这是通过 AHK 完成的),然后将其添加到您的启动目录 (%AppData%\Microsoft\Windows\Start Menu\Programs\Startup) 以便于使用。