Alterne entre alto-falantes internos e HDMI automaticamente

17

Você sabe como quando conecta fones de ouvido na entrada auxiliar do seu laptop, os alto-falantes internos são automaticamente silenciados e os sons saem dos fones de ouvido? Eu quero exatamente isso para HDMI.

Eu conecto um monitor com alto-falantes internos ao meu laptop para assistir a vídeos, às vezes. É muito estranho quando o vídeo está no monitor (que é colocado a 3 m de distância da minha mesa), mas o som sai dos alto-falantes internos do meu laptop (o laptop fica na mesa).

Claro, posso ir para as configurações de som e mudar o canal de saída para HDMI. Mas depois, quando removi o cabo HDMI horas atrás e pode até estar em um local totalmente diferente, o som não será reproduzido porque o servidor de som ainda tenta reproduzi-lo via HDMI, mas não há nada conectado a ele .

Voltar automaticamente para os alto-falantes internos quando nenhum dispositivo estiver conectado via HDMI é mais importante, mas mudar para saída de som via HDMI quando um dispositivo está conectado ainda seria muito bom.

Isso aparentemente funcionou com 11.10 mas não funciona com 16.04.

    
por UTF-8 27.11.2016 / 00:54

1 resposta

6

Antecedentes

Eu tive um problema semelhante durante a suspensão / retomada quando o som mudava da TV HDMI para os alto-falantes do laptop. Ao retomar o som ficaria em alto-falantes do laptop e eu teria que redefinir manualmente o dispositivo de saída para TV em System Settings - > Sound .

Esta foi uma das minhas primeiras experiências irritantes com a atualização do Ubuntu 14.04 para 16.04 e a raiz foi a atualização para o PulseAudio 8 que vem com 16.04 LTS

Depois de muita pesquisa, criei um script chamado TV-sound . Embora eu não conecte e desconecte a TV como você, fiz algumas pesquisas no google e criei uma variação do script para trabalhar na sua situação. Eu testei e funciona.

Etapa 1: crie um script para alternar o áudio entre dispositivos conectados

Vamos criar um script chamado hotplugtv , que o udev chama. Este mesmo script pode ser chamado em muitos lugares embora. Por exemplo, durante o teste, usei-o em lock-screen-timer , quando o som foi revertido para o Laptop durante o bloqueio de tela.

cd /usr/local/bin
sudo touch hotplugtv
sudo chmod +x hotplugtv
gksu gedit hotplugtv

Quando o editor abrir com uma tela em branco, copie e cole o seguinte:

#! /bin/bash

# NAME: hotplugtv
# PATH: /usr/local/bin
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: called from /etc/udev/rules.d/99-monitor-hotplug.rules
# 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.

if [[ $(cat /sys/class/drm/card*-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
#        log-file "HDMI TV connected" ~/bin/log-hotplugtv;
        /bin/sleep 2;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
else
#        log-file "HDMI TV disconnected" ~/bin/log-hotplugtv;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
fi

exit 0

Você precisará substituir as duas ocorrências de rick pelo seu próprio ID de usuário, ou seja, UTF-8 , etc.

Eu sei que isso pode ser mais profissional com o nome de usuário automaticamente definido para uma variável bash, mas eu não sou tão habilidoso ainda :( Enfim, salve o arquivo e saia do gedit .

Etapa 2: criar regras do udev

O udev monitora eventos do hotplug quando você conecta e desconecta seu monitor HDMI. Digite o seguinte para criar uma nova regra.

cd /etc/udev/rules.d
sudo cp 70-persistent-net.rules 99-hotplugtv.rules
gksu gedit 99-hotplugtv.rules

NOTA: Se o arquivo 70-persistent-net.rules não existir em seu diretório, copie qualquer outro arquivo lá. Nós não precisamos do conteúdo do arquivo, apenas as permissões de arquivo para garantir que as nossas são as mesmas.

O editor mostrará um monte de texto irrelevante, destaque-o e exclua-o. Em seguida, destaque o código abaixo e cole-o no editor:

# NAME: 99-hotplugtv.rules
# PATH: /etc/udev/rules.d
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: automatically called on system events
# DATE: Created Nov 26, 2016.
# NOTE: in future may requre systemd service hooks

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

Salve o arquivo e saia.

Para ativar a regra (sem reinicializar), precisamos recarregar o udev:

sudo udevadm control --reload-rules

Agora você pode conectar e desconectar seu monitor / TV HDMI e o som muda apropriadamente.

Advertência

No meu sistema, o som reverte automaticamente para os alto-falantes do laptop quando o HDMI é desconectado. No seu sistema isso não aconteceu. Outras melhorias no código podem ser necessárias se o som não for para os alto-falantes do laptop quando o HDMI estiver desconectado. Por favor, responda via comentário abaixo como as coisas funcionam / não funcionam.

Teste rápido no CLI

Você pode testar rapidamente o código no terminal usando:

    export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
  • Mude para HDMI / TV:

        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
    
  • Mude de volta para os alto-falantes incorporados:

        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
    
  • Lembre-se de substituir rick pelo seu nome de usuário.

  • A linha inicial export provavelmente não é necessária, mas incluímos apenas para garantir.
  • Se você tem várias placas de som, ou algo diferente de hdmi-stereo tweaks são obviamente necessários para descobrir os parâmetros corretos antes de escrever seu script.

Decifrando o nome do seu dispositivo no PulseAudio

O código abaixo usa o mesmo comando duas vezes. Uma vez quando o som está definido para HDMI TV externo. Uma segunda vez quando o som é definido para alto-falantes embutidos do laptop. Sempre que você vir o nome que o PulseAudio usa:

$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 28
    name: <alsa_output.pci-0000_00_1b.0.hdmi-stereo>
───────────────────────────────────────────────────────────────────────────────
$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 30
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>

Quando você tem várias placas de som

Use o comando aplay -l para ver se você tem cartões maiores que o número 0. Se for o caso, você precisará usar o número do cartão apropriado em seus scripts. Por exemplo:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: 92HD91BXX Analog [92HD91BXX Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

No exemplo acima, todos os números de cartões são 0 com diferentes origens de saída. Se você tiver alto-falantes USB, eles podem ter um número de cartão diferente de 0.

Editar 2 de dezembro de 2016

Por alguma razão desconhecida, o roteiro foi quebrado hoje. Acima do código usado para ler: "$ (cat / sys / class / drm / card0-HDMI-A-1 / status", mas eu tive que mudar card0 para card1 e o código acima foi revisado como tal. não posso explicar o que mudou no meu sistema além das atualizações regulares do Ubuntu desde 26 de novembro de 2016.

Editar 14 de dezembro de 2016

O código acima precisava ser alternado novamente para: "$ (cat / sys / class / drm / card0-HDMI-A-1 / status". Em vez de revisar o código entre card0 e card1 dependendo da inicialização , revise o programa para fazer referência a card* para capturar ambos os cenários.

    
por WinEunuuchs2Unix 27.11.2016 / 03:34