Como pausar a reprodução do VLC quando os fones de ouvido estão desconectados?

12

Como é possível pausar a reprodução do VLC quando meus fones de ouvido estão conectados? Posso silenciar os alto-falantes via ALSA, mas quero usar o gatilho para interromper a reprodução, como é habitual em smartphones.

HerHde
fonte
1
Aviso: a segunda resposta é muito mais eficiente no momento da escrita: askubuntu.com/a/642898/20275
int_ua

Respostas:

5

Ok, então, com base no que aprendi aqui , estou tentando uma nova abordagem, usando a ACPI.

  1. Crie um script para pausar e não pausar o VLC:

    sudo touch /etc/acpi/headphone_jack.sh
    sudo chmod +x /etc/acpi/headphone_jack.sh
    

    e coloque o seguinte neste arquivo:

    _pid=`pgrep vlc`
    _pid="${_pid% *}"
    DBUS_SESSION_BUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/$_pid/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//'`
    _username=`grep -z USER= /proc/$_pid/environ |sed 's/.*=//'`
    
    if [ "$3" = unplug ]; then
        su $_username -c "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause"
    else
        su $_username -c "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play"
    fi
    
  2. Agora vamos criar um gatilho de evento (substitua vimpelo seu editor de texto favorito):

    sudo vim /etc/acpi/events/headphones
    

    e adicione o seguinte:

    event=jack/headphone
    action=/etc/acpi/headphone_jack.sh %e
    
  3. Por fim, reinicie o daemon ACPI:

    sudo service acpid restart
    

Eu acho que deve ser exatamente o que você precisa, sem nenhuma pesquisa envolvida. A única desvantagem que posso encontrar com essa implementação é se você tiver vários usuários executando o VLC ao mesmo tempo. Suponho que, nesse caso, o que pode acontecer é que essa abordagem faça uma pausa aleatória e reinicie uma delas (ou ela pode simplesmente não funcionar).

Muitos elogios para @int_ua e @Sneetsher por me fornecerem conhecimentos importantes sobre o tratamento de eventos da ACPI. Também gostei de @ user3073656 por ajudar a simplificar o procedimento.

Acrobacias
fonte
1
Para executar qualquer comando que precise do DBUS, você deve exportar a variável de ambiente da sessão do dbus em execução. Veja o comentário de Germar na resposta de Sneetsher.
daltonfury42
1
Bem manchado. Aqui está a maneira mais limpa que eu poderia pensar em fazer isso. Não há necessidade de scripts de inicialização automática e outros enfeites.
Duplos
@ Acrobacias, essa é a melhor abordagem que eu já vi para obter o ENV alvo. É possível obter o usuário da mesma maneira, grep -z USER /proc/$_pid/environpara que funcione para todos os usuários na máquina (com uma única sessão em execução / vlc). Eu estava procurando por essa opção.
user.dz
@Sneetsher: Doce! Parece muito melhor agora. Passou pela minha cabeça na noite passada, mas eu estava cansada demais na noite passada para pensar claramente. Obrigado pelo empurrão nessa direção.
Stunts
1
Você ainda pode melhorar a resposta usando% e e usando apenas um único arquivo de script. Veja isso .
precisa saber é o seguinte
9

Ok, então você precisará fazer algumas coisas para isso:

  1. Detecte quando os fones de ouvido estão desconectados;
  2. Após o evento em (1), envie um comando "pause" para o VLC;
  3. Detecte quando os fones de ouvido são reconectados;
  4. Após o evento em (3), envie um comando "play" para o VLC;

Para (1) e (3): você pode usar o que é mostrado aqui . Esta resposta contém um pequeno procedimento para encontrar a diferença entre uma tomada conectada e uma desconectada e um script que você pode modificar para se adequar ao seu caso.

Para (2) e (4): você deve usar a interface Dbus do VLC. O código relevante deve ser o seguinte:

dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause

dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play

Para pausar e reproduzir, respectivamente.

Agora, sobre o script. No seu caso, deve ser algo como isto:

#!/bin/bash
# This scripts detecs unplugging headphones.

oldstatus="unrelated string"
while [ 1 ]; do
    # The following line has to be changed depending on the difference (use diff) in '/proc/asound/card0/code#0'
    status=$(grep -A 4 'Node 0x16' '/proc/asound/card0/codec#0' |  grep 'Amp-Out vals:  \[0x80 0x80\]')
    if [ "$status" != "$oldstatus" ]; then
        if [ -n "$status" ]; then
            echo "Plugged in"
             dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play
            oldstatus="$status"
        else
            echo "Unplugged"
            dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause
            oldstatus="$status"
        fi
    fi
    # Now sleep for 250 milli-seconds as per @Serg's request (who learnt if from @Fabby)
    # sleep is timer-based so doesn't use *any* processor cycles while sleeping.
    sleep 0.25
done

Adicione esse script modificado aos aplicativos de inicialização e pronto. Eu acho que deveria fazer o que você queria.

PS - Observe que existem maneiras mais eficientes de fazer isso, como usar inotifypara detectar alterações de eventos (e talvez até outras abordagens), mas essa deve ajudá-lo a começar (e as outras estão acima do meu nível de habilidade e experiência). Suponho que você possa começar com essa abordagem "hackish" e desenvolver a partir daqui.

Acrobacias
fonte
1
Muito obrigado, isso é realmente útil. Recompensarei os pontos caso nenhuma resposta melhor seja publicada. A única coisa que eu não gosto é o polling constante, eu criei uma questão separada para isso: askubuntu.com/questions/640741/...
int_ua
1
Eu vou seguir essa pergunta! Eu poderia usar esse conhecimento.
Stunts
3
Você pode adicionar um sleep 0.25no final, que é um atraso de quarto de segundo. Isso facilita a CPU e ainda funciona rápido o suficiente. Eu uso este, por vezes, em meus próprios scripts, também
Sergiy Kolodyazhnyy
2
A ACPI lida com fones de ouvido, você adicionará isso à sua resposta? askubuntu.com/a/642404/20275
int_ua
Impressionante! Eu vou trabalhar algo com isso hoje à noite.
Acrobacias