LINUX.ORG.RU
ФорумTalks

Как в DeaDBeeF надёжно отследить статус воспроизведеия при запуске

 ,


0

0

cast @waker

Допиливаю по-немногу SNI-плагин. Более-менее всё починил, но возник один затык, который не могу придумать, как решить (туплю) - как гарантированно отследить статус плеера при его запуске.

В данный момент отслеживаются ссобщения DB_EV_PAUSED и DB_EV_SONGCHANGED (если to == NULL - это стоп, иначе - плей) и это замечательно работает в обычном режиме. Проблема заключается в том что:

  • StatusNotifier инициализируется независимо от плеера и может проинициализироваться в произвольное время при запуске (для этого есть ожидание в отдельном потоке callback_wait_notifier_register (здесь), пока просто активное ожидание playback-а)
  • определение состояния через
DB_output_t* out = deadbeef->get_output();
switch (out->state()) {
    ...
}

сопряжено с трудностями, т.к. StatusNotifier может загрузиться слишком рано и получается мусор в out->state() (мусор - частично решено функцией playback_state_active_waiting) или при вызове в момент загрузки трека (подгрузки coverart или ещё чего) получается DDB_PLAYBACK_STATUS_STOP, а сообщения о готовности трека не предусмотрено.

  • определение через таймер, как делаю сейчас, в принципе, работает хорошо (пока ещё код на уровне идеи, но работает), но тут возникает проблема, что при запуске порядок сообщений выглядит таким образом (лог при помощи моего простенького отладочного плагина)
[MSG (16:21:23.495064159)] DB_EV_SONGCHANGED (1000) <0x7ffae8000c20,0,0> | from: [(nil)], to: [0x14b7360], sec: [0.000]
[MSG (16:21:23.495077924)] DB_EV_SONGSTARTED (1001) <0x7ffae8000c50,0,0> | from: [0x14b7360]
[MSG (16:21:23.495086305)] DB_EV_PAUSED (14) <(nil),1,0> | сhange: [paused]
[MSG (16:21:23.495123667)] DB_EV_CONFIGCHANGED (11) <(nil),0,0>
[MSG (16:21:23.497253534)] DB_EV_SONGCHANGED (1000) <0x7ffae8011e50,0,0> | from: [(nil)], to: [0x14b7360], sec: [0.000]
[MSG (16:21:23.497287863)] DB_EV_SONGSTARTED (1001) <0x7ffae8011e80,0,0> | from: [0x14b7360]
[MSG (16:21:23.497303655)] DB_EV_SEEKED (1005) <0x7ffae8011eb0,0,0> | from: [0x14b7360], position: [41.982]

т.е. сообщение DB_EV_SONGCHANGED приходит почему-то два раза (почему???) и после паузы тоже. Поэтому, по логике обработки сообщений, которая на данный момент используется, получается что после PAUSED пришло сразу сообщение SONGCHANGED и воспроизведение запущено.

Пока больше не могу придумать, как правильно при запуске notifier-а понять в каком состоянии его запускать, т.е. отследить в каком состоянии находится плеер на момент загрузки notifier-a (возможно, что воспроизведение уже запустили вручную, пока notifier грузился). Как я понимаю, в случае, например, больших coverart-ов состояние DDB_PLAYBACK_STATUS_STOP может продлиться довольно долго и условный sleep(какое-то время) не поможет.

Каким более правильным образом можете посоветовать решить проблему? Потому что у меня кроме как вариантов убрать, каким-то образом, второе сообщение SONGCHANGED на уровне ядра плеера или добавить какой-нибудь EVENT фактического старта воспроизведения / готовности трека (что решило бы все проблемы), опять же на уровне ядра плеера, не возникает.

ЗЫ. issue на github не создаю, потому что какбы и не баг, вроде бы, а просто мой тупизм и я что-то не понимаю.

★★★★★

Последнее исправление: SkyMaverick (всего исправлений: 4)

проблема описана достаточно сумбурно, поэтому не вполне понятно и как ее решать.

если нужно просто всегда иметь актуальное состояние плеера:

на старте получаем текущее состояние, и подписываемся на обработку событий

дальше реагируем на события, или опрашиваем по таймеру.

waker ★★★★★
()
Ответ на: комментарий от waker

Извиняюсь за сумбурный стиль написания, попробую описать короче. Как получить статус воспроизведения после загрузки

  • если output->state() может возвращать состояние DDB_PLAYBACK_STATUS_STOP неопределённое время (трек загружается, большой coverart прогружается)
  • если запустить плеер в состоянии паузы, то сообщение о старте трека DB_EV_SONGCHANGED и DB_EV_SONGSTARTED приходят и до (что, видимо, правильно) и сразу ПОСЛЕ сообщения DB_EV_PAUSED.

на старте получаем текущее состояние, и подписываемся на обработку событий

Я так и делаю. Если бы вот эти event-ы второй и третий снизу не прилетали ПОСЛЕ DB_EV_PAUSED то проблем бы и не было, но они почему-то прилетают. И получается, что, исходя из логики сообщений, если её правильно понял, что трек запущен после паузы, хотя сам плеер стоит на паузе.

Проблема возникла из-за того, что StatusNotifier может инициализироваться некоторое время (0,5-1,5 сек. обычно) и поэтом я его пустил отдельным потоком и уже когда он инициализировался, то получать статус. Вариант с обработкой сообщений, да понятный, удобный и он работает в общем случае, но вот эти два сообщение после DB_EV_PAUSED я не понял как правильно обработать.

SkyMaverick ★★★★★
() автор топика
Последнее исправление: SkyMaverick (всего исправлений: 2)
Ответ на: комментарий от SkyMaverick

насколько мне известно, в данный момент весь UI код получает статус только опросом текущего состояния по таймеру несколько раз в секунду. одними только событиями не получится обойтись.

waker ★★★★★
()
Ответ на: комментарий от waker

Ок, спасибо, понял. Попробую что-нибудь придумать по этому поводу. Видимо, делать регулярный периодический опрос таймером - это самый простой вариант решения проблемы.

SkyMaverick ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.