Commit Graph

13 Commits

Author SHA1 Message Date
nk
6eb614a729 fix(player): не глохнуть в фоне (wake mode) + авто-переподключение потока
Симптом: по Bluetooth в машине с выключенным экраном радио через время замолкало.
Причины и фиксы:
- setWakeMode(C.WAKE_MODE_NETWORK) + право WAKE_LOCK — ExoPlayer держит partial
  wakelock + wifilock во время игры. Без этого система усыпляла CPU/Wi-Fi при
  выключенном экране → буфер пустел → поток глох (главная причина).
- onPlayerError → scheduleReconnect(): при обрыве сети (туннели, край соты) поток
  пере-готавливается с нарастающей задержкой (2с→15с, до 10 попыток), а не
  замолкает навсегда. Счётчик сбрасывается при успешном старте; переподключение
  отменяется при ручной паузе/стопе/смене станции.
2026-06-07 12:35:07 +03:00
nk
e736c2393f feat(eq): настоящий эквалайзер + улучшайзеры звука (audiofx)
Раньше пресет эквалайзера в настройках был косметикой (лежал в DataStore, к звуку
не подключён). Теперь — реальные системные эффекты на фикс. аудиосессии плеера:
- AudioEffectsController: графический Equalizer (полосы устройства), BassBoost,
  Virtualizer (объём), LoudnessEnhancer (громкость тихих, до +12 дБ). Привязка к
  generateAudioSessionId() в PlayerController, переживает смену станций. Применение
  в реальном времени, сохранение в DataStore (commit на отпускании слайдера).
- Отдельный экран EqualizerScreen (Настройки → ЗВУК → Эквалайзер): тумблер,
  системные пресеты + «Свой», слайдеры полос (±дБ), bass/virtualizer/loudness.
- Эффекты best-effort: при отсутствии поддержки блок недоступен (null), UI скрывает.
- Убран фейковый чип-пресет Flat/Rock/Pop/Jazz/Bass.
2026-06-06 21:14:38 +03:00
nk
d9acc0efb4 fix(sleep): звук сна вплывает в конце таймера, а не в первые 90 секунд
Было: при таймере со звуком радио кроссфейдилось в шум в НАЧАЛЕ (CROSSFADE_MS=90с),
и для 15-мин таймера уже через ~1.5 мин играл полный белый шум всё оставшееся время.

Стало: радио играет почти весь таймер; в последние SOUND_OUTRO_MS (3 мин, но не
больше половины таймера) включается звук сна — радио кроссфейдится в шум, шум держится,
в самом конце затухает в тишину. Генератор шума стартует лениво (только в аутро, не
молотит весь таймер). Засыпаешь под радио, а не под резкий шум сразу.
2026-06-06 18:21:04 +03:00
nk
f423344d13 perf(android): батарея и плавность — gate FFT, изоляция рекомпозиции, поллинг на паузе
- AudioSpectrumAnalyzer: FFT считается ТОЛЬКО когда открыт плеер (флаг active);
  раньше ~86 FFT/с молотили всегда при проигрывании (даже экран выкл) — главный
  пожиратель батареи. Включается из VisualizerHost через DisposableEffect.
- Спектр (45/с) собирается в leaf VisualizerHost, а не на верху PlayerBottomSheet —
  весь плеер больше не рекомпозится 45 раз/сек.
- now-playing поллинг (5с) останавливается на паузе (isPlaying.collectLatest) —
  раньше на паузе зря дёргали сеть каждые 5с.
- PlayerService.onDestroy отменяет serviceScope (singleton-плеер НЕ релизим).
- refreshStations (парс ~700 станций + сеть + Room) уведён на Dispatchers.IO с
  главного потока (jank/ANR на старте).
