Skip to content

Instantly share code, notes, and snippets.

@nerestaren
Created July 13, 2024 18:09
Show Gist options
  • Save nerestaren/ca1c93548983f7796ce05ae32fa65ea5 to your computer and use it in GitHub Desktop.
Save nerestaren/ca1c93548983f7796ce05ae32fa65ea5 to your computer and use it in GitHub Desktop.
Volume control
#Requires AutoHotkey v2.0
#SingleInstance Force
#Include TextRender.ahk
#Include StdOutToVar.ahk
DetectHiddenWindows True
; Changing volume and muting requires https://www.nirsoft.net/utils/sound_volume_command_line.html
; Changing audio device requires https://github.com/frgnca/AudioDeviceCmdlets
; Using TextRender.ahk from https://github.com/iseahound/TextRender
; Using StdOutToVar.ahk from https://www.autohotkey.com/boards/viewtopic.php?t=109148
; INSTALLATION:
; * install required programs
; * download libs and place them and this script anywhere (default dir?)
; * create a new scheduled task, when user logs in, with highest privileges, to run this script
; USAGE:
; * Ctrl + Volume Up/Down: change app volume
; * Ctrl + Volume Mute: mute/unmute app
; * Ctrl + Alt + Volume Up/Down: change audio device
^Volume_Up::change_volume(1)
^Volume_Down::change_volume(-1)
^Volume_Mute::change_volume(0)
^!Volume_Up::change_device(1)
^!Volume_Down::change_device(-1)
tr := TextRender()
LastChange := 0
ProcessName := ""
change_volume(CHANGE) {
global LastChange, ProcessName
LastChange := CHANGE
ProcessName := WinGetProcessName("A")
if (CHANGE = 0) {
; ExitCode := RunWait(Format("*RunAs svcl.exe /Switch {1} /GetMute {1}", ProcessName), , "Hide")
Run(Format("*RunAs svcl.exe /Switch {1}", ProcessName), , "Hide")
;tr.Render(Format("{1}: {2}", ProcessName, ExitCode = 1 ? "Muted" : "Unmuted"), "a: bottom-right x: 99.5vw y: 99.5vh time: 1000")
} else {
; ExitCode := RunWait(Format("*RunAs svcl.exe /ChangeVolume {1} {2} /GetPercent {1}", ProcessName, CHANGE), , "Hide")
Run(Format("*RunAs svcl.exe /ChangeVolume {1} {2}", ProcessName, CHANGE), , "Hide")
;tr.Render(Format("{1}: {2}%", ProcessName, ExitCode / 10), "a: bottom-right x: 99.5vw y: 99.5vh time: 1000")
}
SetTimer(show_message, -30)
}
change_device(DIRECTION) {
text := StdOutToVar("pwsh.exe -command `"Get-AudioDevice -List`"")
output := ""
FoundPos := 0
data := []
DefaultDeviceIndex := 0
while (FoundPos := RegExMatch(text.Output, "Index\s*:\s*.{4}(.+?)\r\n.+?Default\s*:\s*.{4}(.+?)\r\n.+?DefaultCommunication\s*:\s*.{4}(.+?)\r\n.+?Type\s*:\s*.{4}(.+?)\r\n.+?Name\s*:\s*.{4}(.+?)\r\n.+?", &Match, FoundPos != 0 ? FoundPos + StrLen(Match[0]) : 1)) {
if (Match[4] = "Playback") {
data.Push({Index: Match[1], Default: Match[2], DefaultCommunication: Match[3], Type: Match[4], Name: Match[5]})
if (Match[2] = "True") {
DefaultDeviceIndex := data.Length
}
}
}
if (data.Length = 0) {
return
}
if (DefaultDeviceIndex = 0) {
NewDeviceIndex := 1
} else {
NewDeviceIndex := DefaultDeviceIndex + DIRECTION
if (NewDeviceIndex < 1) {
NewDeviceIndex := data.Length
} else if (NewDeviceIndex > data.Length) {
NewDeviceIndex := 1
}
}
Run(Format("pwsh.exe -command `"Set-AudioDevice -Index {1}`"", data[NewDeviceIndex].Index), , "Hide")
tr.Render(data[NewDeviceIndex].Name, "a: bottom-right x: 99.5vw y: 94.5vh time: 1000")
}
show_message() {
global LastChange, ProcessName
if (LastChange = 0) {
ExitCode := RunWait(Format("*RunAs svcl.exe /GetMute {1}", ProcessName), , "Hide")
tr.Render(Format("{1}: {2}", ProcessName, ExitCode = 1 ? "Muted" : "Unmuted"), "a: bottom-right x: 99.5vw y: 94.5vh time: 1000")
} else {
ExitCode := RunWait(Format("*RunAs svcl.exe /GetPercent {1}", ProcessName), , "Hide")
tr.Render(Format("{1}: {2}%", ProcessName, ExitCode / 10), "a: bottom-right x: 99.5vw y: 94.5vh time: 1000")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment