Alternando para o áudio HDMI quando o HDMI está conectado a um laptop (14.04)

12

Estou tentando fazer com que meu laptop mude o áudio para HDMI quando estiver conectado e de volta ao analógico padrão quando for removido.

Eu configurei uma regra do udev para acionar um script para executar a alternância, no entanto, estou tendo problemas para fazê-lo funcionar:

  • Parece que até eu selecionar a saída de áudio HDMI nas Configurações de som, ela não é reconhecida como um coletor disponível, também quando a saída de áudio HDMI é selecionada, a saída analógica não está mais listada.

Veja abaixo:

# HDMI plugged in, not selected in Sound settings.
$ pactl list short sinks 
5   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED
kingamajick@kingamajick-laptop: ~

# HDMI selected in sound settings    
$ pactl list short sinks 
7   alsa_output.pci-0000_00_1b.0.hdmi-stereo    module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED
kingamajick@kingamajick-laptop: ~

# HDMI removed
$ pactl list short sinks 
9   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED

O script que estou usando para alternar a saída é o seguinte:

#!/bin/bash
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done-server $PULSE_SERVER set-card-profile 0 output:analog-stereo+input:analog-stereo
fi

O script apresenta um erro sobre esse coletor quando o aciono antes de selecionar HDMI nas configurações de som.

Kingamajick
fonte

Respostas:

9
  1. Verifique os cartões e perfis disponíveis

    pactl list cards
    
  2. Inclua o seguinte comando no script para alterar o perfil antes de configurar o coletor padrão e os fluxos em movimento

    pactl [options] set-card-profile  CARD PROFILE
    

(Portanto, não é necessário alternar manualmente nas Configurações de som)

Referência:

pactl -h & man pactl

user.dz
fonte
9

Baseado neste link e neste link ... eu testei e funciona bem ubuntu 14.04

você deve criar uma regra em /etc/udev/rules.d/100-hdmi_sound.rules

com este conteúdo

SUBSYSTEM=="drm", ACTION=="change", RUN+="/lib/udev/hdmi_sound_toggle.sh"

então crie

sudo -H gedit /lib/udev/hdmi_sound_toggle.sh

com seu conteúdo

#!/bin/bash

HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))
if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi

Espero que possa ajudar .. desculpe pelo meu inglês eu falava espanhol

Sk.
fonte
4

Eu tive um pouco de dificuldade em seguir isso. Copiei o script original e modifiquei-o conforme sugerido e agora funciona.

Estou incluindo aqui para facilitar o uso de outra pessoa.

#!/bin/bash
## From: /ubuntu/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now

##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pacmd list-sink-inputs | grep index | awk '{print $2}'))

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pacmd move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi

Agora, eu gostaria de acioná-lo com o udev, mas não tenho noção de como fazer isso.

Joe
fonte
1
Isso não funciona no 16.04. Estou trabalhando nisso novamente.
Joe
3

Os scripts fornecidos não funcionaram para mim com o udev pronto para uso no Ubuntu 14.04, tive que adicionar:

export DISPLAY=:0

no início, converta os dois comandos pacmd em pactl e, finalmente, execute o script usando sudo -s -u (user) da regra udev.

#!/bin/bash
## From: /ubuntu/458194/switching-to-hdmi-audio-when-hdmi-is-plugged-into-a-laptop-14-04
## Script needs to be triggered by a udev rule
## Works manually now

export DISPLAY=:0

##source ${HOME}/bin/bash_trace
HDMI_STATUS=`cat /sys/class/drm/card0/*HDMI*/status`
INPUTS=($(pactl list sink-inputs | grep Input | awk '{print $3}' | sed -r 's/^.{1}//')

if [ $HDMI_STATUS = "connected" ]
then
    pactl set-card-profile 0 output:hdmi-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.hdmi-stereo
    for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.hdmi-stereo  &> /dev/null; done
else
    pactl set-card-profile 0 output:analog-stereo
    pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
    for i in ${INPUTS[*]}; do pactl move-sink-input $i alsa_output.pci-0000_00_1b.0.analog-stereo  &> /dev/null; done
fi
Ken
fonte
2

Bem, todos os scripts fornecidos não funcionaram para mim (Ubuntu 16.04), mas eu achei este indicador de aplicativo que permite alterar a saída de som com apenas um clique:

https://github.com/lkettenb/sound-output-switcher

(nota: você precisa instalar o pacote appindicator primeiro: sudo apt-get install python-appindicator)

Só pensei em deixar isso aqui para outras pessoas que possam estar na mesma situação que eu, mesmo que seja uma solução alternativa ... mas facilita e é discreto ;-)

