Stellen Sie die HDMI-Tonausgabe beim Verbinden / Trennen automatisch ein


20

Ich habe ein Dual-Screen-Setup auf meinem Laptop (mit 12.04 LTS) über ein HDMI-verbundenes Display. Alles funktioniert einwandfrei, aber jedes Mal, wenn ich das Kabel ein- oder ausstecke, muss ich die Toneinstellungen aufrufen und das Tonausgabegerät manuell ändern.

Gibt es eine Möglichkeit, das Audioausgabegerät beim Anschließen / Trennen des Kabels zu ändern, sodass beim Anschließen des Bildschirms die Audioausgabe auf HDMI eingestellt wird und beim Trennen der Audioausgabe wieder auf die Laptop-Lautsprecher erfolgt?


Selbes Problem hier.
ThiagoPonte

Dies ist das erste Mal, dass ich hierher komme, um Hilfe zu erhalten. Ich bin am 12.10. Im selben Boot. Es ist nervig. Meiner Erfahrung nach ist es seit 10.10 so. Irgendwo muss es eine Konfiguration geben, die damit umgehen kann. EDIT: voices.canonical.com/david.henningsson/2012/04/14/… Es ist absichtlich so eingestellt. Das ist schrecklich.
user138216

Überprüfen Sie, ob meine Antwort mit Ihnen funktioniert.
Salem

Antworten:


11

Zum Wohle der Leute, die über diese Frage stolpern - Salems Lösung hat sich am 13.04. Beinahe für mich bewährt. Am Ende habe ich alles Mögliche aus dem Internet zusammengetragen. Ich denke, der Deal Breaker für mich war das Fehlen der Umgebungsvariablen PULSE_SERVER

Hier ist meine vollständige Lösung, die im Grunde Salems Lösung mit den wenigen fehlenden Teilen wiederholt. Ich habe es auch als Shell-Skript überarbeitet (trotz meiner Vorliebe für Python), weil ich zuerst befürchtet hatte, dass mein Python-Skript Probleme mit dem Importpfad hat:


(wie bei Salems Antwort) Erstelle eine Datei /etc/udev/rules.d/hdmi_sound.rulesals root mit dem Inhalt:

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

Erstellen Sie eine Datei /usr/local/bin/hdmi_sound_toggleals root mit 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

Dann mache es ausführbar mit chmod 0755 /usr/local/bin/hdmi_sound_toggle

Ich habe versucht, dieses Skript so allgemein wie möglich zu gestalten, aber möglicherweise müssen Sie noch einige Zeilen ändern, z. B. den Dateipfad HDMI_STATUS oder die verwendeten Profile. Sie können eine Liste der Profile anzeigen, indem Sie sie pactl list cardsunter Profile ausführen und suchen.

Beachten Sie, dass das Skript für mich fehlgeschlagen ist, als ich das Schlüsselwort "export" beim Setzen von PULSE_SERVER entfernt habe. Ich denke, pactl sucht nach der env-Variablen

Vergiss nicht, deine udev-Regeln neu zu laden: sudo udevadm control --reload-rules

Aktualisieren Sie dieses Skript für 14.04 Uhr. Vorher würden Sie überall USER_NAME anstelle von USER_ID verwenden


1
Beachten Sie, dass ich | uniqan den Befehl USER_NAME anhängen musste. Beachten Sie auch, dass die Soundeinstellungen in Ubuntu täuschen können. Ich habe die Änderungen nicht im Soundeinstellungsfenster gesehen, aber als ich etwas abgespielt habe, hat sich das Audio reibungslos hin und her bewegt. Ich habe auch festgestellt, dass das Skript nach ein paar Mal Einstecken und Herausziehen des HDMI-Kabels nicht mehr ausgeführt wird (möglicherweise einige) Art Fehler in udev).
FuegoFro

1
Ich | sort -uhabe den Benutzernamen hinzugefügt , weil darin die zusätzliche Option elemer elemer --- My username stand. Entspricht der Lösung von FuegoFro am Ende des Tages.
Elemer82

Ich habe verwendet | grep -v pts, weil ich dort auch einen "root" -Benutzer habe - aufgrund der Tatsache, dass ich das Skript über kate bearbeitet habe, bei dem ein Root-Terminal geöffnet war.
Auspex

Erhalten Sie weiterhin "Verbindungsfehler: Verbindung abgelehnt pa_context_connect () fehlgeschlagen: Verbindung abgelehnt", wenn pactl ausgeführt wird. : \
Tomislav Nakic-Alfirevic

7

Ich habe es endlich geschafft, diese Arbeit mit zu machen udev. Wenn also jemand dasselbe Verhalten möchte, sind hier die Schritte:

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

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

das macht udevdas Skript ausführen , hdmi_sound_togglejedes Mal gibt es eine Änderung in HDMI - Anschluss. Dieses Skript muss über die Ausführungsberechtigung verfügen und die Inhalte lauten wie folgt:

#!/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 kann dies leicht mit Bash gemacht werden, aber da meine Hauptsprache Python ist, habe ich es benutzt. Alles funktioniert bis auf die Benachrichtigung: Es wird nicht angezeigt, ich weiß wirklich nicht warum. Wenn jemand weiß, wie man das Problem behebt, sagt bitte etwas.

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


3

Basierend auf Salems Antwort und Daniel Antwort

Ich nahm Salems Antwort und Daniels Antwort und nahm einige notwendige Änderungen vor. Ihre Lösung funktionierte nicht sofort für mich:

(Ähnlich wie Salems Antwort).

Erstellen Sie eine Datei /etc/udev/rules.d/hdmi_sound.rulesals root mit dem Inhalt:

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

Notiz ACTION=="change", fehlt!

Erstellen Sie eine Datei /usr/local/bin/hdmi_sound_toggleals root mit dem Inhalt:

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

Hinweis USER_NAME =who | grep "(:0)" | cut -f 1 -d ' '| sort -u Ich habe hinzugefügt,| sort -uweil es sonst mit zurückgekommen istelemer elemer elemer dreimal --my username zurückgekommen ist.

Dann mache es ausführbar mit chmod 0755 /usr/local/bin/hdmi_sound_toggle

Vergiss nicht, deine udev-Regeln neu zu laden: sudo udevadm control --reload-rules

Wichtig Dieses Skript wurde für den 14.04. Aktualisiert. Vorher würden Sie überall USER_NAME anstelle von USER_ID verwenden

Credits: Salem und Daniel .


1

Ubuntu 16.04 - 17.04 Antwort

Dies funktioniert für Ubuntu 16.04 - 17.04, das einen Fehler mit Pulse Audio 8 verursacht hat. Erstellen Sie die Datei hotplugtv(oder hotplug-hdmiwenn Sie es vorziehen) und kopieren Sie sie in die folgenden Zeilen:

#!/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 eines Hot-Plug-Ereignisses aufzurufen, erstellen Sie die Datei /etc/udev/rules.d/99-hotplugtv.rulesmit:

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

Wechseln Sie /home/rick/bin/zu dem Pfad, in dem Sie das hotplugtvSkript platziert haben .


Ich danke dir sehr! Es hat auch auf Ubuntu 17.04 funktioniert! Das nervt mich schon lange und das war eine einfache Lösung :)
Georgi Koemdzhiev

1
Sie sind herzlich willkommen. Vielen Dank für den Kommentar, der bestätigt, dass er auch für den 17.04 benötigt wird.
WinEunuuchs2Unix
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.