Lautstärkemixer bestimmte Anwendung stumm schalten. Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

songoku
Posts: 73
Joined: 12 Apr 2018, 13:22

Lautstärkemixer bestimmte Anwendung stumm schalten.

08 Oct 2019, 17:26

Guten Abend,
wie kann ich unter Win10, bestimmte Anwendung per Tastenkombination (un)muten?
mit folgende Code funktioniert es bedingt:

Code: Select all

F4::
Run, Sndvol.exe
WinWaitActive, Lautstärkemixer - Lautsprecher
ControlClick , ToolbarWindow322, Lautstärkemixer - Lautsprecher
WinClose, Lautstärkemixer - Lautsprecher 
Das Problem dabei ist, ClassNN ändert sich jedesmal.

Habe mit SendMessage versucht

Code: Select all

 SendMessage, 0x111, 00000131, 00040BE6, Static2, Lautstärkemixer - Lautsprecher 
Da funktioniert es überhaupt nicht.

Also wie kann ich aus Lautstärkemixer z.B Google Chrome eindeutig erkennen und stumm schalten?

Gruß und schönen Dank im Voraus!
gregster
Posts: 9114
Joined: 30 Sep 2013, 06:48

Re: Lautstärkemixer bestimmte Anwendung stumm schalten.  Topic is solved

08 Oct 2019, 23:41

Es geht jedenfalls ohne den Umweg über das Fenster - dazu braucht es allerdings ein bisschen Code, soweit ich weiß :shifty: - unter anderem Lexikos' VA.ahk Bibliothek:
Docs: https://ahkscript.github.io/VistaAudio/
Download v2.3: https://autohotkey.com/board/topic/21984-vista-audio-control-functions/ (Dropbox-Link funktioniert)


