Skip to content

Repository files navigation

EFIR — Player Client

Клиент-плеер для цифровых экранов (digital signage) на Flutter. Устройство один раз настраивается, отправляет заявку на регистрацию, после подтверждения в панели играет контент по расписанию с сервера.

Сопутствующие документы: TODO_Client.md — статус до production, ROADMAP.md — развитие, deploy/DEPLOY.md — установка на устройства.

Возможности

  • Kiosk/fullscreen: в release-сборке экран нельзя случайно свернуть; wakelock, immersive-режим на Android.
  • Оффлайн-устойчивость: локальный кэш медиа (sha256-проверка), кэш манифеста, аварийный резервный плейлист.
  • Хранилище на выбор: внутренняя память / флешка / диск; авто-откат на внутреннюю при извлечении носителя и авто-возврат, контроль медленного носителя.
  • Сервисная зона (за жестом + опц. PIN): таймлайн «Что дальше» с превью, резервный режим, настройки, диагностика.
  • Авто-подбор адреса сервера: оператор вводит только хост — протокол (https→http) и порт клиент определяет сам.
  • Диагностика: экран состояния (сервер, heartbeat, ревизия, кэш, носитель, версии) + телеметрия в heartbeat.

Установка на устройство

Готовые сборки — в GitHub Releases (собираются CI по тегу vX.Y.Z, версия артефактов берётся из тега):

Платформа Артефакт Установка
Windows *-setup.exe (Inno Setup) Запустить установщик; VC++ Runtime подтянется автоматически. Автозапуск/watchdog: deploy/windows/install-watchdog.ps1
Linux *_linux_amd64.tar.gz Распаковать, sudo ./install.sh <user>; systemd-сервис: deploy/linux/install-service.sh (автозапуск + restart-after-crash)
Android / Android TV *.apk Установить APK (минимум Android 6.0 / API 23)

Подробности (автологин kiosk-пользователя, управление сервисом) — в deploy/DEPLOY.md.

Первый запуск

  1. На экране настройки ввести адрес сервера — достаточно хоста (panel.example.com или 192.168.1.50): протокол и стандартный порт клиент подберёт сам (https → http, явный порт — как указан). /api/... дописывать не нужно.
  2. «Проверить соединение» → «Отправить заявку».
  3. Подтвердить устройство в панели управления («Экраны → Заявки»). Device-token выдаётся один раз; если токен уже был выдан — просто отправить новую заявку.
  4. Плеер начнёт синхронизацию автоматически. Имя устройства задаётся при заявке и далее меняется только из панели.

Дополнительно на экране настройки: выбор места хранения контента (внутренняя память/носитель), целевой дисплей и поворот, сервисный PIN (пустой = вход в сервисную зону без PIN).

Сервисная зона (на устройстве)

Вход из плеера:

  • Desktop: 3× Esc подряд (или F2);
  • Android/TV-пульт: 5× Back подряд или кнопка Menu;
  • Тач-экран: 5 быстрых тапов.

Если задан PIN — будет запрошен. Редактор и PIN-диалог сами закрываются через 30 с бездействия. F12 — debug-overlay поверх плеера.

Внутри: таймлайн «Что дальше», переключатель аварийного оффлайн-режима с локальным плейлистом, ⚙️ настройки (сервер/хранилище/дисплей/PIN), диагностика устройства.

Локальные файлы

Documents/efir/
├── config.json     # server_url, media_root, дисплей, PIN
├── device.json     # device_id + token (chmod 600 на Unix)
├── manifest.json   # кэш манифеста для оффлайн-старта
├── log.txt         # ротация: 5 МБ × 3 файла
└── media/          # кэш контента (если не выбран внешний носитель)

Как работает клиент

POST /device/register/request → approve в панели → GET /device/register/status (одноразовый token) → далее цикл: GET /device/manifest (полл с backoff), POST /device/heartbeat (25 с, телеметрия), GET /device/media/{id} (Bearer, sha256-валидация, докачка через .download). Напрямую в MinIO/S3 клиент не ходит. При 401/403/404 — сброс регистрации и возврат в настройку.

Сборка из исходников

Требования: Flutter 3.44 (stable).

Платформа Что нужно дополнительно
Windows Visual Studio с рабочей нагрузкой «Разработка классических приложений на C++». Сборка WebView-плагина тянет NuGet-пакеты (Microsoft.Web.WebView2, WIL), поэтому нужен доступ в интернет.
Linux libmpv-dev, libwebkit2gtk-4.1-dev
Android

