[英]Output Sound To Audio Device
我正在尝试创建一个脚本,当按下热键时会触发声音效果,这似乎不太困难,但我也希望能够将其输出到特定的音频设备,在我的情况下是虚拟音频电缆.
我在互联网上环顾了一下,看到了许多可能的解决方案,但没有一个对我有用(还没有)。 似乎 AHK 中的正常 SoundPlay 功能无法输出到特定的音频设备,但我也在研究其他选项,例如使用 wmplayer 或其他媒体播放器通过批处理脚本播放声音,但我找不到可以让我将声音输出到特定音频设备的解决方案......
所以我的问题是,向特定的非默认音频设备(虚拟音频电缆)播放声音的最佳方式是什么,可以在命令提示符或自动热键中完成?
你需要的一切都在这里:
Lexikos 的 Vista 音频控制功能
注意:AutoHotkey v1.1.10 及更高版本上的 SoundSet 和 SoundGet 原生支持 Vista 及更高版本。 除非您想使用 SoundSet/SoundGet 不支持的高级功能,否则您不需要 VA.ahk。
https://autohotkey.com/board/topic/21984-vista-audio-control-functions/
要更改默认输出设备,您可以在 cpanel 中编写 Sound 属性的脚本:
Run, mmsys.cpl
WinWait, Sound
ControlSend, SysListView321,{Down num} ' num matches device position
Sleep, 100
ControlClick, &Set Default
Sleep, 100
ControlClick, OK
WinWaitClose, Sound
嗯,
我修改了我找到的一个代码,并上下增加了音量。 您必须使用 device1 和 device2 名称
高飞!
device1:="Speakers / Headphones"
device2:="Communications Headphones"
; http://www.daveamenta.com/2011-05/programmatically-or-command-line-change-the-default-sound-playback-device-in-windows-7/
Devices := {}
IMMDeviceEnumerator := ComObjCreate("{BCDE0395-E52F-467C-8E3D-C4579291692E}", "{A95664D2-9614-4F35-A746-DE8DB63617E6}")
; IMMDeviceEnumerator::EnumAudioEndpoints
; eRender = 0, eCapture, eAll
; 0x1 = DEVICE_STATE_ACTIVE
DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+3*A_PtrSize), "UPtr", IMMDeviceEnumerator, "UInt", 0, "UInt", 0x1, "UPtrP", IMMDeviceCollection, "UInt")
ObjRelease(IMMDeviceEnumerator)
; IMMDeviceCollection::GetCount
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+3*A_PtrSize), "UPtr", IMMDeviceCollection, "UIntP", Count, "UInt")
Loop % (Count)
{
; IMMDeviceCollection::Item
DllCall(NumGet(NumGet(IMMDeviceCollection+0)+4*A_PtrSize), "UPtr", IMMDeviceCollection, "UInt", A_Index-1, "UPtrP", IMMDevice, "UInt")
; IMMDevice::GetId
DllCall(NumGet(NumGet(IMMDevice+0)+5*A_PtrSize), "UPtr", IMMDevice, "UPtrP", pBuffer, "UInt")
DeviceID := StrGet(pBuffer, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "UPtr", pBuffer)
; IMMDevice::OpenPropertyStore
; 0x0 = STGM_READ
DllCall(NumGet(NumGet(IMMDevice+0)+4*A_PtrSize), "UPtr", IMMDevice, "UInt", 0x0, "UPtrP", IPropertyStore, "UInt")
ObjRelease(IMMDevice)
; IPropertyStore::GetValue
VarSetCapacity(PROPVARIANT, A_PtrSize == 4 ? 16 : 24)
VarSetCapacity(PROPERTYKEY, 20)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{A45C254E-DF1C-4EFD-8020-67D146A850E0}", "UPtr", &PROPERTYKEY)
NumPut(14, &PROPERTYKEY + 16, "UInt")
DllCall(NumGet(NumGet(IPropertyStore+0)+5*A_PtrSize), "UPtr", IPropertyStore, "UPtr", &PROPERTYKEY, "UPtr", &PROPVARIANT, "UInt")
DeviceName := StrGet(NumGet(&PROPVARIANT + 8), "UTF-16") ; LPWSTR PROPVARIANT.pwszVal
DllCall("Ole32.dll\CoTaskMemFree", "UPtr", NumGet(&PROPVARIANT + 8)) ; LPWSTR PROPVARIANT.pwszVal
ObjRelease(IPropertyStore)
ObjRawSet(Devices, DeviceName, DeviceID)
}
ObjRelease(IMMDeviceCollection)
Return
$!WheelUp::Send {Volume_Up 5}
$!WheelDown::Send {Volume_Down 5}
currentDevice:=false
^F12::
currentDevice:=!currentDevice
if currentDevice
SetDefaultEndpoint( GetDeviceID(Devices, device1) )
else
SetDefaultEndpoint( GetDeviceID(Devices, device2) )
return
SetDefaultEndpoint(DeviceID)
{
IPolicyConfig := ComObjCreate("{870af99c-171d-4f9e-af0d-e63df40c2bc9}", "{F8679F50-850A-41CF-9C72-430F290290C8}")
DllCall(NumGet(NumGet(IPolicyConfig+0)+13*A_PtrSize), "UPtr", IPolicyConfig, "UPtr", &DeviceID, "UInt", 0, "UInt")
ObjRelease(IPolicyConfig)
}
GetDeviceID(Devices, Name)
{
For DeviceName, DeviceID in Devices
If (InStr(DeviceName, Name))
Return DeviceID
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.