Reputation: 3587
How do I change it?
I'm looking for something like:
SetMasterVolume(0.5)
SetAppVolume('FooBar',0.5)
I tried using ctypes.windll.winmm, but I can't find much documentation on how to use it.
Thanks in advance.
Upvotes: 20
Views: 63887
Reputation: 2169
If not installed, run: pip install pynput
"""
You must set n to the volume levels your computer has.
x: volume in percent, 0 min, 1 max
"""
def set_volume(x):
n = 100 # volume levels your computer has
keyboard = Controller()
pause = 0.0001
desired_level = int(x*n)
# go to 0 first since we dont know the current volume level
press_count = int(n/2)
for _ in range(press_count):
keyboard.press(Key.media_volume_down)
keyboard.release(Key.media_volume_down)
time.sleep(pause)
press_count = int(desired_level/2)
for _ in range(press_count):
keyboard.press(Key.media_volume_up)
keyboard.release(Key.media_volume_up)
time.sleep(pause)
Example: set_volume(0.5)
Upvotes: 0
Reputation: 11
I figured out a way to set the master volume using numpy, while still using Pycaw.
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import numpy as np
Get the audio output device
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
Set the desired volume in percentage (0 to 100)
desired_vol = 50
Get the volume range (min and max values in dB)
vol_range = volume.GetVolumeRange()
min_vol = vol_range[0]
max_vol = vol_range[1]
Convert the desired volume percentage to volume level in dB
desired_vol_db = np.interp(desired_vol, [0, 100], [min_vol, max_vol])
volume.SetMasterVolumeLevelScalar(desired_vol / 100, None)
Print the current volume percentage
curr_vol = int(volume.GetMasterVolumeLevelScalar() * 100)
print(f'Volume set to: {int(curr_vol)} %')
Upvotes: 0
Reputation: 9
you can set the number of presses in pyautogui and create to an even output
e.g. 43 input = 42 output
imports used:
import pyautogui as p
import math, time
from tkinter import simpledialog
using tkinter askdialog to get an input
volume = simpledialog.askinteger("new volume", "what would you like the volume to be?")
and setting the volume
def set_vol(new_volume):
p.press('volumedown', presses = 50) #sets volume to zero
time.sleep(0.5) #using time.sleep to space the presses
x = math.floor(new_volume / 2) #setting the amount of presses required
p.press('volumeup', presses = x) #setting volume
running the definition
set_vol(volume)
Upvotes: 0
Reputation: 9
import pyautogui
x = 50
a = (x//2)
pyautogui.press('volumeup',a)
#this code will increase computer master volume by even numbers
Upvotes: 0
Reputation: 39
You can use pyautogui
:
import pyautogui
pyautogui.FAILSAFE = False
x = 1
while x < 10:
pyautogui.press('volumedown')
x+=1
Upvotes: 0
Reputation: 155
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# Control volume
#volume.SetMasterVolumeLevel(-0.0, None) #max
#volume.SetMasterVolumeLevel(-5.0, None) #72%
volume.SetMasterVolumeLevel(-10.0, None) #51%
Upvotes: 2
Reputation: 119
this is a very roundabout way to do it but it works.you can simulate the key presses for the computers master volume with pynput. it works but it is quite inacurate.
from pynput.keyboard import Key,Controller
keyboard = Controller()
import time
while True:
for i in range(10):
keyboard.press(Key.media_volume_up)
keyboard.release(Key.media_volume_up)
time.sleep(0.1)
for i in range(10):
keyboard.press(Key.media_volume_down)
keyboard.release(Key.media_volume_down)
time.sleep(0.1)
time.sleep(2)
this is an ok method of doing it. every keypress and release is equal to about 2 volume . hope this is somewhat helpful!
Upvotes: 9
Reputation: 18279
I ripped this from here and modified it to use functions only.
import time
import ctypes
# Import the SendInput object
SendInput = ctypes.windll.user32.SendInput
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBoardInput(ctypes.Structure):
_fields_ = [
("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)
]
class HardwareInput(ctypes.Structure):
_fields_ = [
("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)
]
class MouseInput(ctypes.Structure):
_fields_ = [
("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)
]
class Input_I(ctypes.Union):
_fields_ = [
("ki", KeyBoardInput),
("mi", MouseInput),
("hi", HardwareInput)
]
class Input(ctypes.Structure):
_fields_ = [
("type", ctypes.c_ulong),
("ii", Input_I)
]
VK_VOLUME_MUTE = 0xAD
VK_VOLUME_DOWN = 0xAE
VK_VOLUME_UP = 0xAF
def key_down(keyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBoardInput(keyCode, 0x48, 0, 0, ctypes.pointer(extra))
x = Input( ctypes.c_ulong(1), ii_ )
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def key_up(keyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBoardInput(keyCode, 0x48, 0x0002, 0, ctypes.pointer(extra))
x = Input(ctypes.c_ulong(1), ii_)
SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def key(key_code, length = 0):
key_down(key_code)
time.sleep(length)
key_up(key_code)
def volume_up():
key(VK_VOLUME_UP)
def volume_down():
key(VK_VOLUME_DOWN)
def set_volume(int):
for _ in range(0, 50):
volume_down()
for _ in range(int / 2):
volume_up()
Upvotes: 3
Reputation: 546
I know this is too late but if someone is still looking for a seamless solution
Download this exe application from here
and just call this command using python
./SoundVolumeView.exe /SetVolume "High Definition Audio Device\Device\Speakers" 50
Upvotes: 3
Reputation: 1029
I'd hope after 5 years this is no longer a problem for you, but I've just had to do the same thing. It's possible using the PyCaw library.
Simple proof of concept, based on PyCaw's examples
from __future__ import print_function
from pycaw.pycaw import AudioUtilities, ISimpleAudioVolume
def main():
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
volume = session._ctl.QueryInterface(ISimpleAudioVolume)
if session.Process and session.Process.name() == "vlc.exe":
print("volume.GetMasterVolume(): %s" % volume.GetMasterVolume())
volume.SetMasterVolume(0.6, None)
if __name__ == "__main__":
main()
Upvotes: 46
Reputation: 1108
So instead of editing my old answer I'm adding a new post to allow others who use self to use my old code and anyone who's not, to use my new code.
def get_master_volume():
proc = subprocess.Popen('/usr/bin/amixer sget Master', shell=True, stdout=subprocess.PIPE)
amixer_stdout = proc.communicate()[0].split('\n')[4]
proc.wait()
find_start = amixer_stdout.find('[') + 1
find_end = amixer_stdout.find('%]', find_start)
return float(amixer_stdout[find_start:find_end])
def set_master_volume(volume):
val = float(int(volume))
proc = subprocess.Popen('/usr/bin/amixer sset Master ' + str(val) + '%', shell=True, stdout=subprocess.PIPE)
proc.wait()
Upvotes: 0
Reputation: 1108
First import subprocess
import subprocess
Then to get the master volume
def get_master_volume(self):
proc = subprocess.Popen('/usr/bin/amixer sget Master', shell=True, stdout=subprocess.PIPE)
amixer_stdout = proc.communicate()[0].split('\n')[4]
proc.wait()
find_start = amixer_stdout.find('[') + 1
find_end = amixer_stdout.find('%]', find_start)
return float(amixer_stdout[find_start:find_end])
And to set the Master volume
def set_master_volume(self, widget):
val = self.volume
val = float(int(val))
proc = subprocess.Popen('/usr/bin/amixer sset Master ' + str(val) + '%', shell=True, stdout=subprocess.PIPE)
proc.wait()
Upvotes: -1