J'ai une configuration à double écran sur mon ordinateur portable (avec 12.04 LTS) à l'aide d'un écran connecté par HDMI. Tout fonctionne bien, mais chaque fois que je connecte/déconnecte le câble, je dois accéder aux préférences Son et changer le périphérique de sortie du son manuellement.
Est-il possible de changer le périphérique de sortie audio lors de la connexion/déconnexion du câble, de sorte que lorsque je connecte mon écran, la sortie audio est réglée sur HDMI et lorsque je le déconnecte, le son est renvoyé aux haut-parleurs de l'ordinateur portable?
J'ai finalement réussi à faire fonctionner 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.rules
avec le contenu suivant:
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"
ceci va permettre à udev
d'exécuter le script hdmi_sound_toggle
chaque fois qu'il y a un changement de connexion HDMI. Ce script doit avoir une 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 ma langue principale est python je l'ai utilisé. Tout fonctionne sauf la notification: cela ne s'affiche pas, je ne sais vraiment pas pourquoi. Si quelqu'un sait comment le réparer, dites quelque chose.
Remarque: les noms de règle de script/udev peuvent être modifiés, mais vous devez utiliser le chemin complet.
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 fragments de tout le Web, je pense que la rupture de la transaction a été pour moi l'absence de la variable d'environnement Pulse_SERVER
Voici ma solution complète, qui consiste essentiellement à répéter 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) parce que j'avais peur au début que mon script Python se heurte à des problèmes de chemin d'importation:
(identique à la réponse de Salem) Créez un fichier /etc/udev/rules.d/hdmi_sound.rules
en tant que root avec le contenu:
SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/hdmi_sound_toggle"
Créez un fichier /usr/local/bin/hdmi_sound_toggle
en tant 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
Puis rendez-le 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 aurez peut-être encore besoin de changer 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 cards
et 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
Mise à jour ce script est mis à jour pour 14.04. Avant cela, vous utiliseriez USER_NAME au lieu de USER_ID partout.
J'ai pris la réponse de Salem et celle de daniel et apporté les modifications nécessaires. Leur solution n'a pas fonctionné pour moi immédiatement:
(similaire à la réponse de Salem).
Créez un fichier /etc/udev/rules.d/hdmi_sound.rules
en tant que root avec le contenu:
SUBSYSTEM=="drm", RUN+="/usr/local/bin/hdmi_sound_toggle"
Remarque ACTION=="change",
est manquant!
Créez un fichier /usr/local/bin/hdmi_sound_toggle
en tant 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 -u
car sinon, il est retourné avec elemer elemer elemer
--mon nom d'utilisateur 3 fois .
Puis rendez-le 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.
Cela fonctionne pour Ubuntu 16.04 - 17.04 qui introduisait un bogue avec Pulse Audio 8. Créez le fichier hotplugtv
(ou hotplug-hdmi
si vous préférez) et copiez-le 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.
Pour appeler ce script à partir de udev
lors d'événements hot-plug, créez le fichier /etc/udev/rules.d/99-hotplugtv.rules
contenant:
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/home/rick/bin/hotplugtv"
Remplacez /home/rick/bin/
par le chemin où vous avez placé le script hotplugtv
.