- Coil ImageLoader: память 25% + диск 100МБ (обложки не перекачиваются каждую сессию).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:33:00 +03:00
nk
861b0e2b8f feat: будильник с радиостанцией + выбор битрейта по умолчанию
Будильник (Settings → Будильник): несколько будильников, время, станция, дни недели,
fade-in пробуждения. AlarmManager.setAlarmClock (вне doze) + фолбэк, BootReceiver
перепланирует после перезагрузки, AlarmReceiver→PlayerService (foreground) →
PlayerController.startAlarmPlayback (нарастание громкости). Room: AlarmEntity/Dao, БД v7.
Выбор битрейта по умолчанию в Settings (Авто/Эконом/Стандарт/Высокое) → preferredBitrate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:25:42 +03:00
nk
4411d53a6c feat(player): звуки для сна (белый/розовый/коричневый шум) + Smart Sleep Fade
SleepSoundPlayer — процедурная генерация цветного шума через AudioTrack (розовый —
фильтр Келлета, коричневый — random walk). В таймере сна выбор звука: радио плавно
перетекает в выбранный шум (кроссфейд ≤90с), шум играет, к концу затухает — как в
спеке («Smart Sleep Fade»). В шторке таймера — чипы выбора звука.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:08:32 +03:00
nk
bda2c5b30f feat(player): таймер сна с плавным затуханием (fade-out)
P0-фича из спеки. PlayerController: startSleepTimer/cancelSleepTimer — в последние
20с экспоненциальный fade-out громкости (frac^2), затем пауза + возврат громкости.
В плеере — пилюля «Таймер сна» (иконка Moon): при активном показывает остаток
M:SS акцентом. Шторка с интервалами 15/30/45/60/90/120 мин + «Выключить».

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 10:08:54 +03:00
nk
05e5538945 feat(player): живой эквалайзер по реальному звуку (FFT-спектр)
Эквалайзер на плеере больше не декоративная синус-волна — реагирует на
реальный звук. Через TeeAudioProcessor подключаемся к декодированному PCM в
аудио-конвейере ExoPlayer (без разрешений/микрофона), считаем FFT → лог-полосы
(AudioSpectrumAnalyzer), PlayerController отдаёт спектр StateFlow'ом, LiveEqualizer
рисует столбики по уровням (с быстрым ростом/плавным спадом). Когда звука нет
(пауза/float-выход) — фолбэк на прежнюю синус-волну.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:39:09 +03:00
nk
4612a8f33c fix(player): следовать кросс-протокольным редиректам (http→https)
Многие станции отдают по http 301 на https; ExoPlayer по умолчанию не идёт
по кросс-протокольному редиректу и не играет их. Включён общий HTTP-источник
с setAllowCrossProtocolRedirects(true) — такие станции заиграют без правки URL.
ICY-метаданные сохраняются (обрабатываются на уровне ProgressiveMediaSource).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:42:43 +03:00
nk
9268e14cc6 feat(stations): свайп по списку листает чипы + свечение играющей станции
1) Горизонтальный свайп по области списка переключает фильтры-чипы в их
   порядке ([Все]+жанры), выбранный чип автоскроллится в зону видимости.
   Вертикальная прокрутка грида сохраняется.

2) У играющей станции в списке — мягкое радиальное свечение позади обложки,
   которое «гуляет» (двигается центр) и вылезает из-под краёв, + эквалайзер-
   бейдж в углу. Источник активной станции — PlayerController.currentStationId.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 14:12:01 +03:00
nk
5ffaf9a924 feat(player): переключатель качества звука на экране воспроизведения
Перепроверены все 594 рабочие станции на наличие битрейт-вариантов
потока (скрипт-пробер). У 71 станции найдено по 2–4 качества
(Record-флагманы 96/64/32, zaycev 256/128/48, ВГТРК 192/128/64,
НАШЕ/Орфей/Шансон HQ и др.) — записаны в поле qualities в stations.json.
HLS (EMG) и Love (UID-привязка) корректно пропущены.

Клиент: модель StreamQuality, хранение в Room (миграция v5),
предпочтение битрейта в настройках. На экране плеера — чип текущего
качества (виден только если вариантов ≥2) и шторка «Качество звука»
со ступенями; переключение на лету без сброса now-playing, выбор
запоминается между станциями.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 12:36:47 +03:00
nk
a83672b455 feat: auth screen with auto-redirect, sync favorites/history with backend 2026-06-02 19:12:07 +03:00
nk
cf79af5273 feat(service): add ExoPlayer controller and MediaSessionService 2026-06-01 12:21:22 +03:00