Як призупинити відтворення VLC, коли відключені навушники?


12

Як можна призупинити відтворення VLC, коли мої навушники підключені? Я можу вимкнути динаміки через ALSA, але хочу скористатися плагінним пусковим механізмом, щоб зупинити відтворення, як це зазвичай у смартфонах.


1
Зауважте: друга відповідь набагато ефективніша під час написання: askubuntu.com/a/642898/20275
int_ua

Відповіді:


5

Добре, тому на основі того, що я звідси навчився , я намагаюся новий підхід, використовуючи ACPI.

  1. Створіть сценарій для призупинення та відключення VLC:

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

    і розмістіть у цьому файлі таке:

    _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. Тепер створимо тригер події (замінимо vimулюбленим текстовим редактором):

    sudo vim /etc/acpi/events/headphones
    

    і додайте наступне:

    event=jack/headphone
    action=/etc/acpi/headphone_jack.sh %e
    
  3. Нарешті, перезапустіть демон ACPI:

    sudo service acpid restart
    

Я думаю, що має бути саме те, що потрібно, без участі в опитуваннях. Єдиний недолік, який я можу знайти при цій реалізації, - якщо у вас є кілька користувачів, які працюють VLC одночасно. Я припускаю, що в цьому випадку може статися те, що такий підхід випадково призупинить і відновить одну з них (або може просто не працювати).

Великі кудо для @int_ua та @Sneetsher за надання мені важливих знань щодо обробки подій ACPI. Також великі пальці розміром до @ user3073656, щоб допомогти спростити процедуру.


1
щоб запустити будь-яку команду, яка потребує DBUS, вам потрібно експортувати змінну оточуючого середовища сеансу dbus. Дивіться коментар Гермара щодо відповіді Снішера.
daltonfury42

1
Добре помічений. Ось найчистіший спосіб, який я міг би придумати, щоб зробити це. Немає необхідності в сценаріях автоматичного запуску і тому подібному.
Трюки

@Stunts, це найкращий підхід, який я бачив, щоб отримати цільовий ENV. Отримати користувача можна однаково, grep -z USER /proc/$_pid/environтому він буде працювати для всіх користувачів машини (з одним запущеним сеансом / vlc). Я шукав такий варіант.
user.dz

@Sneetsher: Солодке! Зараз виглядає набагато краще. Це минуло ввечері перейшло в голову, але я був занадто втомився вчора ввечері, щоб чітко подумати про це. Дякуємо за поштовх у цьому напрямку.
Трюки

1
Ви все ще можете вдосконалити відповідь, використовуючи% e та використовуючи лише один файл сценарію. Дивіться це .
daltonfury42

9

Гаразд, для цього вам потрібно буде виконати кілька речей:

  1. Виявити, коли навушники відключені;
  2. Після події в (1) надішліть команду "пауза" у VLC;
  3. Виявити, коли навушники підключені назад;
  4. Після події в (3) надішліть команду "play" на VLC;

Для (1) і (3): Ви можете використовувати те, що тут показано . Ця відповідь містить невелику процедуру пошуку різниці між підключеним та відключеним гніздом та сценарієм, який ви можете змінити, щоб відповідати вашому випадку.

Для (2) і (4): Вам слід використовувати інтерфейс Dbus VLC. Відповідний код повинен бути таким:

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

Для пауз та гри відповідно.

Тепер про сценарій. У вашому випадку це має виглядати приблизно так:

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

Додайте цей модифікований сценарій до запуску програм, і ви налаштовані Я думаю, це має робити те, що ти хотів.

PS - Зауважте, що є більш ефективні способи зробити це, наприклад, використовувати inotifyдля виявлення змін подій (і, можливо, навіть інші підходи), але саме з цього слід почати (а інші вище рівня мого майстерності та досвіду). Я припускаю, що ви можете почати з цього "хакітського" підходу і будувати звідси.


1
Велике спасибі, це справді корисно. Я наберу бали, якщо кращої відповіді не буде розміщено. Єдине, що мені не подобається - це постійні опитування, я створив для цього окреме питання: askubuntu.com/questions/640741/…
int_ua

1
Я піду за цим питанням! Я міг би використати ці знання.
Трюки

3
Ви можете додати а sleep 0.25в кінці, що становить чверть секунди. Це полегшує процесор і все ще працює досить швидко. Я інколи використовую це і в своїх власних сценаріях
Сергій Колодяжний,

2
ACPI відключає навушники, ви додасте це до своєї відповіді? askubuntu.com/a/642404/20275
int_ua

Дивовижно! Я щось сьогодні з цим попрацюю.
Трюки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.