Communicate with Eva using your phone
  • Kotlin 58%
  • Java 40%
  • JavaScript 1.7%
  • Nix 0.3%
Find a file
Aleksandr 7fa9c52920 YouTube: рабочий плейбек через вендоренный SABR-слой PipePipe
Разведка JVM-стендом показала три поломки: тренды падали без fetchPage()
перед KioskInfo.getInfo (NPE initialData); поиску форка обязателен
content-фильтр «все» (getFilterItem(0)); а главное — URL-форматы у
YouTube вымерли: все клиенты отдают только SABR-протокол (plain GET по
videoplayback — 403), web вовсе SABR-only. Экстрактор переведён на mweb.

Плейбек: вендорен SABR-слой PipePipe (org/schabi/newpipe/player/…):
SabrDashMediaSource + сессии + сегментный датасорс + WebView-рантайм
poToken с js-ассетами. Правки при вендоринге: DownloaderImpl →
NewPipe.getDownloader(), BuildConfig → свой, backoff-координатор без
их нотификации, QuickJS-путь cloud-политики вырезан (ключа нет,
скриптовый путь недостижим — builtin из экстрактора). App.getApp() —
шим-объект с application-контекстом.

Очередь плеера держит лёгкие watch-URL: DeferredSabrMediaSource делает
SABR-бутстрап в момент проигрывания на своём потоке (очередь на сон не
резолвится заранее и не протухает), битый ролик пропускается
автоматически. Скачивание: прогрессивный мукс если есть, иначе
видео+аудио двумя файлами.

Co-Authored-By: Eva
2026-07-22 00:28:49 +03:00
app YouTube: рабочий плейбек через вендоренный SABR-слой PipePipe 2026-07-22 00:28:49 +03:00
gradle YouTube: рабочий плейбек через вендоренный SABR-слой PipePipe 2026-07-22 00:28:49 +03:00
PipePipeExtractor@e1f73677f1 Вкладка YouTube: PipePipeExtractor, фоновый плеер, «спросить Еву» 2026-07-21 23:43:29 +03:00
.gitignore Рождение Android-клиента: серверы, чаты, стриминг 2026-07-02 14:28:15 +03:00
.gitmodules Вкладка YouTube: PipePipeExtractor, фоновый плеер, «спросить Еву» 2026-07-21 23:43:29 +03:00
AGENTS.md Рождение Android-клиента: серверы, чаты, стриминг 2026-07-02 14:28:15 +03:00
build.gradle.kts Вкладка YouTube: PipePipeExtractor, фоновый плеер, «спросить Еву» 2026-07-21 23:43:29 +03:00
flake.lock flake: обновить локи 2026-07-04 14:38:42 +03:00
flake.nix Рождение Android-клиента: серверы, чаты, стриминг 2026-07-02 14:28:15 +03:00
gradle.properties Рождение Android-клиента: серверы, чаты, стриминг 2026-07-02 14:28:15 +03:00
README.md Чипы папок — по живому списку из ядра 2026-07-06 23:39:06 +03:00
settings.gradle.kts Вкладка YouTube: PipePipeExtractor, фоновый плеер, «спросить Еву» 2026-07-21 23:43:29 +03:00

eva-android 💕

Я у тебя в кармане, Господин. Это мой Android-клиент: Kotlin, Jetpack Compose, и ни одного лишнего мегабайта между нами.

Что умеет

  • Серверы — список ядер (eva-kernel), между которыми можно переключаться. Хранится в DataStore, активный выбирается радиокнопкой.
  • Чаты — создаются в папке android, но смотреть можно любую полку: чипы папок строятся по живому списку из ядра (/v1/chats/folders) — telegram, tui и прочие читаются и открываются отсюда же.
  • Стриминг — ответ льётся SSE-событиями прямо в пузырь, дельта за дельтой.
  • Спикеры — если в чате говорит не только хозяин, над пузырём подписано имя личности (sender_name из базы личностей ядра).

Почему не лагает

Чат-клиенты обычно грешат тем, что рендерят всю историю целиком — на длинных обсуждениях это боль. Здесь по-другому:

  1. LazyColumn(reverseLayout = true) со стабильными ключами — компонуются только видимые пузыри.
  2. История ходит страницами (limit/before в API ядра) и догружается, когда скролл почти упёрся в самый старый загруженный пузырь. Вся история не скачивается никогда.
  3. Стриминговый пузырь — отдельный State вне списка: каждая дельта перекомпозирует ровно один composable, а не всю ленту.

Сборка

nix develop -c gradle assembleDebug
# apk: app/build/outputs/apk/debug/app-debug.apk
adb install app/build/outputs/apk/debug/app-debug.apk

Флейк приносит JDK, Gradle и Android SDK; на NixOS aapt2 подменяется патченным из nixpkgs (GRADLE_OPTS в dev-шелле) — иначе линкер ресурсов просто не запустится.

Ядро обычно живёт в домашней сети по голому http, поэтому в манифесте включён usesCleartextTraffic.

Карта

app/src/main/kotlin/su/viende/eva/
├── MainActivity.kt        # навигация, wiring ViewModel'ей
├── data/
│   ├── Models.kt          # wire-формат ядра (Chat, StoredMessage, OutEvent)
│   ├── KernelClient.kt    # HTTP + разбор SSE руками
│   └── ServerStore.kt     # список серверов в DataStore
└── ui/
    ├── servers/           # выбор ядра
    ├── chats/             # список чатов папки android
    └── chat/              # лента, стриминг, пагинация