Good time of day! Currently developing something like "smart home" and I need to start different audio streams with different volume level. For example, I want to hear background music with 20% of original volume but in case if someone press door bell then I want to hear that bell ring with 100% volume. For my purposes currently, I'm using mpg123 with Python scripts. Python script with pexpect runs mpg123 with needed settings like

mpg123 -vC <filename>

Current approach sends 's' like pause immediately after the player starts. Then I'm sending needed count of '-' like decrease volume by 2 to the player and resume it. Huh... it works but an implementation is ugly, and there is some gap between the player start and volume decreasing. At least I hear few first "packets" before python script actually pauses player and decrease volume.

Is there any way to reduce the volume by some command? Is there any way to start mpg123 paused? At least to eliminate that gap


  • Pulseaudio or ALSA? Under Pulseaudio, you can control the volume per application, and it remembers the last volume by name of application. Some tools like paplay have options to set application or stream name. With pacmd, and you can script volume changes etc. Under ALSA< it's going to be a lot more difficult.
    – dirkt
    Jul 6, 2017 at 7:20
  • I can use pulse or ALSA but I will be glad to use some higher level tool like player and control volume in it, not in system mixer
    – user922871
    Jul 6, 2017 at 7:37

2 Answers 2


i do the same for bluetooth audio management in smart home and use the following

mpg123 -f -2000 test.mp3

the maximum value of the amplitude is 100% which coressponds to 32768, i use a value of 2000 which is about 6.1 %, for more details see the manual man mpg123

I dont suggest to use pulse, just use alsa internally with mpg123

have fun


Options for Pulseaudio:

1) Stream the output of mpg123 into paplay, for example with something like

mpg123 --stdout ... | paplay --rate=44100 --format=s16le --channels=2 --stream-name=Music --client-name=Musicplayer --volume=65536

You can either set the volume on the commandline as above, or set the volume once in pavucontrol by client-name, and the next time the same application starts it will remember the volume. So if you use different client names, say Musicplayer and Bellringer, you can pre-set the volume once and for all, without having it to change from Python.

2) Use some other program to play MP3 files that uses Pulseaudio and either can set the client name, or has a recognizable client name, or has a option to set the volume. E.g.

mplayer -volume=... ...

Then you have the same options as above.

3) Use pamcd or pactl to set the volume of the stream that's playing, e.g.

pacmd set-sink-input-volume 42 50%

You can use something similar to

pacmd list-sink-inputs | egrep '(index)|(name)'

to find the index numer for a given stream or client name. Or parse the complete output in Python.

4) Use the DBUS interface of Pulseaudio from Python. This will require some programming.

I wouldn't advise to use Python with pexpect to somehow change the volume through the UI, that looks like a horrible kludge, and isn't really "higher level".

  • Thanks a lot! Your answer is really helpful! Do you know any other ways to interact with the player? It will be good for me to softly increase/decrease volume value. Thanks!
    – user922871
    Jul 6, 2017 at 19:00
  • With mpg123? No, I don't know ways to interact with it, and I wouldn't try. You can change the volume smoothly via pacmd or DBus.
    – dirkt
    Jul 6, 2017 at 21:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .