23 Commits

Author SHA1 Message Date
deeily
e61d8ac649 dvr_admin v2.4.0: Novicam NR1604 integration (частичная)
Поддержка Novicam V3.4.96 рядом с Hikvision, изолировано через IP-whitelist
_NOVICAM_IPS_TEMP. Cam 2/3/4 работают (live + playback с шифрованием), cam 1
остаётся открытым вопросом — Linux libPlayCtrl.so не декодит её mainstream
несмотря на идентичный wire-формат плагину.

Инфраструктура Novicam:
- _novicam_session_login() — sessionID из <SessionUserCheck>, используется
  как Cookie WebSession (Novicam не выставляет Set-Cookie)
- _sdk_http_live_reader_novicam() — отдельный reader для live stream
- _sdk_http_playback_reader_encrypted(_novicam=True) — ветка в encrypted
  playback для Novicam (без /ISAPI/Security/token, свой HB pattern)
- _fetch_channels_inline fallback на /ContentMgmt/InputProxy/channels
  при 403 от /Streaming/channels (маппинг id=N → N01)
- Pre-activation probes перед /SDK/play (security=1 + PTZ endpoints) —
  активируют канал в сессии после Spy DLL анализа плагина
- HTTP-заголовки (Accept/Accept-Language/Accept-Charset) идентичны
  эталонному плагину — влияет на формат потока

Playback fixes:
- PlayM4_GetSourceBufferRemain throttle перед InputData — фикс 15-сек
  прыжков при ×1 воспроизведении. DVR заливает архив в scan-режиме
  (~10× быстрее реалтайма), без троттлинга libPlayCtrl захлёбывается.
  TCP flow control естественно замедляет DVR до темпа декодера.
- PTS-based current_start через buf.video_ms при reconnect — защита от
  прыжков вперёд на неотыгранный интервал

Инфраструктура для cam 1 (готова, отключена):
- _NovMuxWine singleton — wine + Windows PlayCtrl.dll (Novicam 194 exp)
- wine_playm4_nov/ с mux server без SetStreamOpenMode (file mode) —
  плагин использует default stream mode
- Включается через _use_nov_wine = (cam_num == 1), сейчас False

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:27:38 +03:00
deeily
35aaa982c8 dvr_admin v2.3.1: security hardening + resource cleanup из аудита
Безопасность:
- Brute-force throttle на /login: 5 неудач с (IP, user) → блок 60с,
  окно 5 мин. Успешный вход сбрасывает счётчик
- Referer / Sec-Fetch-Site check на /view/<dvr>/stream и /playback —
  защита от CSRF через <img> с чужих сайтов
- Rate-limit потоков per-user: max 24 concurrent stream/playback,
  429 при превышении. Защита от DoS

Ресурсы:
- Fix утечки retry-буфера в view_playback SDK HTTP (retry-путь
  не вызывал release если второй заход тоже не дал кадров)
- Кэш _get_channel_fps TTL 10 мин — лишний ISAPI-запрос при каждом
  открытии playback устранён

Version bump 2.3.0 → 2.3.1, CHANGELOG обновлён.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:57:29 +03:00
deeily
5415daefd5 dvr_admin: Fernet encrypt stream_key, Docker wine support, cleanup fixes
Security / шифрование:
- stream_key (128-byte KDF-derived key для encrypted H.265+) теперь
  шифруется Fernet как и пароль DVR. Добавлены _enc_stream_key /
  _dec_stream_key, расшифровка в _dvr_row, автомиграция plaintext→Fernet
  при старте для существующих записей
- dvrs_add / dvrs_edit шифруют stream_key на INSERT/UPDATE

Resource cleanup:
- release(buf): kill() теперь вне buf.lock + wait(timeout=2) чтобы
  не оставлять зомби-процессов (wine/ffmpeg) после disconnect
- view_playback: при смене ключа старый buffer также wait(timeout=2)

Docker:
- Dockerfile: установка wine + wine32 (i386) + xvfb для PlayCtrl.dll
- Предварительная инициализация WINEPREFIX=/app/.wine во время build
  (избегаем задержек первого wineboot в runtime)
- entrypoint.sh запускает Xvfb на :1, затем gunicorn
- COPY dvr_admin/wine_playm4/ в образ (директория gitignore'д —
  нужно положить вручную перед docker build, см. DEPLOY.md)
- DEPLOY.md: добавлена секция «Требования для сборки» с пояснением
  про wine_playm4/ и варианты без него

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:47:19 +03:00
deeily
593afa8cbb dvr_admin v2.3.0: Phase 3 playback — wide layouts, drag-drop, deep-links, clip speed
- Wide layouts 6/8/13 (grid-template-areas как в iVMS) + drag-drop камер
  из дерева и между pane'ами (swap с рестартом потоков)
