Configurar saída de som HDMI automaticamente ao conectar / desconectar

18

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 toda vez que eu conecto / desconecto o cabo eu tenho que ir para Preferências de som e mudar o dispositivo de saída de som manualmente.

Existe alguma maneira de alterar o dispositivo de saída de som na conexão / desconexão do cabo, então quando eu conecto meu monitor a saída de som é ajustada para HDMI e quando eu o desconecto o som volta para os alto-falantes do laptop?

    
por Salem 02.03.2013 / 23:12

5 respostas

7

Eu finalmente consegui fazer isso funcionar usando udev . Então, se alguém quiser o mesmo comportamento, veja as etapas:

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

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

isso fará com que udev execute o script hdmi_sound_toggle sempre que houver uma alteração 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, exceto a notificação: ele não aparece, eu realmente não sei porque. Se alguém souber como consertá-lo, por favor, diga alguma coisa.

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

    
por Salem 08.03.2013 / 17:09
11

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

Aqui está a minha solução completa, que basicamente repete a solução de Salem com as poucas peças que faltam. Eu também o refiz como um shell script (apesar do meu amor por Python) porque no começo eu estava com medo de que meu script Python estivesse sendo executado em problemas de caminho de importação:

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

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

Crie um arquivo /usr/local/bin/hdmi_sound_toggle como 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 com chmod 0755 /usr/local/bin/hdmi_sound_toggle

Eu tentei tornar esse script o mais genérico possível, mas você ainda pode precisar alterar algumas linhas, como o caminho do arquivo HDMI_STATUS ou os perfis usados. Você pode ver uma lista de perfis executando pactl list cards e procurando em Perfis.

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

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

Atualizar este script é atualizado para o 14.04. Antes disso, você usaria USER_NAME em vez de USER_ID em todos os lugares

    
por Daniel 26.12.2013 / 01:10
3

Baseado na resposta Salem e resposta do daniel

Eu respondi Salem e daniel respondeu e fez algumas mudanças necessárias, a solução não funcionou para mim fora da caixa:

(semelhante à resposta de Salem).

Crie um arquivo /etc/udev/rules.d/hdmi_sound.rules como root com o conteúdo:

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

Nota ACTION=="change", está faltando!

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

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

Observação USER_NAME = who | grep "(:0)" | cut -f 1 -d ' '| sort -u adicionei | sort -u porque senão ele retornou com elemer elemer elemer --my nome de usuário 3 vezes.

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

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

Importante este script é atualizado para o 14.04. Antes disso, você usaria USER_NAME em vez de USER_ID em todos os lugares

Créditos: Salem e daniel .

    
por elemer82 09.10.2014 / 21:31
2

Esta é a primeira vez que venho aqui por alguma ajuda sobre isso ... Eu estou no mesmo barco em 12.10. É irritante. Tem sido assim desde 10.10 na minha experiência. Tem que haver uma configuração em algum lugar que possa lidar com isso.

EDIT: link

É definido dessa maneira de propósito. Isso é horrível.

    
por user138216 07.03.2013 / 00:06
1

Ubuntu 16.04 - 17.04 Resposta

Isso funciona para o Ubuntu 16.04 - 17.04, que introduziu um bug no Pulse Audio 8. Crie o arquivo hotplugtv (ou hotplug-hdmi , se preferir) e copie as 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 de udev durante eventos de hot-plug, crie o arquivo /etc/udev/rules.d/99-hotplugtv.rules contendo:

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

Altere /home/rick/bin/ para o caminho em que você colocou o script hotplugtv .

    
por WinEunuuchs2Unix 25.04.2017 / 00:54