Imposta l'uscita audio HDMI automaticamente su connessione / disconnessione


20

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

Esiste un modo per cambiare il dispositivo di uscita audio al momento della connessione / disconnessione del cavo, quindi quando collego il mio display l'uscita audio è impostata su HDMI e quando la disconnetto il suono torna agli altoparlanti del laptop?


Lo stesso problema qui.
ThiagoPonte

Questa è la prima volta che vengo qui per qualsiasi aiuto su questo ... Sono sulla stessa barca il 12.10. È fastidioso. È stato così dal 10.10 nella mia esperienza. Deve esserci una configurazione da qualche parte in grado di gestirlo. EDIT: voices.canonical.com/david.henningsson/2012/04/14/… È impostato appositamente in questo modo. È orribile.
user138216

Controlla se la mia risposta funziona con te.
Salem,

Risposte:


11

A beneficio delle persone che si imbattono in questa domanda: la soluzione di Salem ha funzionato quasi per me nel 13.04, ho finito per raccogliere frammenti da tutto il web, penso che il patto per me fosse la mancanza della variabile d'ambiente PULSE_SERVER

Ecco la mia soluzione completa, che sostanzialmente ripete la soluzione di Salem con i pochi pezzi mancanti. L'ho anche rifatto come uno script di shell (nonostante il mio amore per Python) perché all'inizio avevo paura che il mio script Python si imbattesse in problemi relativi al percorso di importazione:


(uguale alla risposta di Salem) Crea un file /etc/udev/rules.d/hdmi_sound.rulescome root con il contenuto:

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

Crea un file /usr/local/bin/hdmi_sound_togglecome 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 renderlo eseguibile con chmod 0755 /usr/local/bin/hdmi_sound_toggle

Ho provato a rendere questo script il più generico possibile, ma potresti ancora aver bisogno di cambiare alcune linee, come il percorso del file HDMI_STATUS o i profili utilizzati. Puoi visualizzare un elenco di profili eseguendo pactl list cardse guardando in Profili.

Nota che lo script non è riuscito per me quando ho rimosso la parola chiave "export" durante l'impostazione di PULSE_SERVER, penso che pactl stia cercando la variabile env

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

Aggiorna questo script è aggiornato per 14.04. Prima di allora, avresti usato USER_NAME invece di USER_ID ovunque


1
Nota che dovevo accodare | uniqal comando USER_NAME. Si noti inoltre che le impostazioni dei suoni in Ubuntu possono essere ingannevoli. Non vedevo i cambiamenti nel pannello delle impostazioni audio, ma una volta riprodotto qualcosa l'audio si spostava avanti e indietro senza problemi e ho anche notato che dopo alcune volte di collegamento e scollegamento dell'HDMI, lo script ha smesso di essere eseguito (forse alcuni sorta di bug in udev).
Fuego,

1
Ho aggiunto | sort -uil nome utente perché diceva un'opzione extra elemer elemer --- Il mio nome utente. Come la soluzione di FuegoFro alla fine della giornata.
elemer82

Ho usato | grep -v pts, perché in realtà ho avuto anche un utente "root" lì, a causa del fatto che stavo modificando lo script tramite Kate, che aveva un terminale root aperto.
Auspex,

Continuare a ricevere "Errore di connessione: connessione rifiutata pa_context_connect () non riuscita: connessione rifiutata" durante l'esecuzione di pactl. : \
Tomislav Nakic-Alfirevic il

7

Finalmente sono 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.rulescon il seguente contenuto:

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

questo farà udeveseguire lo script hdmi_sound_toggleogni volta che si verifica una modifica nella connessione HDMI. Lo script deve disporre dell'autorizzazione di esecuzione e i contenuti sono i seguenti:

#!/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 facilmente realizzato 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, ti preghiamo di dire qualcosa.

Nota: i nomi della regola script / udev possono essere modificati, ma è necessario utilizzare il percorso completo.


3

Sulla base di Salem 's risposta e Daniel risposta' s

Ho preso la risposta di Salem e la risposta di Daniel e ho apportato alcune modifiche necessarie, la loro soluzione non ha funzionato per me fuori dagli schemi:

(simile alla risposta di Salem).

Crea un file /etc/udev/rules.d/hdmi_sound.rulescome 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_togglecome 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 -uperché altrimenti è tornato conelemer elemer elemer--my username 3 volte.

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

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

Importante questo script è aggiornato per il 14.04. Prima di allora, avresti usato USER_NAME invece di USER_ID ovunque

Crediti: Salem e daniel .


1

Risposta di Ubuntu 16.04 - 17.04

Funziona con Ubuntu 16.04 - 17.04 che ha introdotto un bug con Pulse Audio 8. Crea il file hotplugtv(o hotplug-hdmise 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: modificare il nome utente "rick" con il proprio nome utente.

Per chiamare questo script udevdurante gli eventi hot plug, creare il file /etc/udev/rules.d/99-hotplugtv.rulescontenente:

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

Passa /home/rick/bin/al percorso in cui hai inserito lo hotplugtvscript.


Grazie mille! Ha funzionato anche su Ubuntu 17.04! Questo mi ha infastidito per molto tempo ed è stata una soluzione semplice :)
Georgi Koemdzhiev,

1
Sei il benvenuto. Grazie per il commento che conferma che è necessario anche per 17.04.
WinEunuuchs2Unix
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.