- Переименование favorite в UI (inline ✎), upsert по имени, полный сброс
  pane'ов в applyFavorite (фиксит чёрные экраны при повторном применении)
- Layout 2×2 по умолчанию, авто-подгрузка таймлайна при добавлении камеры
- Share-link: кнопка 🔗 в playback и view_dvr archive, URL
  /playback?dvr&ch&iso → 1×1 + seek к моменту, серверный access check
  с редиректом на dashboard
- Clip save: слайдер скорости ×1/×2/×4/×8 через ffmpeg setpts+libx264
  (mp4/mkv/gif), суффикс _xN в имени файла
- Quality FPS cap (Авто/5/10/15/25) с persist в localStorage +
  backpressure на MJPEG producer (пропуск GetJPEG если клиент отстаёт)
- Seek ±1м / ±5м вместо ±10с / ±30с (везде)
- Native SDK playback auto-retry alt channel offset (фикс NVR
  10.10.13.40 где смещение отличается)
- Таймлайн: aggregate всех pane'ов, клиппинг к границам дня,
  «Запись не найдена» per pane, красный курсор + свечение, шаг 1ч
- view_dvr archive: синие сегменты (раньше пусто), дедуп часов
- Mobile nav: убран «Архив»
- Infra (feature-flag OFF): Multiplexed wine playm4_mux_server.exe +
  _MuxWine singleton — один wine-процесс на все playback-сессии.
  Отложено до следующих релизов

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:38:49 +03:00
deeily
8b9936df01 dvr_admin v2.2.0: раздел «Воспроизведение» — мульти-канал + избранное
Новый пункт sidebar «Воспроизведение» с кастомным плеером архива по образцу
iVMS-4200. Виден всем авторизованным, DVR фильтруются по dvr_access/concept_access.

Фаза 1 (single-pane MVP):
- Роут /playback: дерево DVR с availability dots, MJPEG video, таймлайн
  из /api/dvr/<id>/recordings, кастомный календарь (сегодня=зелёный,
  дни с записями=синий, выбранный=оранжевая обводка)
- Центрированные контролы: ⏮ ⏸ ⏭ | « ×1 » | время
- Live кнопка слева (красная с pulsing dot), Clip popup с SSE прогрессом,
  REC кнопка (логика идентична существующей view_dvr recToggle)
- Пауза сохраняет кадр через canvas-capture + snap fallback

Фаза 2 (multi-pane grid):
- Рефакторинг state в panes[] с layout 1/4/9/16 (6/8/13 disabled)
- Клик камеры → назначается в активный/первый пустой pane
- Sub-stream автоматически при layout>1 (снижение битрейта ×4-8)
- Новые камеры стартуют в live; архив — кликом по таймлайну
- Sync play/pause/seek/speed/date между всеми pane'ами
- Speed resync: рестарт всех pane'ов от master ISO + /speed broadcast

Избранное (saved grid views):
- Таблица user_pb_views + API GET/POST/PUT/DELETE /api/playback/views
- ★ кнопка popup для сохранения, секция «Избранное» в дереве над DVR'ами
- Клик применяет layout+камеры, активное подсвечено оранжевым

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 00:44:38 +03:00
deeily
1e96a0da5d dvr_admin v2.1.0: native SDK playback через wine PlayCtrl.dll
Linux libPlayCtrl.so не может декодировать encrypted H.265+ (pm4err=2).
Решение: wine subprocess (playm4_pb_server.exe) с DecCallBackMend для
получения полных кадров без tearing. Push-based архитектура через pipe.

Скорость ×2/×4 работает (PlayM4_Fast + PlayBackControl PLAYFAST).
×8/×16 ограничение DVR — не ускоряет data feed для encrypted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 19:14:55 +03:00
deeily
ad72d6e589 Release v2.0: H.265+ Smart Codec со Stream Encryption v2.0 2026-04-20 16:40:29 +03:00
deeily
efa4ea8fc5 dvr_admin v2.0.2: encrypted clip download через native SDK
- Clip download encrypted: PlayBackByTime_V40 + byDownload=1 работает без SetPlayBackSecretKey
  (SDK расшифровывает внутренне, data callback отдаёт чистый MPEG-PS)
