mirror of
https://github.com/deadcxap/P2S_OSD.git
synced 2026-07-02 05:43:41 +03:00
10 KiB
10 KiB
Проект: оверлей телеметрии Bambu Lab P2S поверх RTSP-потока
Цель
Собрать одно-контейнерное приложение, которое:
- получает видеопоток камеры принтера по
rtsps://...:322/streaming/live/1; - получает телеметрию/статус по MQTT (LAN-only + developer mode, совместимо с OpenBambuAPI);
- накладывает данные на видео в реальном времени;
- отдает готовый поток для OBS/go2rtc/другого ретранслятора;
- стабильно работает без GPU;
- имеет структурированные логи, healthcheck и устойчивость к пропаданию MQTT/RTSP.
Базовые требования (чек-лист)
- Один Docker-контейнер.
- Автозапуск пайплайна при старте контейнера (без ручных команд).
- Работа на CPU.
- Читаемые логи состояния и ошибок.
- Переживание обрывов MQTT и RTSP без падения процесса.
- HTTP-эндпоинт health/readiness для мониторинга.
- Возможность включить в контейнер сторонний проект (например, go2rtc), но в рамках одного контейнера.
Вариант 1 (рекомендуемый): Python orchestration + FFmpeg drawtext + встроенный RTSP-сервер (MediaMTX)
Идея
- Python-процесс:
- подписывается на MQTT, нормализует телеметрию;
- пишет текущий оверлей в текстовый файл (
/run/overlay.txt); - держит HTTP
/healthzи/readyz; - логирует состояние/ошибки (JSON-лог).
- FFmpeg-процесс:
- читает RTSP;
- накладывает
drawtext=textfile=/run/overlay.txt:reload=1; - публикует поток в локальный MediaMTX (
rtsp://127.0.0.1:8554/p2s_overlay).
- MediaMTX в том же контейнере раздает RTSP/RTMP/WebRTC (по необходимости).
Плюсы
- Минимум собственного низкоуровневого видео-кода.
- Устойчивость: FFmpeg и MQTT можно рестартовать независимо (через supervisor).
- Простое масштабирование форматирования оверлея.
Риски/минусы
drawtextограничен по сложной верстке (таблицы/иконки сложнее).- Нужно аккуратно синхронизировать обновление файла оверлея (atomic write).
План реализации
- Слой конфигурации
- ENV: IP принтера, пароль, MQTT-топики, формат выдачи, fps/битрейт.
- Сбор телеметрии
- MQTT client (paho-mqtt/asyncio-mqtt), reconnect с backoff.
- Парсер payload по схеме OpenBambuAPI.
- Модель состояния
- Единый
PrinterStateс timestamp последнего обновления. - Поля: AMS (слот/тип/цвет), статус, прогресс, слой, job name, elapsed/remaining, температуры, вентиляторы, ошибки.
- Единый
- Рендер оверлея в текст
- Шаблон строк (несколько строк с фиксированным порядком).
- Атомарная запись через tmp + rename.
- Видео-пайплайн
- FFmpeg командой из env (preset, reconnect options).
- В случае потери видео: автоreconnect без завершения контейнера.
- Выдача потока
- Поднять MediaMTX в том же контейнере, публиковать туда выход FFmpeg.
- Наблюдаемость
/healthz: жив ли процесс./readyz: есть ли свежая телеметрия и/или видео за N секунд./metrics(опционально, Prometheus).
- Fail-safe поведение
- Нет MQTT: показывать
MQTT: disconnected, последнее известное состояние. - Нет RTSP: показывать standby/заглушку либо держать процесс с reconnect.
- Нет MQTT: показывать
- Docker
- multi-stage build, tini/s6/supervisord как init.
- Один
CMD, стартующий supervisor, который поднимает все процессы.
Вариант 2: GStreamer (единый мультимедийный граф) + Python для телеметрии
Идея
- GStreamer получает RTSP (
rtspsrc), декодирует CPU (avdec_h264), накладывает текст (textoverlay/cairooverlay), кодирует (x264enc), отдает RTSP/UDP. - Python процесс обновляет shared-state (например, через локальный сокет/redis-inproc-файл).
Плюсы
- Гибче компоновка пайплайна и ниже latency при правильной настройке.
- Возможны более сложные оверлеи (через cairo).
Риски/минусы
- Более крутая кривая настройки.
- Сложнее сопровождение для команды без опыта GStreamer.
План реализации
- Собрать baseline pipeline с reconnect.
- Подключить динамический text source.
- Реализовать health probes + watchdog pipeline.
- Обернуть в supervisor и Docker.
Вариант 3: go2rtc как ядро ретрансляции + sidecar-процесс оверлея внутри того же контейнера
Идея
- go2rtc забирает исходный поток и отдает его локально.
- Отдельный процесс внутри контейнера (FFmpeg/Python) берет поток из go2rtc, добавляет overlay, публикует обратно вторым потоком.
Плюсы
- Удобная интеграция, если у вас уже экосистема на go2rtc.
- Гибкая маршрутизация клиентов.
Риски/минусы
- Чуть сложнее маршрутизация потоков и конфиги.
- Потребление CPU выше при двойной обработке.
План реализации
- Встроить бинарь go2rtc в образ.
- Поднять stream source и overlay stream.
- Прописать стабильные имена потоков и healthchecks.
Рекомендованная структура проекта
app/main.py— orchestration, lifecycle.app/mqtt_client.py— подключение/подписки/reconnect.app/state.py— модель состояния и нормализация.app/overlay_renderer.py— генерация/run/overlay.txt.app/health_api.py—/healthz,/readyz,/metrics.docker/ffmpeg.sh— запуск ffmpeg с reconnect-флагами.docker/mediamtx.yml— конфиг локальной раздачи потоков.docker/supervisord.conf— процессы: python, ffmpeg, mediamtx.
Формат оверлея (пример)
P2S | Printing | 42% | Layer 135/320
Job: gearbox_v7.3mf
AMS: Slot 2 | PLA Basic | #FF7A00
Elapsed: 01:12:33 | Remaining: 00:35:20
Nozzle: 218°C | Bed: 60°C | Chamber: 36°C
Fans: Part 70% | Aux 40% | Chamber 35%
MQTT: OK (0.8s) | Video: OK (0.2s)
Отказоустойчивость (обязательная логика)
- MQTT down
- Не падать.
- Статус в overlay:
MQTT disconnected. - Экспоненциальный reconnect (до max interval).
- RTSP down
- Не падать.
- FFmpeg reconnect (
-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 10).
- Оба канала down
- Контейнер жив,
/healthz = 200,/readyz = 503.
- Контейнер жив,
- Переполнение/битый payload
- Валидация входа, лог ошибки, продолжение работы.
Логирование
- Формат: JSON Lines.
- Поля:
ts,level,component,event,message,error,printer_ip. - Важные события:
- connect/disconnect/reconnect (mqtt, rtsp);
- смена статуса печати;
- смена задания;
- деградация readiness.
Health endpoints
GET /healthz— процесс жив (всегда 200, пока event loop работает).GET /readyz— готовность сервиса:- 200: есть видео и/или телеметрия свежее N сек;
- 503: оба источника stale.
GET /status— краткий JSON со state (для дебага).
Docker-стратегия
- База:
python:3.12-slim+ffmpeg+mediamtx(скачанный бинарь). - PID 1:
tini. - Процесс-менеджмент:
supervisord/s6-overlay. HEALTHCHECKнаcurl -f http://127.0.0.1:8080/healthz.- Автостарт через
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"].
Этапы внедрения (MVP -> production)
- MVP (1–2 дня)
- MQTT ingest + простой overlay.txt + FFmpeg drawtext +
/healthz.
- MQTT ingest + простой overlay.txt + FFmpeg drawtext +
- Стабилизация (2–4 дня)
- reconnect стратегия,
/readyz, структурные логи, docker healthcheck.
- reconnect стратегия,
- Production hardening (3–5 дней)
- watchdog процессов, graceful shutdown, ограничения CPU/RAM, документация.
- Опционально
- Preset-ы оверлея (минимальный/расширенный), локализация, экспорт метрик.
Что выбрать сейчас
Для старта рекомендован Вариант 1 как самый быстрый и предсказуемый для CPU-only контейнера. Он лучше всего закрывает требования по надежности, простоте сопровождения и интеграции с go2rtc/OBS.