When I'm playing some games like chivalry Medieval Warfare and I switch to another software like Firefox or Desktop the sound of the game still plays.
So, How can I fix this problem ?
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityI tested the script below on Rhythmbox, doing the job without a single error.
Running the script below in the background will pause the targeted process if its window is not in front (within one second), muting sound if it comes with the application.
Whenever the window gets in front again, the process is resumed where it was, and sound works again.
If the targeted process/application does not run at all, the script switches to a longer period (mode), checking only once per five seconds if the targeted application runs or not. This way, the script is extremely low on juice if it has no job to fulfill.
#!/usr/bin/env python3
import subprocess
import time
# ---set the proc to pause when not the active window
wclass = "rhythmbox"
# ---
def get(cmd):
# just a helper function to not repeat verbose subprocess sections
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except subprocess.CalledProcessError:
pass
while True:
# the longer period: application is not running (saving fuel)
time.sleep(5)
front1 = ""
while True:
# if the application runs, switch to a shorter response time
time.sleep(1)
# get the possible pid, get() returns "None" if not running,
# script then switches back to 5 sec check
pid = get(["pgrep", wclass])
if pid:
front2 = wclass in get([
"xprop", "-id", get(["xdotool", "getactivewindow"])
])
# run either kill -stop or kill -cont only if there is
# a change in the situation
if front2 != front1:
if front2 == True:
cm = ["kill", "-cont", pid]
print("run") # just a test indicator, remove afterwards
else:
cm = ["kill", "-stop", pid]
print("stop") # just a test indicator, remove afterwards
subprocess.Popen(cm)
front1 = front2
else:
break
The script needs xdotool
to get information on the frontmost window:
sudo apt-get install xdotool
pause_app.py
In the head section of the script, set the process name to pause (replace rhythmbox
).
Usually this is the same as the (first section of) the WM_CLASS
, but in your case, I am having doubts if this should not be steam
or something else. Run to make sure
ps -u <yourname>
to make an educated guess, and subsequently
kill <pid>
(the process id)
to check.
Run the script by the command:
python3 /path/to/pause_app.py
and check if all works as expected.
If all works fine, add to Startup Applications: Dash > Startup Applications > Add. Then add the command:
python3 /path/to/pause_app.py
The script can be easily edited to target multiple applications, but first please see if this is what you need.
If you'd prefer to mute the sound in general once the targeted window is not in front, replace the command to pause the application by the command to mute (/unmute) sound. The script then becomes:
#!/usr/bin/env python3
import subprocess
import time
# ---set the proc to pause when not the active window
wclass = "rhythmbox"
# ---
def get(cmd):
# just a helper function to not repeat verbose subprocess sections
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except subprocess.CalledProcessError:
pass
while True:
# the longer period: application is not running (saving fuel)
time.sleep(5)
front1 = ""
while True:
# if the application runs, switch to a shorter response time
time.sleep(1)
# get the possible pid, get() returns "None" if not running,
# script then switches back to 5 sec check
pid = get(["pgrep", wclass])
if pid:
front2 = wclass in get([
"xprop", "-id", get(["xdotool", "getactivewindow"])
])
# run either kill -stop or kill -cont only if there is
# a change in the situation
if front2 != front1:
if front2 == True:
cm = ["amixer", "-q", "-D", "pulse", "sset", "Master", "on"]
print("sound") # just a test indicator, remove afterwards
else:
cm = ["amixer", "-q", "-D", "pulse", "sset", "Master", "off"]
print("no sound") # just a test indicator, remove afterwards
subprocess.Popen(cm)
front1 = front2
else:
break
Usage is exactly similar to the first script.
The script bellow relies on all native tools of Ubuntu, pactl
and qdbus
to determine active app, automatically mute and unmute as the app gains and focus from user.
The app name is set in APP_ICON_NAME
variable. You can use pactl list sink-inputs | grep icon_name
to determine the value you need it to be set. In my case, i tested it with chromium-browser
.
The script will undergo minor improvements in style and perhaps additional features will be added , but as of right now it's 90% usable and performs it's task properly. It will eventually be posted to github
#!/bin/bash
list_sinks()
{
pactl list sink-inputs | awk '/Sink Input #/{ sub(/#/," "); printf $3" "} /application.icon_name/{ printf $0"\n" }'
}
get_active_app_icon_name()
{
qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.ActiveApplication \
| xargs -I {} qdbus org.ayatana.bamf {} org.ayatana.bamf.view.Icon
}
get_sinks_for_app()
{
list_sinks | while read line ; do
if grep -q "$APP_ICON_NAME" <<< "$line"
then
awk '{printf $1" "}' <<< "$line"
fi
done
}
mute_sinks()
{
for sink_id in $( get_sinks_for_app ) ; do
pactl set-sink-input-mute "$sink_id" 1
done
}
unmute_sinks()
{
for sink_id in $( get_sinks_for_app ) ; do
pactl set-sink-input-mute "$sink_id" 0
done
}
main()
{
local APP_ICON_NAME="chromium-browser"
while true
do
if [ "$( get_active_app_icon_name )" != "$APP_ICON_NAME" ] ;
then
mute_sinks
else
unmute_sinks
fi
sleep 0.25
done
}
main
If the game is using the normal sound system from ubuntu, a.k.a. pulse audio, then you go into:
system settings -> sound -> applications
You should see your song playing application there, you can change the volume and even mute it.
bftag@KubuntuMSW:~$ xprop WM_CLASS WM_CLASS(STRING) = "UDKGame-Linux", "UDKGame-Linux"