HTML-страницам нужен WebView. На Windows это рантайм WebView2: в Windows 10/11 он обычно уже стоит, а установщик клиента доставит его сам, если нет. На Linux — пакет libwebkit2gtk-4.1-0 (в Debian/Ubuntu ставится вместе с -dev). Без них клиент работает, но HTML-слоты пропускаются с записью в лог: видео, картинки и плейлисты не затрагиваются.

flutter pub get
flutter build windows --release   # или: flutter build linux --release / flutter build apk --release

Релиз: создать тег vX.Y.Z и запушить — GitHub Actions соберёт Windows-инсталлятор, Linux tar.gz и APK (для APK нужны секреты подписи, см. android/key.properties.example).

Локальная release-сборка APK требует android/key.properties с release-keystore — без него сборка падает (fallback на debug-подпись убран сознательно: debug-подписанный «релиз» нельзя распространять и обновлять поверх).

Обновление через панель

Панель раздаёт сборки экранам, но доверенной стороной не является: артефакт подписывается Ed25519-ключом, приватная половина которого живёт офлайн и в секретах CI, а публичная вшита в клиент. Компрометация сервера не даёт разлить на экраны посторонний бинарь — подпись не сойдётся, и клиент откажется ставить.

python tools/sign_release.py --generate-key   # один раз
  • приватный ключ → секрет репозитория UPDATE_SIGNING_KEY_BASE64 и офлайн-бэкап;
  • публичный → переменная репозитория EFIR_UPDATE_PUBLIC_KEY (вшивается в сборку через --dart-define) и CLIENT_UPDATE_PUBLIC_KEY в .env сервера.

Без EFIR_UPDATE_PUBLIC_KEY сборка выходит с отключёнными обновлениями (fail-closed): лучше не обновляться, чем поставить непроверенный бинарь. Потеря приватного ключа = невозможность выпускать обновления для уже установленных клиентов: сменить вшитый ключ можно только сборкой, установленной вручную.

Релизный workflow кладёт в GitHub Release SIGNATURES.txt (файл sha256 подпись) — подпись оттуда вставляется в панель при загрузке сборки.

Установка обновления по платформам

Платформа Как ставится Условие автоматической установки
Android / Android TV PackageInstaller молча — только если приложение Device Owner; иначе система требует подтверждения, и панель показывает ready

| Windows | тихий запуск Inno-инсталлятора | всегда: клиент ставится в профиль пользователя, поэтому UAC не всплывает | | Linux | распаковка новой версии + перестановка симлинка current | всегда: каталог принадлежит пользователю сервиса, root не нужен |

Device Owner на Android включается только на свежесброшенном устройстве без добавленных аккаунтов и задним числом не назначается:

adb shell dpm set-device-owner com.efir.client/.EfirDeviceAdminReceiver
# Пайп в кавычках — чтобы grep выполнялся на устройстве, а не в хостовой
# оболочке (в PowerShell его просто нет).
adb shell "dumpsys device_policy | grep -i owner"

Ни на одной платформе обновление не поднимает привилегии. Схема «root-хелпер, которому процесс пользователя говорит, что выполнить» отвергнута сознательно: это готовое локальное повышение привилегий, а закрыть его нечем без сертификата подписи кода. Вместо этого каталог установки принадлежит тому же пользователю, что и приложение.

Linux: /opt/efir-client/versions/<версия> + симлинк current, на который смотрит ExecStart. Обновление распаковывает версию рядом и переставляет симлинк (атомарно, через rename), после чего клиент завершается, а Restart=always поднимает уже новую сборку. Предыдущая версия остаётся на диске — откат делается перестановкой симлинка.

Windows ставится в профиль пользователя, а не в Program Files — иначе каждое обновление упиралось бы в UAC, а на экране, к которому никто не подходит, диалог UAC означает, что обновления нет. Права администратора нужны один раз и только если в системе отсутствует Visual C++ Runtime (мастер об этом скажет).

Архитектура (кратко)

lib/controllers/playlist_controller.dart — состояние устройства: регистрация, манифест-полл, heartbeat, кэш, хранилище. lib/views/ — плеер (двойной видеоплеер media_kit/mpv для бесшовных переходов), экран настройки, сервисный редактор, диагностика. lib/services/ — API, кэш медиа, конфиг, хранилище, логи. Планы — ROADMAP.md.

About

📱 EFIR Client — плеер цифровых экранов на Flutter: kiosk, офлайн-кэш, авто-настройка (Windows/Linux/Android TV)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages