Réglez automatiquement la sortie audio HDMI lors de la connexion / déconnexion

20

J'ai une configuration à double écran sur mon ordinateur portable (en utilisant 12.04 LTS) en utilisant un écran connecté HDMI. Tout fonctionne bien, mais chaque fois que je connecte / déconnecte le câble, je dois aller dans les préférences audio et changer manuellement le périphérique de sortie audio.

Existe-t-il un moyen de changer le périphérique de sortie audio lors de la connexion / déconnexion du câble, donc lorsque je connecte mon écran, la sortie audio est réglée sur HDMI et lorsque je le déconnecte, le son revient aux haut-parleurs d'un ordinateur portable?

Salem
la source
Même problème ici.
ThiagoPonte
C'est la première fois que je viens ici pour toute aide à ce sujet ... Je suis dans le même bateau le 12.10. C'est ennuyant. C'est ainsi depuis 10h10 dans mon expérience. Il doit y avoir une configuration quelque part qui peut gérer cela. EDIT: voices.canonical.com/david.henningsson/2012/04/14/… C'est défini de cette façon exprès. C'est horrible.
user138216
Vérifiez si ma réponse fonctionne avec vous.
Salem

Réponses:

11

Pour le bénéfice des personnes qui tombent sur cette question - la solution de Salem a presque fonctionné pour moi en 13.04, j'ai fini par rassembler des morceaux de partout sur le web, je pense que le facteur décisif pour moi était le manque de la variable d'environnement PULSE_SERVER

Voici ma solution complète, qui est essentiellement la répétition de la solution de Salem avec les quelques pièces manquantes. Je l'ai également refait en tant que script shell (malgré mon amour pour Python) car j'avais d'abord peur que mon script Python rencontre des problèmes de chemin d'importation:


(identique à la réponse de Salem) Créez un fichier en /etc/udev/rules.d/hdmi_sound.rulestant que root avec le contenu:

SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"

Créez un fichier en /usr/local/bin/hdmi_sound_toggletant que root avec le contenu:

#!/bin/sh
USER_NAME=`who | grep "(:0)" | cut -f 1 -d ' '`
USER_ID=`id -u $USER_NAME`
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`

export PULSE_SERVER="unix:/run/user/"$USER_ID"/pulse/native"

if [ $HDMI_STATUS = "connected" ]
then
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:hdmi-stereo+input:analog-stereo
else
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

Rendez-le ensuite exécutable avec chmod 0755 /usr/local/bin/hdmi_sound_toggle

J'ai essayé de rendre ce script aussi générique que possible, mais vous devrez peut-être encore modifier certaines lignes, telles que le chemin du fichier HDMI_STATUS ou les profils utilisés. Vous pouvez voir une liste de profils en exécutant pactl list cardset en regardant sous Profils.

Notez que le script a échoué pour moi lorsque j'ai supprimé le mot clé "export" lors de la définition de PULSE_SERVER, je pense que pactl recherche la variable env

N'oubliez pas de recharger vos règles udev: sudo udevadm control --reload-rules

Mettre à jour ce script est mis à jour pour 14.04. Avant cela, vous utiliseriez USER_NAME au lieu de USER_ID partout

Daniel
la source
1
Notez que je devais ajouter | uniqà la commande USER_NAME. Notez également que les paramètres des sons dans Ubuntu peuvent être trompeurs. Je ne voyais pas les changements dans le panneau des paramètres sonores, mais une fois que je jouais quelque chose, le son allait et venait sans à-coup, j'ai également remarqué qu'après quelques fois de branchement et de débranchement du HDMI, le script a cessé de s'exécuter (peut-être certains sorte de bug dans udev).
FuegoFro
1
J'ai ajouté | sort -uau nom d'utilisateur parce qu'il disait l'option supplémentaire elemer elemer --- Mon nom d'utilisateur. Identique à la solution de FuegoFro en fin de journée.
elemer82
J'ai utilisé | grep -v pts, car en fait, j'ai également eu un utilisateur "root" - du fait que je modifiais le script via kate, qui avait un terminal root ouvert.
Auspex
Continuez à obtenir "Échec de la connexion: connexion refusée pa_context_connect () a échoué: connexion refusée" lors de l'exécution de pactl. : \
Tomislav Nakic-Alfirevic
7

J'ai finalement réussi à faire ce travail en utilisant udev. Donc, si quelqu'un veut le même comportement, voici les étapes:

Nous devons d'abord créer un fichier /etc/udev/rules.d/hdmi_sound.rulesavec le contenu suivant:

    SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"

cela fera udevexécuter le script à hdmi_sound_togglechaque changement de connexion HDMI. Ce script doit avoir l'autorisation d'exécution et le contenu est le suivant:

#!/usr/bin/env python

import subprocess
from syslog import syslog

def output(cmd):
    return subprocess.check_output(cmd, shell=True)

# the following variables may need some modification.
user = "my_username"
card = "/sys/class/drm/card0"
dev_speaker = "output:analog-stereo+input:analog-stereo"
dev_hdmi = "output:hdmi-stereo+input:analog-stereo"
#

interfaces = output("ls {0}".format(card), ).split("\n")

vga = filter(lambda x: "VGA" in x, interfaces)[0]
hdmi = filter(lambda x: "HDMI" in x, interfaces)[0]

syslog("HDMI connection was changed!")

hdmi_connected = output("cat {0}/{1}/status".format(card,hdmi)).startswith("connected")
title = "HDMI was {0}".format("connected" if hdmi_connected else "disconnected")
message = "Audio output has changed to {opt}.".format(opt = "HDMI" if hdmi_connected else "built-in speakers")

cmd = "sudo -u " + user + " /usr/bin/pactl set-card-profile 0 " + (dev_hdmi if hdmi_connected else dev_speaker)

syslog("HDMI was connected." if hdmi_connected else "HDMI was disconnected.")
try:
    a = output(cmd)
    output("sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))
    syslog("Audio output changed.")
except Exception as ex:
    syslog("Error changing output device: " + str(ex))

Cela peut probablement être fait facilement en bash, mais comme mon langage principal est le python, je l'ai utilisé. Tout fonctionne sauf la notification: elle n'apparaît pas, je ne sais vraiment pas pourquoi. Si quelqu'un sait comment le réparer, dites quelque chose.

Remarque: les noms de script / règle udev peuvent être modifiés, mais vous devez utiliser le chemin complet.

Salem
la source
3

Sur la base de Salem « s réponse et daniel réponse de l »

J'ai pris la réponse de Salem et celle de Daniel et j'ai fait les changements nécessaires, leur solution n'a pas fonctionné pour moi hors de la boîte:

(similaire à la réponse de Salem).

Créez un fichier en /etc/udev/rules.d/hdmi_sound.rulestant que root avec le contenu:

SUBSYSTEM=="drm", RUN+="/usr/local/bin/hdmi_sound_toggle"

La note ACTION=="change", manque!

Créez un fichier en /usr/local/bin/hdmi_sound_toggletant que root avec le contenu:

#!/bin/sh
USER_NAME=`who | grep "(:0)" | cut -f 1 -d ' '| sort -u`
USER_ID=`id -u $USER_NAME`
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`

export PULSE_SERVER="unix:/run/user/"$USER_ID"/pulse/native"

if [ $HDMI_STATUS = "connected" ]
then
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:hdmi-stereo+input:analog-stereo
else
    sudo -u $USER_NAME pactl --server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

Remarque USER_NAME =who | grep "(:0)" | cut -f 1 -d ' '| sort -u J'ai ajouté,| sort -usinon il est revenu avec -elemer elemer elemermon nom d'utilisateur 3 fois.

Rendez-le ensuite exécutable avec chmod 0755 /usr/local/bin/hdmi_sound_toggle

N'oubliez pas de recharger vos règles udev: sudo udevadm control --reload-rules

Important ce script est mis à jour pour 14.04. Avant cela, vous utiliseriez USER_NAME au lieu de USER_ID partout

Crédits: Salem et daniel .

elemer82
la source
1

Ubuntu 16.04 - 17.04 Répondre

Cela fonctionne pour Ubuntu 16.04 - 17.04 qui a introduit un bug avec Pulse Audio 8. Créez le fichier hotplugtv(ou hotplug-hdmisi vous préférez) et copiez dans les lignes suivantes:

#!/bin/bash

# NAME: hotplugtv
# PATH: /home/$USER/bin
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: called from /etc/udev/rules.d/99-hotplugtv.rules 
#       and /home/$USER/bin/lock-screen-timer
# DATE: Created Nov 26, 2016.
# NOTE: logs output using log-file
# UPDT: Dec 14, 2016 - Sometimes /sys/class/drm/card0 & sometimes /sys/class/drm/card1
#       so use /sys/class/dmcard* instead.
#       Dec 21, 2016 - Relocated to /home/$USER/bin for calling by lock-screen-timer
#       Aug 06, 2017 - Convert from home grown log-file to universal logger command.

if [[ $(cat /sys/class/drm/card*-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
        logger -t /home/rick/bin/log-hotplugtv "HDMI TV connected"
        /bin/sleep 2;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
else
        logger -t /home/rick/bin/log-hotplugtv "HDMI TV disconnected"
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
fi

exit 0

IMPORTANT: remplacez le nom d'utilisateur «rick» par votre nom d'utilisateur.

Afin d'appeler ce script à partir udevdes événements hot-plug, créez le fichier /etc/udev/rules.d/99-hotplugtv.rulescontenant:

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/home/rick/bin/hotplugtv"

Accédez /home/rick/bin/au chemin où vous avez placé le hotplugtvscript.

WinEunuuchs2Unix
la source
Merci beaucoup! Cela a également fonctionné sur Ubuntu 17.04! Cela me dérange depuis longtemps et c'était une solution simple :)
Georgi Koemdzhiev
1
De rien. Merci pour le commentaire confirmant qu'il est également nécessaire pour le 17.04.
WinEunuuchs2Unix