- Auto-detect channel для native SDK: encrypted DVR используют plain cam_num (из pcap iVMS)
- Убран нерабочий SetPlayBackSecretKey и ненужный _decrypt_ps_via_playm4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 16:39:32 +03:00
deeily
934ea5bd5a dvr_admin v2.0.1: playback speed control + NVR channel auto-detect
- Playback speed ×2/×4/×8 для encrypted H.265+ через PlayM4_SetStreamOpenMode(FILE) + PlayM4_Fast
- Auto-detect channel offset DVR (cam_num) vs NVR (32+cam_num) — per-instance, без глобального кэша
- Socket timeout handling: socket.timeout не вызывает reconnect, silent timeout увеличен до 10с
- Slow→normal force reconnect: DVR залипает после PLAYSLOW, reconnect сбрасывает
- Reconnect по wall time вместо video_ms (в file mode PlayM4 decode ahead)
- Hello flag validation в playback handshake (0x29=OK, иначе retry с другим offset)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 19:38:52 +03:00
deeily
8b47442251 dvr_admin v2.0 (testing): H.265+ Smart Codec со Stream Encryption
Первая волна: live preview / main view / playback archive для Hikvision
DVR с user-заданным Encryption Key (Live View Parameters). Работает на
нативной libPlayCtrl.so без wine в runtime.

### Добавлено
- Live 16-канальный грид (2 fps), main view (12 fps), playback archive
  через `/SDK/play` / `/SDK/playback` HTTP protocol + libPlayCtrl.so
- Pull-модель PlayM4_GetJPEG вместо SetDecCallBack (callback'и крашили
  под нагрузкой из-за GIL race в 16 native decoder threads)
- Session reconnect loop (DVR рвёт /SDK/play ~30 сек) + heartbeat
  /ISAPI/Security/sessionHeartbeat + auto-recovery на 401
- UI sync часов к видео-PTS через PlayM4_GetSystemTime + /pos endpoint,
  _pbWall re-peg каждые 2 сек. Оба template'а (fullscreen + modal)
- Pure Python KDF `_hik_stream_kdf_128(user_key)` — реверс NetStream.dll
  через Ghidra headless. K1=6a68a361bf6eb567, K2=cd7afe68ca6fde75,
  cipher D(K1)-swap-E(K2)-swap-D(K1) на 16-байт блоки. Финальная формула
  `user_key_ascii + derived16 × 7` (константа для любого ключа)
- Spy DLL под wine + Ghidra reverse engineering workflow

### Исправлено
- UI часы в архиве тикают на всех скоростях (убрано `if(_pbRate!==1)`
  в _startSeekTimer + добавлено обновление m-status в модальном template)
- Сервер больше не падает в 16-канальном гриде encrypted (убраны
  per-frame ffmpeg forks, pull-модель JPEG)

### TODO (остаются в testing до фикса)
- Playback speed ×2/×4/×8 — протокол захвачен, код применён
  (PlayM4_Fast + dynamic GETJPEG_INTERVAL), ожидает теста
- Clip download encrypted — NET_DVR_SetPlayBackSecretKey returns FALSE,
  план B: post-factum decrypt через pure Python cipher

### Docker
- gunicorn --workers 1 --threads 16 (single worker обязательно для
  libPlayCtrl thread safety)
- _DVR_LD_SET=1 env чтобы skip self-exec в контейнере
2026-04-16 03:33:50 +03:00
deeily
10f8c4207d Release dvr_admin v1.10: мобильная версия 2026-04-14 18:32:32 +03:00
deeily
358b20a207 Release dvr_admin v1.9.1: security fixes, memory leaks, ELK (скрыто)
Security:
- XSS: _html.escape() для полей из БД в списке пользователей DVR
  и карточках DVR (u["name"], d["name"], d["ip"], loc_name)
- JS-инъекция: openEditModal(...) через json.dumps() + _html.escape

Memory leaks / hanging threads:
- _user_activity: TTL 24ч, gc раз в час, лимит 500 записей
- IP-кэши (_sdk_failed_ips и др.) очищаются в dvrs_delete
- _ffmpeg_reader: select() с таймаутом, watchdog 30с для live
  (playback не трогаем), graceful shutdown через buf.clients==0

ELK (скрыто в UI до стабилизации):
- Карточка настройки отправки логов в ELK (HTTP ES bulk / Logstash HTTP/TCP)
- Фоновый демон elk-forwarder с очередью и батчами
- Таблица app_settings(key, value) + эндпоинты /api/settings/elk
2026-04-14 02:27:22 +03:00
deeily
ace5111a59 Release dvr_admin v1.9: админ-панель с графиками CPU/RAM/диск/GPU
- Раздел "Логи" переименован в "Админ панель": canvas-графики
  в стиле Zabbix (CPU/RAM/диск/GPU, история 60 точек, обновление 3с)
- Таблица активности пользователей: онлайн-статус, последний запрос,
  счётчик запросов через after_request хук
