Defina a saída de som HDMI automaticamente ao conectar/desconectar

Defina a saída de som HDMI automaticamente ao conectar/desconectar

Eu tenho uma configuração de tela dupla no meu laptop (usando 12.04 LTS) usando um monitor conectado por HDMI. Tudo funciona bem, mas sempre que conecto/desconecto o cabo tenho que ir às preferências de som e alterar manualmente o dispositivo de saída de som.

Existe alguma maneira de alterar o dispositivo de saída de som ao conectar/desconectar o cabo, então quando eu conecto meu monitor a saída de som é definida como HDMI e quando eu o desconecto o som volta para os alto-falantes do laptop?

Responder1

Para o benefício das pessoas que se deparam com esta questão - a solução de Salem quase funcionou para mim em 13.04, acabei reunindo pedaços de toda a web, acho que o problema para mim foi a falta da variável de ambiente PULSE_SERVER

Aqui está minha solução completa, que basicamente repete a solução de Salem com algumas peças que faltam. Eu também o refiz como um script de shell (apesar de meu amor por Python) porque inicialmente tive medo de que meu script Python estivesse apresentando problemas de caminho de importação:


(igual à resposta de Salem) Crie um arquivo /etc/udev/rules.d/hdmi_sound.rulescomo root com o conteúdo:

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

Crie um arquivo /usr/local/bin/hdmi_sound_togglecomo root com o conteúdo:

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

Em seguida, torne-o executável comchmod 0755 /usr/local/bin/hdmi_sound_toggle

Tentei deixar esse script o mais genérico possível, mas ainda pode ser necessário alterar algumas linhas, como o caminho do arquivo HDMI_STATUS ou os perfis usados. Você pode ver uma lista de perfis executando pactl list cardse procurando em Perfis.

Observe que o script falhou para mim quando removi a palavra-chave "export" ao configurar PULSE_SERVER, acho que pactl está procurando a variável env

Não se esqueça de recarregar suas regras do udev:sudo udevadm control --reload-rules

Atualizareste script foi atualizado para 14.04. Antes disso, você usaria USER_NAME em vez de USER_ID em todos os lugares

Responder2

Ubuntu 16.04 - 20.04 Resposta

Isso funciona para Ubuntu 16.04 - 20.04 que introduziu um bug no Pulse Audio 8. Crie o arquivo hotplugtv(ou hotplug-hdmise preferir) e copie nas seguintes linhas:

#!/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:Altere o nome de usuário "rick" para o seu nome de usuário.

Para chamar esse script udevdurante eventos hot-plug, crie o arquivo /etc/udev/rules.d/99-hotplugtv.rulescontendo:

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

Mude /home/rick/bin/para o caminho onde você colocou hotplugtvo script.

Responder3

Finalmente consegui fazer isso funcionar usando udev. Então, se alguém quiser o mesmo comportamento, aqui estão as etapas:

Primeiro precisamos criar um arquivo /etc/udev/rules.d/hdmi_sound.rulescom o seguinte conteúdo:

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

isso fará com que udevo script seja executado hdmi_sound_togglesempre que houver uma mudança na conexão HDMI. Esse script deve ter permissão de execução e o conteúdo é o seguinte:

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

Provavelmente isso pode ser feito facilmente no bash, mas como minha linguagem principal é python eu usei. Tudo funciona menos a notificação: não aparece, realmente não sei por quê. Se alguém souber como consertar, por favor diga alguma coisa.

Nota: os nomes da regra script/udev podem ser alterados, mas você precisa usar o caminho completo.

Responder4

Existe uma maneira mais fácil:

Defina default-sink e default-source em /etc/pulse/default.pa, conforme descrito aqui: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

Não se esqueça de reiniciar o pulseaudio antes de tentar novamente:

pulseaudio -k

informação relacionada