Nat Azodnem
fonte
0

Mais uma vez, outra solução (testada em 16.04) com base nas anteriores, mas com algumas melhorias que funcionam usando o pactlapontador adequado para o servidor certo (pode ser aprimorada para obter automaticamente nomes dos cartões e perfis, consulte pactl listou pactl infopor enquanto).

#!/bin/bash

USER_NAME=$(who | grep tty$(sudo fgconsole) | cut -f1 -d' ')
USER_ID=$(id -u "$USER_NAME")
HDMI_STATUS=$(</sys/class/drm/card0/*HDMI*/status)

HDMI_CARD="pci-0000_00_03.0"
HDMI_PROFILE="hdmi-stereo-extra1"

INTERNAL_CARD="pci-0000_00_1b.0"
INTERNAL_PROFILE="analog-stereo"

export LANG=C
export PULSE_SERVER="unix:/run/user/$USER_ID/pulse/native"

function pactl_cmd() {
  sudo -u $USER_NAME pactl --server $PULSE_SERVER $*
}

if [ "$HDMI_STATUS" = "connected" ]; then
  CARD=$HDMI_CARD
  OUTPUT=$HDMI_PROFILE
else
  CARD=$INTERNAL_CARD
  OUTPUT=$INTERNAL_PROFILE
fi

pactl_cmd set-default-sink alsa_output.$CARD.$OUTPUT
pactl_cmd set-card-profile alsa_card.$CARD output:$OUTPUT

INPUTS=($(pactl_cmd list sink-inputs | grep "^Sink Input #"|cut -d# -f2))
for i in ${INPUTS[*]}; do
  pactl_cmd move-sink-input $i alsa_output.$CARD.$OUTPUT
done

A essência relacionada está aqui .

Treviño
fonte
Eu tinha um script semelhante que funcionava usando, card0mas um dia ele mudou para, card1então eu mudei o script e, no dia seguinte, mudei novamente para card0. No final, mudei o código para card*e está tudo bem desde então. Apenas um alerta se algo semelhante acontecer com você.
WinEunuuchs2Unix 8/17/17
0

Os scripts do Udev são executados como raiz, mas você também precisa saber qual gerenciador de exibição está usando. Esses scripts devem funcionar, mas você deve autorizar o gerenciador de exibição a fazê-lo.

Encontre o DM que você está usando:

pgrep -a Xorg

Veja a opção -auth, ela mostrará o gerenciador de exibição. Pode ser sddm ou lightdm nos últimos lançamentos do Ubuntu.

Esta linha deve ser exportada como variável XAUTHORITY, assim:

ls /car/run/sddm*

por exemplo, isso poderia ser uma saída válida:

/var/lib/mdm/{.Xauth (Isso será usado pelo script)

É assim que seu script deve ficar:

#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=`ls /var/run/sddm*`
HDMI_STATUS="$(cat /sys/class/drm/card0-HDMI-A-1/status)"
USER=`whoami`
export XAUTHORITY=/home/$USER/.Xauthority
export DISPLAY=:0

if [ "$HDMI_STATUS" = connected ];
then
    sudo -u $USER pactl set-card-profile 0 output:hdmi-stereo+input:analog-stereo
else
    sudo -u $USER pactl set-card-profile 0 output:analog-stereo+input:analog-stereo
fi
exit 0

Isso permitirá que o seu gerente de exibição altere a saída HDMI. Siga as instruções para criar os arquivos de regras do udev e tornar o script executável.

LinuxHelper
fonte