Es sei denn, du willst lieber ein externes Tool wie nirCmd verwenden: Das hat den Kommanodozeilenbefehl muteappvolume, der dafür geeignet sein sollte (in Verbindung mit AHK's Run-Befehl), nicht getestet. Aber das ist für uns AutoHotkey-User ja eigentlich nicht angemessen - wenn es sich vermeiden lässt ;)

Vielleicht gibt es auch andere (einfachere ?) Methoden mit AHK (gibt es die nicht immer ?), aber für mich funktioniert dieser Code für Chrome:
(Drücke Leertaste, um Chrome zu (un-)muten)

Code: Select all

#Include VA.ahk	; https://autohotkey.com/board/topic/21984-vista-audio-control-functions/

OnExit, ExitSub
return
 
ExitSub:
ObjRelease(process)
ExitApp
 
Space::
process := ""
for item in ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE name='chrome.exe'")
	if(item.CommandLine ~= "service-sandbox-type=audio")
		process := GetVolumeObject(item.ProcessId)
if process
{	
	VA_ISimpleAudioVolume_GetMute(process, Mute)
	VA_ISimpleAudioVolume_SetMute(process, !Mute)
}
return


GetVolumeObject(Param)
{
    static IID_IASM2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"
    , IID_IASC2 := "{bfb7ff88-7239-4fc9-8fa2-07c950be9c6d}"
    , IID_ISAV := "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
    
    ; Turn empty into integer
    if !Param
        Param := 0
    
    ; Get PID from process name
    if Param is not Integer
    {
        Process, Exist, %Param%
        Param := ErrorLevel
    }
    
    ; GetDefaultAudioEndpoint
    DAE := VA_GetDevice()
    
    ; activate the session manager
    VA_IMMDevice_Activate(DAE, IID_IASM2, 0, 0, IASM2)
    
    ; enumerate sessions for on this device
    VA_IAudioSessionManager2_GetSessionEnumerator(IASM2, IASE)
    VA_IAudioSessionEnumerator_GetCount(IASE, Count)
    
    ; search for an audio session with the required name
    Loop, % Count
    {
        ; Get the IAudioSessionControl object
        VA_IAudioSessionEnumerator_GetSession(IASE, A_Index-1, IASC)
        
        ; Query the IAudioSessionControl for an IAudioSessionControl2 object
        IASC2 := ComObjQuery(IASC, IID_IASC2)
        ObjRelease(IASC)
        
        ; Get the session's process ID
        VA_IAudioSessionControl2_GetProcessID(IASC2, SPID)
        
        ; If the process name is the one we are looking for
        if (SPID == Param)
        {
            ; Query for the ISimpleAudioVolume
            ISAV := ComObjQuery(IASC2, IID_ISAV)
            
            ObjRelease(IASC2)
            break
        }
        ObjRelease(IASC2)
    }
    ObjRelease(IASE)
    ObjRelease(IASM2)
    ObjRelease(DAE)
    return ISAV
}
 
;
; ISimpleAudioVolume : {87CE5498-68D6-44E5-9215-6DA47EF883D8}
;
VA_ISimpleAudioVolume_SetMasterVolume(this, ByRef fLevel, GuidEventContext="") {
    return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "float", fLevel, "ptr", VA_GUID(GuidEventContext))
}
VA_ISimpleAudioVolume_GetMasterVolume(this, ByRef fLevel) {
    return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "float*", fLevel)
}
VA_ISimpleAudioVolume_SetMute(this, ByRef Muted, GuidEventContext="") {
    return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "int", Muted, "ptr", VA_GUID(GuidEventContext))
}
VA_ISimpleAudioVolume_GetMute(this, ByRef Muted) {
    return DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "int*", Muted)
}
(Code ist im Original von GeekDude, glaub ich: https://autohotkey.com/board/topic/21984-vista-audio-control-functions/page-12#entry608538 (siehe im Spoiler) und VA.ahk, wie gesagt von Lexikos)

Chrome scheint etwas tricky zu sein (im Vergleich zu Programmen mit nur einem Prozess), da derjenige Chrome-Prozess, der für Audio zuständig ist, nicht der Hauptprozess ist.

Daher meine Suche nach einem bestimmten String in den Befehlszeilen der verschiedenen Chrome-(Teil-)Prozesse, der diesen zu identifizieren scheint (nur kurz getetest auf Win10, AHK und Chrome - jeweils letzte Version, 64 bit). Der entsprechende Prozess scheint erst dann gestartet zu werden, wenn Chrome das erste Mal Sound abspielen will (auch erst dann erscheint 'Google Chrome' in Windows' Lautstärkemixer). Der Lautstärkemixer merkt sich jedoch, wenn Chrome gemutet geschlossen wurde.

Nur zur Klarstellung: dieser Code schaltet Chrome lautstärkemäßig komplett ab. Individuell stumm geschaltete Tabs oder Player sind vom anschalten jedoch nicht betroffen, die bleiben stumm. Also der gleiche Effekt, den man per Hand im 'Lautstärkemixer' erzielt, afaik. Da wird die Stummschaltung dann auch angezeigt.

Wenn ein Programm nur einen Prozess hat, dann sollte es reichen, den Prozessnamen direkt an GetVolumeObject() zu übergeben:

Code: Select all

Space::
process := ""
process := GetVolumeObject("irgendwas.exe")
if process
{	
	VA_ISimpleAudioVolume_GetMute(process, Mute)
	VA_ISimpleAudioVolume_SetMute(process, !Mute)
}
return
(Rest des Codes unverändert)

Bei Firefox, das mehrere Prozesse hat, führt dies zwar offenbar dazu (zumnidest, wenn man den Hauptprozess erwischt), dass im Mixer die Lautstärke gemutet angezeigt wird. Aber Firefox wird dann gar nicht wirklich stummgeschaltet. Man müsste also auch hier sehen, welcher Prozess für den Sound tatsächlich verantwortlich ist - oder vielleicht versuchen, mit einer Schleife alle Firefox-Prozesse zu muten. Müsste man mal ausprobieren, ob das gut funktioniert... :think:
gregster
Posts: 9114
Joined: 30 Sep 2013, 06:48

Re: Lautstärkemixer bestimmte Anwendung stumm schalten.

09 Oct 2019, 00:00

Um auf deinen Ursprungscode zurüclzukommen... ControlClick nimmt als ersten Parameter ja auch alternativ den Text des zu klickenden Kontrollelements.

Der sollte sich für ein Programm im Mixer hoffentlich nur selten ändern (oder mehrfach vorkommen). Per Window Spy sehe ich dort z. B. Stumm für Google Chrome als Text für das Kontrollelement, das Chrome stumm schalten kann. Das funktioniert dann für mich:

Code: Select all

F4::
Run, Sndvol.exe
WinWaitActive, Lautstärkemixer - Lautsprecher
ControlClick , Stumm für Google Chrome, Lautstärkemixer - Lautsprecher
WinClose, Lautstärkemixer - Lautsprecher 
Return
Edit: Das scheint auch zu funktionieren:

Code: Select all

F4::
Run, Sndvol.exe, , min
Winwait, Lautstärkemixer - Lautsprecher 
SendMessage, 0x201, 0 ,0 , Stumm für Google Chrome, Lautstärkemixer - Lautsprecher 	; LButton down
SendMessage, 0x202, 0 ,0 , Stumm für Google Chrome, Lautstärkemixer - Lautsprecher 	; LButton up
WinClose, Lautstärkemixer - Lautsprecher 
Return
songoku
Posts: 73
Joined: 12 Apr 2018, 13:22

Re: Lautstärkemixer bestimmte Anwendung stumm schalten.

09 Oct 2019, 17:17

vielen lieben Dank, alle Methoden funktionieren.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 53 guests