Como posso silenciar automaticamente uma aplicação quando não estiver em foco?

3

Quando estou jogando alguns jogos como o Medieval Warfare de cavalaria e mudo para outro software como o Firefox ou o Desktop, o som do jogo ainda é reproduzido.

Então, como posso corrigir esse problema?

    
por Battlefield TAG 12.06.2016 / 13:48

3 respostas

5

(Automaticamente) silencia o som de um aplicativo específico se sua janela não estiver na frente

Eu testei o script abaixo no Rhythmbox, fazendo o trabalho sem um único erro.

A execução do script abaixo em segundo plano pausará o processo de segmentação se a janela não estiver na frente (dentro de um segundo), silenciando o som se ele for fornecido com o aplicativo.
Sempre que a janela fica na frente novamente, o processo é retomado onde estava e o som funciona novamente.

Se o processo / aplicativo alvo não for executado , o script mudará para um período mais longo (modo), verificando apenas uma vez a cada cinco segundos se o aplicativo alvo corre ou não. Desta forma, o script é extremamente baixo em suco se não tiver trabalho a cumprir.

O script

#!/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

Como usar

  • O script precisa de xdotool para obter informações na primeira janela:

    sudo apt-get install xdotool
    
  • Copie o script em um arquivo vazio, salve-o como pause_app.py
  • Na seção head do script, defina o nome do processo para pausar (substitua rhythmbox ).
    Normalmente, isso é o mesmo que a (primeira seção) do WM_CLASS , mas no seu caso, estou tendo dúvidas se isso não deve ser steam ou qualquer outra coisa. Corra para se certificar de que

    ps -u <yourname>
    

    para fazer um palpite, e subsequentemente

    kill <pid> 
    (the process id)
    

    para verificar.

  • Execute o script pelo comando:

    python3 /path/to/pause_app.py
    

    e verifique se tudo funciona conforme esperado.

  • Se tudo funcionar bem, adicione a Startup Applications: Dash > Aplicativos de inicialização > Adicionar. Em seguida, adicione o comando:

    python3 /path/to/pause_app.py
    

Nota

O script pode ser facilmente editado para segmentar vários aplicativos, mas primeiro veja se é isso que você precisa.

Alternativamente

Se você preferir ignorar o som em geral quando a janela de destino não estiver na frente, substitua o comando pause o aplicativo pelo comando > mudo (/ ativar) som . O script então se torna:

#!/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

O uso é exatamente semelhante ao primeiro script.

    
por Jacob Vlijm 12.06.2016 / 18:43
4

O script abaixo se baseia em todas as ferramentas nativas do Ubuntu, pactl e qdbus para determinar o aplicativo ativo, automaticamente silenciar e ativar o som conforme o aplicativo ganha e se concentra do usuário.

O nome do aplicativo é definido na variável APP_ICON_NAME . Você pode usar pactl list sink-inputs | grep icon_name para determinar o valor que você precisa que seja definido. No meu caso, eu testei com chromium-browser .

O script sofrerá pequenas melhorias no estilo e, talvez, recursos adicionais serão adicionados, mas a partir de agora ele é 90% utilizável e executa sua tarefa corretamente. Ele eventualmente será postado no 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
    
por Sergiy Kolodyazhnyy 12.06.2016 / 21:16
3

Se o jogo estiver usando o sistema de som normal do ubuntu, ou seja, áudio de pulso, então você entra em:

configurações do sistema - > som - > aplicações

Você deve ver sua música reproduzindo o aplicativo lá, você pode alterar o volume e até mesmo ignorá-lo.

    
por E. Timotei 12.06.2016 / 14:50