Imposta automaticamente l'uscita audio HDMI su connessione / disconnessione

18

Ho una configurazione a doppio schermo sul mio laptop (usando 12.04 LTS) usando un display HDMI collegato. Tutto funziona bene, ma ogni volta che connetto / disconnetto il cavo devo andare su Preferenze audio e cambiare manualmente il dispositivo di uscita del suono.

C'è un modo per cambiare il dispositivo di uscita audio sulla connessione / disconnessione del cavo, quindi quando collego il mio schermo l'uscita audio è impostata su HDMI e quando la scollego il suono ritorna agli altoparlanti del laptop?

    
posta Salem 02.03.2013 - 23:12

5 risposte

7

Sono finalmente riuscito a farlo funzionare usando udev . Quindi, se qualcuno vuole lo stesso comportamento, ecco i passaggi:

Per prima cosa dobbiamo creare un file /etc/udev/rules.d/hdmi_sound.rules con il seguente contenuto:

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

questo renderà udev a eseguire lo script hdmi_sound_toggle ogni volta che c'è una modifica nella connessione HDMI. Questo script deve avere il permesso di esecuzione e il contenuto è il seguente:

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

Probabilmente questo può essere fatto facilmente in bash, ma poiché il mio linguaggio principale è python l'ho usato. Tutto funziona tranne la notifica: non si presenta, davvero non so perché. Se qualcuno sa come risolverlo, per favore dì qualcosa.

Nota: i nomi delle regole di script / udev possono essere modificati, ma è necessario utilizzare il percorso completo.

    
risposta data Salem 08.03.2013 - 17:09
11

Per il beneficio delle persone che incappano in questa domanda - la soluzione di Salem ha quasi funzionato per me nel 13.04, ho finito per raccogliere pezzi da tutto il web, penso che l'interruttore per me è stata la mancanza della variabile di ambiente PULSE_SERVER

Ecco la mia soluzione completa, che sostanzialmente sta ripetendo la soluzione di Salem con i pochi pezzi mancanti. L'ho anche ridimensionato come script di shell (nonostante il mio amore per Python) perché inizialmente temevo che il mio script Python fosse in esecuzione nei problemi di importazione:

(come la risposta di Salem) Crea un file /etc/udev/rules.d/hdmi_sound.rules come utente root con il contenuto:

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

Crea un file /usr/local/bin/hdmi_sound_toggle come utente root con il contenuto:

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

Quindi rendilo eseguibile con chmod 0755 /usr/local/bin/hdmi_sound_toggle

Ho cercato di rendere questo script il più generico possibile, ma potrebbe comunque essere necessario modificare alcune righe, come il percorso del file HDMI_STATUS oi profili utilizzati. Puoi visualizzare un elenco di profili eseguendo pactl list cards e guardando in Profili.

Si noti che lo script non è riuscito per me quando ho rimosso la parola chiave "export" quando ho impostato PULSE_SERVER, penso che pactl stia cercando la variabile env

Non dimenticare di ricaricare le tue regole di udev: sudo udevadm control --reload-rules

Aggiornamento questo script viene aggiornato per 14.04. Prima dovresti utilizzare USER_NAME invece di USER_ID ovunque

    
risposta data Daniel 26.12.2013 - 01:10
3

Basato su risposta di Salem e daniel risposta

Ho preso la risposta di Salem e daniel ha risposto e fatto alcuni cambiamenti necessari, la loro soluzione non ha funzionato per me fuori dalla scatola:

(simile alla risposta di Salem).

Crea un file /etc/udev/rules.d/hdmi_sound.rules come utente root con il contenuto:

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

Nota ACTION=="change", mancante!

Crea un file /usr/local/bin/hdmi_sound_toggle come utente root con il contenuto:

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

Nota USER_NAME = who | grep "(:0)" | cut -f 1 -d ' '| sort -u Ho aggiunto | sort -u perché altrimenti è tornato con elemer elemer elemer --my nome utente 3 volte.

Quindi rendilo eseguibile con chmod 0755 /usr/local/bin/hdmi_sound_toggle

Non dimenticare di ricaricare le tue regole di udev: sudo udevadm control --reload-rules

Importante questo script viene aggiornato per 14.04. Prima dovresti utilizzare USER_NAME invece di USER_ID ovunque

Crediti: Salem e Daniel .

    

risposta data elemer82 09.10.2014 - 21:31
2

Questa è la prima volta che vengo qui per qualsiasi aiuto su questo ... Sono sulla stessa barca il 12.10. È fastidioso. È così da 10.10 anni nella mia esperienza. Ci deve essere una configurazione da qualche parte in grado di gestirlo.

EDIT: link

È impostato in questo modo di proposito. È orribile.

    
risposta data user138216 07.03.2013 - 00:06
1

Ubuntu 16.04 - 17.04 Risposta

Questo funziona con Ubuntu 16.04 - 17.04 che ha introdotto un bug con Pulse Audio 8. Crea il file hotplugtv (o hotplug-hdmi se preferisci) e copia nelle seguenti righe:

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

IMPORTANTE: modifica il nome utente "rick" con il tuo nome utente.

Per chiamare questo script da udev durante gli eventi hot-plug, crea il file /etc/udev/rules.d/99-hotplugtv.rules contenente:

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

Modifica /home/rick/bin/ nel percorso in cui hai inserito lo script hotplugtv .

    

risposta data WinEunuuchs2Unix 25.04.2017 - 00:54

Leggi altre domande sui tag