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.
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() if session.Process and ... to if session.Process is not None and ...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!
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 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() 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% 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() /usr is only on unix-based systemsYou can use pyautogui:
import pyautogui pyautogui.FAILSAFE = False x = 1 while x < 10: pyautogui.press('volumedown') x+=1 import pyautogui x = 50 a = (x//2) pyautogui.press('volumeup',a) #this code will increase computer master volume by even numbers 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) 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)} %') 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)
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() self.volume needs to equal 50.0 so just by calling val = float(int(val)) It will set 50 to an integer if its something like 50.1 and then changes it to a float of 50.0
pygame.mixer.music.set_volume(value)