Когда я играю в некоторые игры, такие как рыцарская средневековая война, и переключаюсь на другое программное обеспечение, такое как Firefox или Desktop, звук игры все еще играет.
Итак, как я могу решить эту проблему?
Я протестировал сценарий ниже на Rhythmbox, делая задание без единственной ошибки.
Запущение скрипта ниже в фоновом режиме приостановит целенаправленный процесс, если его окно не будет впереди (в течение одной секунды), отключая звук звука, если это идет с приложением.
Каждый раз, когда окно добирается впереди снова, процесс возобновляется, где это было, и звук работает снова.
Если целенаправленный процесс/приложение не работает вообще, сценарий переключается на более длительный период (режим), проверяя только однажды в пять секунд, если целевое приложение работает или нет. Таким образом, сценарий является чрезвычайно низким на соке, если он не имеет никакого задания для выполнения.
#!/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
Потребности сценария xdotool
получить информацию о frontmost окне:
sudo apt-get install xdotool
pause_app.py
В главном разделе сценария, определенного имя процесса для приостановки (замена rhythmbox
).
Обычно это совпадает с (первый раздел) WM_CLASS
, но в Вашем случае, у меня есть сомнения, если это не должно быть steam
или что-то еще. Выполненный для проверки
ps -u <yourname>
высказывать образованное предположение, и впоследствии
kill <pid>
(the process id)
проверять.
Запустите скрипт командой:
python3 /path/to/pause_app.py
и проверьте если все работы как ожидалось.
Если все хорошо работает, добавьте к Приложениям Запуска: Тире> Приложения Запуска> Добавляет. Затем добавьте команду:
python3 /path/to/pause_app.py
Сценарий может быть легко отредактирован для предназначения для нескольких приложений, но сначала посмотрите, является ли это тем, в чем Вы нуждаетесь.
Если Вы предпочли бы отключать звук звука в целом, после того как целенаправленное окно не впереди, замените команду для приостановки приложения командой для отключения звука (/небесшумный режим) звука. Сценарий затем становится:
#!/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
Использование точно подобно первому сценарию.
Если игра использует нормальную аудиосистему от человечности, иначе импульсное аудио, то Вы входите:
параметры настройки системы-> звук-> приложения
необходимо видеть, что песня играет приложение там, можно изменить объем и даже отключить звук его.
Рев сценария полагается на все собственные инструменты Ubuntu, pactl
и qdbus
для определения активного приложения автоматически отключите звук и не отключите звук, поскольку приложение получает и фокус от пользователя.
Имя приложения определяется в APP_ICON_NAME
переменная. Можно использовать pactl list sink-inputs | grep icon_name
для определения значения, Вам нужен он, чтобы быть установленными. В моем случае я протестировал его с chromium-browser
.
Сценарий подвергнется незначительным улучшениям стиля, и возможно дополнительные опции будут добавлены, но с прямо сейчас это на 90% применимо и работает, это - задача правильно. Это будет в конечном счете отправлено на 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