Как я могу автоматически отключить приложение, когда оно не в фокусе?

Когда я играю в некоторые игры, такие как рыцарская средневековая война, и переключаюсь на другое программное обеспечение, такое как Firefox или Desktop, звук игры все еще играет.

Итак, как я могу решить эту проблему?

3
задан 13 June 2016 в 08:37

3 ответа

(Автоматически) отключите звук звука определенного приложения, если его окно не впереди

Я протестировал сценарий ниже на 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

Использование точно подобно первому сценарию.

5
ответ дан 13 June 2016 в 08:37

Если игра использует нормальную аудиосистему от человечности, иначе импульсное аудио, то Вы входите:

параметры настройки системы-> звук-> приложения

необходимо видеть, что песня играет приложение там, можно изменить объем и даже отключить звук его.

3
ответ дан 13 June 2016 в 08:37

Рев сценария полагается на все собственные инструменты 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
4
ответ дан 13 June 2016 в 08:37

Другие вопросы по тегам:

Похожие вопросы: