3

I'm working on a project where I need to get the current system audio output level within Python. Basically, I want to know how loud the current sound coming out of the speakers are using Python on a Linux system. I don't need to know the exact volume level of the speakers, the relative volume is what I'm looking for. I haven't found any good resources online for this.

ndmeiri
  • 4,979
  • 12
  • 37
  • 45
  • The library [pyalsaaudio](https://pypi.python.org/pypi/pyalsaaudio) and these 2 questions may help you: https://stackoverflow.com/questions/11553131/get-system-volume-sound-level-in-linux-using-python and https://askubuntu.com/questions/689521/control-volume-using-python-script. – Taylor D. Edmiston Apr 05 '18 at 01:46
  • 1
    I appreciate the comment Taylor, but both of those answers are about changing the system volume level. I'm trying to tell how loud the system currently is. For example; if nothing is playing, I want a 0 to be returned. If something is playing, I want the current audio level of that stream. Thank you. – Corey Campbell Apr 05 '18 at 01:58
  • I added a more specific answer below (a bit too long to fit in a comment) – Taylor D. Edmiston Apr 05 '18 at 02:05
  • Did you find a solution? – HappyFace Oct 18 '20 at 22:25

2 Answers2

3

tl;dr - An alternative answer for getting the discrete system output volume on macOS.

After seeing your question and learning that I can't build pyalsaaudio on macOS, I wanted to provide an additional answer for how this could be done on macOS specifically since it's not abstracted in a cross-platform way.

(I know this won't be helpful to your immediate use case, but I have a hunch I'm not the only Mac user that will stumble by this question interested in a solution that we can run too.)

On macOS, you can get the output volume by running a little AppleScript:

$ osascript -e 'get volume settings'
output volume:13, input volume:50, alert volume:17, output muted:false

I wrapped that call in a Python function to parse volume + mute state into a simple 0–100 range:

import re
import subprocess


def get_speaker_output_volume():
    """
    Get the current speaker output volume from 0 to 100.

    Note that the speakers can have a non-zero volume but be muted, in which
    case we return 0 for simplicity.

    Note: Only runs on macOS.
    """
    cmd = "osascript -e 'get volume settings'"
    process = subprocess.run(cmd, stdout=subprocess.PIPE, shell=True)
    output = process.stdout.strip().decode('ascii')

    pattern = re.compile(r"output volume:(\d+), input volume:(\d+), "
                         r"alert volume:(\d+), output muted:(true|false)")
    volume, _, _, muted = pattern.match(output).groups()

    volume = int(volume)
    muted = (muted == 'true')

    return 0 if muted else volume

For example, on a MacBook Pro at various volume bar settings:

>>> # 2/16 clicks
>>> vol = get_speaker_output_volume()
>>> print(f'Volume: {vol}%')
Volume: 13%
>>> # 2/16 clicks + muted
>>> get_speaker_output_volume()
0
>>> # 16/16 clicks
>>> get_speaker_output_volume()
100
Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
0

Does this snippet from https://askubuntu.com/a/689523/583376 provide the info you're looking for?

First, pip install pyalsaaudio and then run to get the volume:

>>> import alsaaudio
>>> m = alsaaudio.Mixer()
>>> vol = m.getvolume()
>>> vol
[50L]

Note: This code is copied from the second half of the linked answer. I'm on a Mac, and so can't actually run it as the lib won't build on macOS, but at a glance it looks to provide the current system audio output level on Linux.

Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
  • 1
    Perhaps, current audio level isn't the right choice of words. I'm looking for the output version of example 2 from this page: https://www.programcreek.com/python/example/52624/pyaudio.PyAudio. This program records the volume from a microphone over time, I want the volume from the speakers over time. Thank you for your continued support. – Corey Campbell Apr 05 '18 at 02:40
  • Okay, so are you looking for a continuous signal of the audio output level stream as opposed to a discrete value? – Taylor D. Edmiston Apr 05 '18 at 02:45
  • Yes, I found out that audio intensity is the term I am looking for. – Corey Campbell Apr 05 '18 at 02:53
  • 1
    Okay, so you're seeking the audio intensity of *what is actually playing through the speakers* as opposed to the output volume *the speakers are set to*? – Taylor D. Edmiston Apr 05 '18 at 02:59
  • That would be correct. Again, thank you for your help. – Corey Campbell Apr 05 '18 at 16:50