Configura la salida de sonido HDMI automáticamente al conectar/desconectar

Configura la salida de sonido HDMI automáticamente al conectar/desconectar

Tengo una configuración de pantalla dual en mi computadora portátil (usando 12.04 LTS) usando una pantalla conectada HDMI. Todo funciona bien, pero cada vez que conecto/desconecto el cable tengo que ir a Preferencias de Sonido y cambiar el dispositivo de salida de sonido manualmente.

¿Hay alguna forma de cambiar el dispositivo de salida de sonido al conectar/desconectar el cable, de modo que cuando conecto mi pantalla, la salida de sonido se configura en HDMI y cuando la desconecto el sonido vuelve a los parlantes de la computadora portátil?

Respuesta1

Para beneficio de las personas que se topan con esta pregunta: la solución de Salem casi funcionó para mí en 13.04, terminé reuniendo fragmentos de toda la web, creo que el factor decisivo para mí fue la falta de la variable de entorno PULSE_SERVER.

Aquí está mi solución completa, que básicamente consiste en repetir la solución de Salem con las pocas piezas que faltan. También lo rehice como un script de shell (a pesar de mi amor por Python) porque al principio tenía miedo de que mi script de Python tuviera problemas con la ruta de importación:


(igual que la respuesta de Salem) Cree un archivo /etc/udev/rules.d/hdmi_sound.rulescomo raíz con el contenido:

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

Crea un archivo /usr/local/bin/hdmi_sound_togglecomo root con el contenido:

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

Luego hazlo ejecutable conchmod 0755 /usr/local/bin/hdmi_sound_toggle

Intenté hacer que este script fuera lo más genérico posible, pero es posible que aún necesites cambiar algunas líneas, como la ruta del archivo HDMI_STATUS o los perfiles utilizados. Puede ver una lista de perfiles ejecutando pactl list cardsy buscando en Perfiles.

Tenga en cuenta que el script falló cuando eliminé la palabra clave "exportar" al configurar PULSE_SERVER, creo que pactl está buscando la variable env

No olvides recargar tus reglas de udev:sudo udevadm control --reload-rules

ActualizarEste script está actualizado para el 14.04. Antes de eso, usarías USER_NAME en lugar de USER_ID en todas partes.

Respuesta2

Ubuntu 16.04 - 20.04 Respuesta

Esto funciona para Ubuntu 16.04 - 20.04 que introdujo un error con Pulse Audio 8. Cree el archivo hotplugtv(o hotplug-hdmisi lo prefiere) y cópielo en las siguientes líneas:

#!/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:Cambie el nombre de usuario "rick" por su nombre de usuario.

Para llamar a este script udevdurante eventos de conexión en caliente, cree el archivo /etc/udev/rules.d/99-hotplugtv.rulesque contiene:

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

Cambie /home/rick/bin/a la ruta donde colocó hotplugtvel script.

Respuesta3

Finalmente logré hacer que esto funcionara usando udev. Entonces, si alguien quiere el mismo comportamiento, estos son los pasos:

Primero necesitamos crear un archivo /etc/udev/rules.d/hdmi_sound.rulescon el siguiente contenido:

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

esto hará que udevse ejecute el script hdmi_sound_togglecada vez que haya un cambio en la conexión HDMI. Ese script debe tener permiso de ejecución y el contenido es el siguiente:

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

Probablemente esto se pueda hacer fácilmente en bash, pero como mi idioma principal es Python, lo usé. Todo funciona menos la notificación: no aparece, realmente no sé por qué. Si alguien sabe como solucionarlo por favor diga algo.

Nota: los nombres de la regla script/udev se pueden cambiar, pero es necesario utilizar la ruta completa.

Respuesta4

Hay una manera más fácil:

Defina default-sink y default-source en /etc/pulse/default.pa, como se describe aquí: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

No olvides reiniciar pulseaudio antes de volver a intentarlo:

pulseaudio -k

información relacionada