HDMI-Tonausgabe beim Verbinden/Trennen automatisch einstellen

HDMI-Tonausgabe beim Verbinden/Trennen automatisch einstellen

Ich habe auf meinem Laptop (mit 12.04 LTS) eine Dual-Screen-Konfiguration mit einem über HDMI angeschlossenen Display. Alles funktioniert einwandfrei, aber jedes Mal, wenn ich das Kabel anschließe/trenne, muss ich zu den Soundeinstellungen gehen und das Tonausgabegerät manuell ändern.

Gibt es eine Möglichkeit, das Tonausgabegerät beim Anschließen/Trennen des Kabels zu ändern, sodass beim Anschließen meines Displays die Tonausgabe auf HDMI eingestellt ist und beim Trennen der Ton wieder über die Laptop-Lautsprecher geht?

Antwort1

Für diejenigen, die über diese Frage stolpern: Salems Lösung hat bei mir in 13.04 fast funktioniert, ich habe schließlich alles aus dem Internet zusammengetragen, aber ich glaube, der Knackpunkt für mich war das Fehlen der Umgebungsvariable PULSE_SERVER.

Hier ist meine vollständige Lösung, die im Grunde Salems Lösung mit den wenigen fehlenden Teilen wiederholt. Ich habe sie auch als Shell-Skript neu erstellt (trotz meiner Vorliebe für Python), weil ich zunächst befürchtete, dass mein Python-Skript auf Probleme mit dem Importpfad stößt:


(dasselbe wie Salems Antwort) Erstellen Sie /etc/udev/rules.d/hdmi_sound.rulesals Root eine Datei mit dem Inhalt:

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

Erstellen Sie als Root eine Datei /usr/local/bin/hdmi_sound_togglemit dem Inhalt:

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

Machen Sie es dann ausführbar mitchmod 0755 /usr/local/bin/hdmi_sound_toggle

Ich habe versucht, dieses Skript so allgemein wie möglich zu gestalten, aber Sie müssen möglicherweise trotzdem einige Zeilen ändern, z. B. den HDMI_STATUS-Dateipfad oder die verwendeten Profile. Sie können eine Liste der Profile anzeigen, indem Sie es ausführen pactl list cardsund unter „Profile“ nachsehen.

Beachten Sie, dass das Skript bei mir fehlgeschlagen ist, als ich beim Festlegen von PULSE_SERVER das Schlüsselwort "export" entfernt habe. Ich denke, pactl sucht nach der Umgebungsvariable

Vergessen Sie nicht, Ihre Udev-Regeln neu zu laden:sudo udevadm control --reload-rules

AktualisierenDieses Skript wurde für 14.04 aktualisiert. Davor hätten Sie überall USER_NAME statt USER_ID verwendet

Antwort2

Ubuntu 16.04 - 20.04 Antwort

Dies funktioniert für Ubuntu 16.04 – 20.04, bei dem ein Fehler mit Pulse Audio 8 aufgetreten ist. Erstellen Sie die Datei hotplugtv(oder, hotplug-hdmiwenn Sie dies bevorzugen) und kopieren Sie die folgenden Zeilen hinein:

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

WICHTIG:Ändern Sie den Benutzernamen „rick“ in Ihren Benutzernamen.

Um dieses Skript udevwährend Hot-Plug-Ereignissen aufzurufen, erstellen Sie die Datei /etc/udev/rules.d/99-hotplugtv.rulesmit dem folgenden Inhalt:

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

Wechseln Sie /home/rick/bin/zum Pfad, in dem Sie hotplugtvdas Skript platziert haben.

Antwort3

Ich habe es endlich geschafft, dies mit zum Laufen zu bringen udev. Wenn also jemand dasselbe Verhalten möchte, sind hier die Schritte:

/etc/udev/rules.d/hdmi_sound.rulesZuerst müssen wir eine Datei mit folgendem Inhalt erstellen :

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

Dadurch wird udevdas Skript hdmi_sound_togglejedes Mal ausgeführt, wenn sich die HDMI-Verbindung ändert. Das Skript muss über eine Ausführungsberechtigung verfügen und hat den folgenden Inhalt:

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

Wahrscheinlich lässt sich das ganz einfach in Bash machen, aber da meine Hauptsprache Python ist, habe ich es verwendet. Alles funktioniert, außer der Benachrichtigung: Sie wird nicht angezeigt, ich weiß wirklich nicht, warum. Wenn jemand weiß, wie man das behebt, sagen Sie bitte etwas.

Hinweis: Die Namen der Skript-/Udev-Regel können geändert werden, Sie müssen aber den vollständigen Pfad verwenden.

Antwort4

Es geht auch einfacher:

Definieren Sie Standardsenke und Standardquelle in /etc/pulse/default.pa, wie hier beschrieben:https://rastating.github.io/setting-default-audio-device-in-ubuntu-18-04/

grep default- /etc/pulse/default.pa
load-module module-default-device-restore
set-default-sink alsa_output.pci-0000_00_1f.3.analog-stereo
set-default-source alsa_input.pci-0000_00_1f.3.analog-stereo

Vergessen Sie nicht, Pulseaudio vor dem erneuten Versuch neu zu starten:

pulseaudio -k

verwandte Informationen