3 votes

Comment mettre automatiquement en sourdine une application lorsqu'elle n'est pas au point ?

Lorsque je joue à des jeux comme Chivalry Medieval Warfare et que je passe à un autre logiciel comme Firefox ou Desktop, le son du jeu est toujours présent.

Alors, comment puis-je résoudre ce problème ?

5voto

Jacob Vlijm Points 78990

Couper (automatiquement) le son d'une application spécifique si sa fenêtre n'est pas en façade

J'ai testé le script ci-dessous sur Rhythmbox, faisant le travail sans une seule erreur.

L'exécution du script ci-dessous en arrière-plan mettra en pause le processus ciblé si sa fenêtre n'est pas devant (dans la seconde qui suit), en coupant le son s'il accompagne l'application.
Dès que la fenêtre est à nouveau devant, le processus reprend là où il était, et le son fonctionne à nouveau.

Si le processus/application ciblé ne ne fonctionne pas du tout le script passe à une période (mode) plus longue, en vérifiant seulement une fois par cinq secondes si l'application ciblée fonctionne ou non. De cette façon, le script est extrêmement dépourvu de jus s'il n'a pas de tâche à accomplir.

Le 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

Mode d'emploi

  • Le script a besoin de xdotool pour obtenir des informations sur la fenêtre la plus en avant :

    sudo apt-get install xdotool
  • Copiez le script dans un fichier vide, enregistrez-le sous le nom de pause_app.py

  • Dans la section head du script, définissez le nom du processus à mettre en pause (remplacez rhythmbox ).
    En général, il s'agit de la même chose que la (première section de la) WM_CLASS mais dans votre cas, j'ai des doutes sur le fait que cela ne devrait pas être steam ou autre chose. Courir pour s'assurer

    ps -u <yourname>

    pour faire une supposition éclairée, et ensuite

    kill <pid> 
    (the process id)

    pour vérifier.

  • Exécuter le script par la commande :

    python3 /path/to/pause_app.py

    et vérifiez si tout fonctionne comme prévu.

  • Si tout fonctionne bien, ajoutez-les aux applications de démarrage : Dash > Startup Applications > Add. Ajoutez ensuite la commande :

    python3 /path/to/pause_app.py

Note

Le script peut être facilement modifié pour cibler plusieurs applications, mais voyez d'abord si c'est ce dont vous avez besoin.

Ou bien

Si vous préférez couper le son en général une fois que la fenêtre ciblée n'est pas devant, remplacez la commande en mettre l'application en pause par l'ordre de couper (/désactiver) le son . Le script devient alors :

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

L'utilisation est exactement similaire au premier script.

4voto

Sergiy Kolodyazhnyy Points 97292

Le script ci-dessous s'appuie sur tous les outils natifs d'Ubuntu, pactl y qdbus pour déterminer l'application active, mettre en sourdine et rétablir automatiquement la sourdine au fur et à mesure que l'utilisateur se concentre sur l'application.

Le nom de l'application est défini dans APP_ICON_NAME variable. Vous pouvez utiliser pactl list sink-inputs | grep icon_name pour déterminer la valeur que vous souhaitez lui attribuer. Dans mon cas, je l'ai testé avec chromium-browser .

Le script subira des améliorations mineures au niveau du style et peut-être que des fonctionnalités supplémentaires seront ajoutées, mais pour l'instant il est utilisable à 90% et effectue sa tâche correctement. Il sera éventuellement publié sur 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

3voto

E. Timotei Points 181

Si le jeu utilise le système de son normal d'ubuntu, aussi connu sous le nom de pulse audio, alors vous allez dans :

paramètres système -> son -> applications

Vous devriez y voir l'application de lecture de votre chanson, vous pouvez en modifier le volume et même la mettre en sourdine.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X