Тема: AHK: Изменение громкости только в Хроме [Решено]
Данный скрипт меняет звук чисто в хроме. Недостаток - нужно указать PID иначе не работает.
Через костыль смог реализовать лишь такой вариант обхода обнаруженных PID хрома (по нажатию F2).
Vol := 20 ; Начальный звук / Меняет обратно на это значение при обходе в поиске 'Chrome_Pid'.
Step := 3 ; Шаг изм. громкости.
Chrome_Pid := 0 ; Pid Audio Service (Shift+Esc в Хроме) - указать вручную / Нажать F2 для помощи в определении.
Wait := 1000 ; Сколько ожидать реакции для записи нового 'Chrome_Pid'.
I_Start := 1 ; С какого индекса начинать медленный обход с изм. звука.
Return
;----------------------------------------------------------------------------------
Up::
Down::
If !(Chrome_Pid){
MsgBox, Вкладка не указана!`nНажмите F2 - для помощи.
Return
}
Vol += (A_ThisHotkey = "Up" ? Step : -Step)
Vol := SetAppVolume(Chrome_Pid, vol)
Tool("Vol: " Vol)
Return
;----------------------------------------------------------------------------------
;Для помощи в указании 'Chrome_Pid': (~16 номер при 17 вкладок)
F2:: ;[euras] 01.06.2021 https://www.autohotkey.com/boards/viewtopic.php?p=402842#p402842
Ex=
SetTimer, GetPID_Gui, -1
Return
GetPID_Gui:
ToolTip, Нажать [Esc] при смене звука,0,0
I := 0
Gui Add, ListView, x2 y0 w100 h900, Номер|PID
For proc in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
{
If (proc.Name = "chrome.exe"){
If (Ex = 1){
Return
}
I++
LV_Add("", "#" (I < 10 ? "0" I : I), proc.ProcessId)
SetAppVolume(proc.ProcessId, 1) ; Меняет звук вкладки на 1% - для того чтобы определить нужный Pid.
Gui Show,, Process List: Chrome.exe
If (I >= I_Start)
Sleep, Wait
SetAppVolume(proc.ProcessId, Vol) ; Меняет звук вкладки. Если нужно будет повторить обход.
}
}
If (I <> 0)
Tool("Список составлен!",10000)
Else
Tool("Хром не найден!",10000)
Return
GuiEscape:
Gui, Destroy
Ex := 1
Chrome_Pid := proc.ProcessId
Return
;----------------------------------------------------------------------------------
;[teadrinker] 21.06.2021 http://forum.script-coding.com/viewtopic.php?pid=148527#p148527
SetAppVolume(PID, Volume){ ; WIN_V+
SetBatchLines -1
static MMDeviceEnumerator := "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
, IID_IMMDeviceEnumerator := "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
, IID_IAudioSessionManager2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"
, IID_IAudioSessionControl2 := "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}"
, IID_ISimpleAudioVolume := "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
, eRender := 0, eMultimedia := 1, CLSCTX_ALL := 0x17
if (Volume + 0 != "")
Volume := Volume > 100 ? 100 : Volume < 0 ? 0 : Volume
IMMDeviceEnumerator := ComObjCreate(MMDeviceEnumerator, IID_IMMDeviceEnumerator)
; IMMDeviceEnumerator::GetDefaultAudioEndpoint
DllCall(NumGet(NumGet(IMMDeviceEnumerator+0)+4*A_PtrSize), "Ptr", IMMDeviceEnumerator, "UInt", eRender, "UInt", eMultimedia, "PtrP", IMMDevice)
ObjRelease(IMMDeviceEnumerator)
VarSetCapacity(GUID, 16)
DllCall("Ole32.dll\CLSIDFromString", "Str", IID_IAudioSessionManager2, "Ptr", &GUID)
; IMMDevice::Activate
DllCall(NumGet(NumGet(IMMDevice+0)+3*A_PtrSize), "Ptr", IMMDevice, "Ptr", &GUID, "UInt", CLSCTX_ALL, "Ptr", 0, "PtrP", IAudioSessionManager2)
ObjRelease(IMMDevice)
; IAudioSessionManager2::GetSessionEnumerator
DllCall(NumGet(NumGet(IAudioSessionManager2+0)+5*A_PtrSize), "Ptr", IAudioSessionManager2, "PtrP", IAudioSessionEnumerator)
ObjRelease(IAudioSessionManager2)
; IAudioSessionEnumerator::GetCount
DllCall(NumGet(NumGet(IAudioSessionEnumerator+0)+3*A_PtrSize), "Ptr", IAudioSessionEnumerator, "UIntP", SessionCount)
Loop % SessionCount
{
; IAudioSessionEnumerator::GetSession
DllCall(NumGet(NumGet(IAudioSessionEnumerator+0)+4*A_PtrSize), "Ptr", IAudioSessionEnumerator, "Int", A_Index-1, "PtrP", IAudioSessionControl)
IAudioSessionControl2 := ComObjQuery(IAudioSessionControl, IID_IAudioSessionControl2)
ObjRelease(IAudioSessionControl)
; IAudioSessionControl2::GetProcessId
DllCall(NumGet(NumGet(IAudioSessionControl2+0)+14*A_PtrSize), "Ptr", IAudioSessionControl2, "UIntP", ProcessId)
If (PID == ProcessId)
{
ISimpleAudioVolume := ComObjQuery(IAudioSessionControl2, IID_ISimpleAudioVolume)
if (Volume + 0 != "")
; ISimpleAudioVolume::SetMasterVolume
DllCall(NumGet(NumGet(ISimpleAudioVolume+0)+3*A_PtrSize), "Ptr", ISimpleAudioVolume, "Float", volume/100.0, "Ptr", 0)
else
; ISimpleAudioVolume::SetMute
DllCall(NumGet(NumGet(ISimpleAudioVolume+0)+5*A_PtrSize), "Ptr", ISimpleAudioVolume, "UInt", Volume = "mute" ? true : false, "Ptr", 0)
ObjRelease(ISimpleAudioVolume)
}
ObjRelease(IAudioSessionControl2)
}
ObjRelease(IAudioSessionEnumerator)
Return Volume
}
Tool(Text, Wait := 1000){
ToolTip, % Text, 0,0
SetTimer, T_Off, -%Wait%
}
T_Off:
ToolTip
Return
Собственно вопрос как выяснить PID в Хроме, что отвечает за звук?
--------------------------
Upd: Рабочий вариант с быстрым обходом PIDs:
SetBatchLines -1
DllCall("LoadLibrary", "str", "Wtsapi32.dll", "ptr")
;---------------------------------------------------
Vol := 0.1 ; Начальный звук (Vol: 1 = 100%).
Step := 0.03 ; Шаг изм. громкости.
Return
;---------------------------------------------------
; Меняет звук в хроме:
Up::
Down::
Vol += (A_ThisHotkey = "Up" ? Step : -Step)
Vol := (Vol > 1 ? 1 : Vol < 0.01 ? 0.01 : Vol)
DllCall("Wtsapi32\WTSEnumerateProcesses", "ptr", 0, "uint", 0, "uint", 1, "ptr*", pProcessInfo, "uint*", count)
addr := pProcessInfo, PIDs := []
Loop % count
{
if (StrGet(NumGet(addr + 8)) = "chrome.exe")
PIDs[NumGet(addr + 4, "uint")] := 1
addr += A_PtrSize = 4 ? 16 : 24
}
DllCall("Wtsapi32\WTSFreeMemory", "ptr", pProcessInfo)
IID_IAudioSessionManager2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"
IID_ISimpleAudioVolume := "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
dev := VA_GetDevice()
if !dev
throw "Can't get device"
if VA_IMMDevice_Activate(dev, IID_IAudioSessionManager2, 7, 0, mgr) != 0
throw "Can't get session manager"
ObjRelease(dev)
if VA_IAudioSessionManager2_GetSessionEnumerator(mgr, enm) != 0
throw "Can't get session enumerator"
ObjRelease(mgr)
VA_IAudioSessionEnumerator_GetCount(enm, count)
Loop % count
{
; IAudioSessionControl *session;
VA_IAudioSessionEnumerator_GetSession(enm, A_Index-1, ssn)
VA_IAudioSessionControl_GetDisplayName(ssn, name)
VA_IAudioSessionControl2_GetProcessId(ssn, pid)
sav := ComObjQuery(ssn, IID_ISimpleAudioVolume)
ObjRelease(ssn)
if !sav ; Unlikely?
throw "Can't get Volume control"
if PIDs[pid]{
VA_ISimpleAudioVolume_SetMasterVolume(sav, Vol)
ObjRelease(sav)
break
}
ObjRelease(sav)
}
ObjRelease(enm)
Tool(Round(Vol*100) "%")
Return
VA_ISimpleAudioVolume_SetMasterVolume(this, Level, EventContext=""){
Return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "uint", this, "float", Level, "uint", VA_GUID(EventContext))
}
Tool(Text, Wait := 1000){
ToolTip, % Text, 0,0
SetTimer, T_Off, -%Wait%
}
T_Off:
ToolTip
Return