- GPU через nvidia-smi (появляется автоматически)
- Синхронизация времени DVR с автоопределением формата XML/plain text
  и учётом локальной timezone (кнопка пока скрыта в UI)
- Колонка действий в таблице DVR: min-width 220px
2026-04-14 02:11:05 +03:00
deeily
043c4c12b4 Release dvr_admin v1.8.2: SDK mode, logs, sidebar collapse, UI polish
- Выбор режима SDK (auto/shttp/native) для каждого регистратора
- Раздел «Логи» в сайдбаре (только для администраторов)
- Сворачиваемая боковая панель с сохранением состояния в localStorage
- Прошивка регистраторов на дашборде (firmwareVersion из ISAPI)
- Высота шапки 44 px — квадрат при свёрнутой панели
- Новые иконки: видеокамера (Просмотр), звёздочка (Мои виды)
- Дашборд пользователей: скрыты IP, модель и прошивка
- Исправлено дублирование кнопки «Добавить» на странице Регистраторов
2026-04-13 20:45:18 +03:00
deeily
f87c227330 Release dvr_admin v1.8.1: sync UI по PTS, ×16, slow-internet
- Heartbeat PLAYFAST каждые 3с с sock lock — стабильность потока на ускорении
- Переключение скорости только дельтой команд (без лишнего PLAYNORMAL)
- Диапазон 1/4…×16, добавлен Slow Forward (PLAYSLOW)
- Плашка "Slow internet" при отсутствии кадров
- Синхронизация UI по реальному PTS с DVR (MPEG-PS для H.265, PlayM4_GetSystemTime для H.264)
- Endpoint /playback/<ch>/pos + poll раз в 2с на клиенте
2026-04-13 16:08:10 +03:00
deeily
3d3f64e4c6 Release dvr_admin v1.8: плавное ускоренное воспроизведение архива
SDK-over-HTTP протокол с PLAYFAST для ×2/×4/×16 без прыжков по таймлайну.
H.265: парсинг MPEG-PS → H.265 ES → ffmpeg. H.264: PlayM4.
Digest-аутентификация на сокете, автоопределение кодека по IMKH.
2026-04-09 18:27:57 +03:00
deeily
988df4d613 Release dvr_admin v1.7
Fix APP_VERSION not rendering on dashboard (f-string used old string concat syntax).
2026-04-08 01:07:54 +03:00
deeily
0021730359 Release dvr_admin v1.7
- Мои виды: создание именованных видов с произвольным набором камер
- Переименование каналов (per-user) в «Мои виды»
- Полноэкранный плеер доступен из «Мои виды»
- Архивный плеер: FPS с DVR через ISAPI, окно 24ч, без параллельных потоков при seek
- Исправлен плеер в /view (display:none override)
- Версия в APP_VERSION
2026-04-08 01:01:57 +03:00
deeily
4a7a2c55d7 Release dvr_admin v1.6.1: прогресс-бар скачивания клипа 2026-04-07 12:42:56 +03:00
deeily
a19843fda3 Move SDK libs to dvr_admin/lib, fix paths in app.py
SDK библиотеки перенесены из doc/ в dvr_admin/lib/ (были идентичны).
_SDK_DIR и _SDK_LIB теперь указывают на dvr_admin/lib/.
2026-04-07 12:28:09 +03:00
deeily
fa730238d0 Release dvr_admin v1.6
Переведено скачивание клипов на Hikvision SDK (PlayBackByTime_V40 +
data callback) — точное время по часам DVR без seek-смещения.
Исправлена загрузка SDK-библиотек через self-restart с LD_LIBRARY_PATH.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:26:38 +03:00
deeily
3da61f09ca Release dvr_admin v1.5
- Archive player: loading spinner on stream start/seek/timeline click
- Archive player: live clock updates every second during playback
- Timeline: removed segment overlays, hourly labels (0–24)
- Clip download: split time inputs into separate HH/MM/SS fields
- Clip download: cancel button aborts fetch and kills ffmpeg on server
- Security: CSRF protection, HttpOnly/SameSite cookies, XSS escaping,
  parameter validation, access control on ping endpoint
- Dashboard: user-specific DVR cards, live clock and version widgets
- Preview channels resume after closing fullscreen player
- Docker: moved SDK libs into dvr_admin/, cleaned up dvr_admin_docker/
2026-04-06 22:46:19 +03:00
deeily
d8ce3daf1f Initial commit: dvr_admin v1.2
- Flask-приложение управления DVR Hikvision
- Предпросмотр каналов, архив, скачивание клипов
- Управление пользователями с правами доступа
- Docker-контейнер с Gunicorn
2026-04-05 21:44:40 +03:00