dvr_admin/CHANGELOG.md
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

20 KiB
Raw Blame History

Changelog

Все значимые изменения фиксируются в этом файле.
Формат основан на Keep a Changelog.

[1.9] — 2026-04-14

Добавлено

  • Раздел «Админ панель» (переименован бывший «Логи»):
    • Canvas-графики CPU / RAM / Диск / GPU в стиле Zabbix — линия с заливкой, сетка, точка текущего значения, история последних 60 точек (~3 минуты при обновлении каждые 3с)
    • GPU-метрики (utilization + VRAM) через nvidia-smi, появляется автоматически если GPU обнаружен
    • Таблица активности пользователей: индикатор online/offline, имя + роль (admin/user), когда был последний запрос, какая страница, счётчик всех запросов
    • Двухколоночный layout: слева метрики, справа логи (колонки меняются местами на узких экранах)
  • Endpoint GET /api/system/metrics — CPU, RAM, диск (/), GPU, активность пользователей (только админ)
  • Трекинг активности пользователей через after_request хук: {username → last_seen, last_path, req_count, is_admin}
  • Синхронизация времени на регистраторе (PUT /ISAPI/System/time/localTime) с автоопределением формата: сначала GET, затем PUT в XML или plain text в зависимости от того, что вернул DVR (кнопка временно скрыта в UI до стабилизации)

Улучшено

  • Колонка действий в таблице регистраторов получила min-width:220px — все четыре кнопки гарантированно влезают без обрезания
  • psutil добавлен в зависимости для сбора системных метрик

Исправлено

  • Синхронизация времени: учёт локальной timezone (datetime.now() вместо utcnow()) — DVR получает корректное локальное время
  • Синхронизация времени для разных моделей DVR: некоторые требуют XML, другие — plain text; теперь определяется динамически

[1.8.2] — 2026-04-13

Добавлено

  • Выбор режима SDK для каждого регистратора на вкладке «Регистраторы»:
    • Авто (по умолчанию) — сначала SDK HTTP, при неудаче fallback на Native SDK → RTSP+PlayM4 → ffmpeg
    • HTTP SDK — только SDK-over-HTTP (PLAYFAST/PLAYSLOW/PTS-sync), без fallback'ов
    • Native SDK — только classic SDK-логин (NET_DVR_Login_V40), SDK HTTP пропускается
  • Селект режима в таблице списка DVR (инлайн, сразу применяется) и в модалках добавления/редактирования
  • Новый endpoint POST /dvrs/<id>/sdk_mode для быстрого переключения
  • При смене режима кэши _shttp_failed_ips/_shttp_ok_ips/_sdk_failed_ips сбрасываются для этого IP, чтобы новый режим вступил в силу с ближайшей сессии
  • Раздел «Логи» в сайдбаре (только администраторы): буфер последних 5000 строк (Flask + werkzeug), фильтры DBG/INF/WARN/CRIT, фильтр по дате, полнотекстовый поиск, автообновление 5 с
  • Сворачиваемая боковая панель: два состояния — развёрнутая (иконки + подписи) и свёрнутая (только иконки 44 px); состояние сохраняется в localStorage
  • Прошивка регистратора на дашборде: новая колонка «Прошивка» получает firmwareVersion через /ISAPI/System/deviceInfo

Улучшено

  • Высота шапки и логотипа уменьшена до 44 px — при свёрнутой панели в углу образуется точный квадрат
  • Иконка раздела «Просмотр» заменена на значок видеокамеры, «Мои виды» — на звёздочку (избранное)
  • Дашборд для обычных пользователей: скрыты колонки IP, Модель и Прошивка — отображаются только Название, Концепция и Статус

Исправлено

  • На странице «Регистраторы» дублировалась кнопка «Добавить» (появлялась и в топбаре, и в контенте)

База данных

  • Колонка sdk_mode TEXT NOT NULL DEFAULT 'auto' в таблице dvrs (автоматическая миграция через ALTER TABLE IF NOT EXISTS)

[1.8.1] — 2026-04-13

Добавлено

  • Ускорение архива до ×16 (раньше максимум был ×4): теперь диапазон 1/4 · 1/2 · ×1 · ×2 · ×4 · ×8 · ×16
  • Замедление воспроизведения (Slow Forward) через SDK HTTP команду PLAYSLOW (0x0003010A): 1/2 и 1/4
  • Плашка «Slow internet» поверх видео — красное предупреждение при отсутствии кадров >1.5с (на ускорении) или >2.5с (на ×1)
  • Синхронизация UI-времени по реальному timestamp с DVR: часы в интерфейсе теперь идут в ногу с OSD на видео при любой скорости
    • H.265: парсер MPEG-PS извлекает PTS из PES-заголовков каждого видеокадра
    • H.264: PlayM4_GetSystemTime() возвращает абсолютное время декодированного кадра
    • Новый endpoint /view/<dvr_id>/playback/<ch>/pos отдаёт video_ms от начала воспроизведения
    • Клиент раз в 2 секунды запрашивает позицию и подгоняет _pbWall под ответ сервера
  • Поддерживаемые скорости на сервере: {-4, -2, 1, 2, 4, 8, 16} (iRate как в jsVideoPlugin)

Исправлено

  • Обрыв потока на ×4/×8/×16 через ~6 секунд: DVR требует heartbeat-пакет PLAYFAST каждые ровно 3 секунды (подтверждено pcap-трассировкой оригинального плагина) — добавлен отдельный поток heartbeat-а с threading.Event.wait(3.0)
  • Повреждение данных в сокете при одновременной записи из heartbeat-треда и основного ридера — добавлен threading.Lock() на все sock.sendall()
  • Развал потока при переходе ×2→×4→×8: убран лишний PLAYNORMAL между последовательными ускорениями. Теперь отправляется только дельта команд (как делает оригинальный плагин в трассировке): ×2→×4 = 1×PLAYFAST, а не PLAYNORMAL + 2×PLAYFAST
  • Накопление рассинхрона UI/видео на высоких скоростях: формула wall_clock × rate давала дрейф до 30+ секунд. Полностью заменена на синхронизацию по PTS/SystemTime с сервера
  • Замирание UI-часов при зависшем потоке: детекция stale-кадров (>1.5с gap) останавливает счётчик времени, при возобновлении корректно доигрывает

Технические детали

  • Добавлена поддержка 33-битной обёртки PTS в парсере PES
  • Поля pts_base / video_ms в ChannelBuffer для хранения видео-времени
  • Функция _rate_idx() конвертирует rate (×1/×2/×4/2/4/…) в индекс (0/1/2/1/2) — упрощает расчёт дельты команд в _set_speed
  • Команды SDK HTTP binary: PLAYSTART=0x103, PLAYNORMAL=0x107, PLAYFAST=0x109, PLAYSLOW=0x10A

[1.8] — 2026-04-09

Добавлено

  • Плавное ускоренное воспроизведение архива (×2, ×4, ×16) через Hikvision SDK-over-HTTP протокол: все кадры отрисовываются на реальной скорости, без прыжков по таймлайну
  • SDK HTTP: Digest-аутентификация на сокете (2-step: получение nonce → запрос с Digest)
  • SDK HTTP: команда PLAYFAST (0x00030109) для смены скорости без переподключения
  • H.265 декодирование: парсинг MPEG-PS → извлечение H.265 elementary stream → декодирование через ffmpeg
  • H.264 декодирование: PlayM4 (libPlayCtrl.so) для потоков с codec_flags=01
  • Автоопределение кодека по IMKH-заголовку (codec_flags[0]: 01=H.264, 02=H.265)

Исправлено

  • SDK HTTP: deadlock при чтении ffmpeg stdout (отдельный поток для чтения)
  • Prefetch endpoint: NameError: _td при клике по таймлайну
  • Ускорение ×2/×4/×16 через native SDK (PlayM4_Fast + NET_DVR_PlayBackControl) не давало визуального эффекта — заменено на SDK HTTP PLAYFAST

[1.7] — 2026-04-07

Добавлено

  • Мои виды — новый раздел в боковом меню: пользователь создаёт произвольные виды с любым набором камер из разрешённых ему регистраторов
  • Камеры в виде перетаскиваются (drag-and-drop), порядок сохраняется
  • Редактор вида: модальное окно с переименованием и управлением камерами (выбор по DVR с чекбоксами)
  • SSE-эндпоинт /api/myview/sse — единый поток превью для камер с разных регистраторов
  • Полноэкранный плеер (прямой эфир + архив + скачивание клипа) доступен из «Мои виды»
  • Переименование каналов в «Мои виды»: каждый пользователь задаёт своё название, сохраняется в БД
  • Версия приложения вынесена в константу APP_VERSION в начале скрипта

Улучшено

  • Архивный плеер: окно воспроизведения расширено с 1 до 24 часов — длинные записи больше не обрываются
  • Архивный плеер: FPS берётся с регистратора через ISAPI (maxFrameRate), фоллбэк 20 fps
  • Архивный плеер: при переключении времени (клик по таймлайну) предыдущий поток явно завершается — нет параллельных соединений
  • Архивный плеер: ffmpeg-путь тоже throttle до реального FPS — потребление памяти при просмотре архива снижено

[1.6.1] — 2026-04-07

Улучшено

  • Скачивание клипа: прогресс-бар с двумя фазами — «Загрузка с DVR» (байты / процент) и «Конвертация»
  • Скачивание клипа: задание выполняется в фоновом потоке, браузер не блокируется
  • Кнопка «Отменить» прерывает фоновое задание и сигнализирует SDK прекратить приём данных

[1.6] — 2026-04-07

Исправлено

  • Скачивание клипов переведено на Hikvision SDK (PlayBackByTime_V40 + data callback): точное время начала по часам DVR, без seek-смещения
  • SDK-библиотеки загружаются корректно: процесс перезапускается с правильным LD_LIBRARY_PATH, чтобы libPlayCtrl.so находила зависимость libAudioRender.so

[1.5] — 2026-04-06

Добавлено

  • Дашборд обычного пользователя: карточки «Время» (живые часы) и «Версия»
  • Дашборд: обычный пользователь видит только разрешённые ему регистраторы
  • IP регистратора в шапке предпросмотра — кликабельная ссылка на веб-интерфейс устройства

Безопасность

  • CSRF-защита: все state-changing запросы (POST/PUT/DELETE) проверяют токен сессии; токен автоматически добавляется в формы и fetch-запросы через JavaScript
  • Куки сессии: установлены флаги HttpOnly и SameSite=Lax — куки недоступны из JS и не отправляются при кросс-сайтовых запросах
  • Открытый редирект: параметр next после логина принимается только как относительный путь, исключая редирект на внешние домены
  • XSS: все пользовательские данные в HTML-шаблонах экранируются через html.escape() вместо частичного replace('"', '&quot;')
  • Валидация параметров: channel, year, month проверяются на допустимый формат и диапазон до использования в XML-запросах и вычислениях
  • Контроль доступа: /api/dvr/<id>/ping теперь проверяет права пользователя на конкретный DVR
  • Небезопасный ключ по умолчанию: при запуске без SECRET_KEY выводится предупреждение в stderr

Убрано

  • Лишние папки и скрипты со старым кодом который уже нигде не используется

Исправлено

  • Удаление пользователя не срабатывало — клик всплывал на строку таблицы и перехватывался её onclick
  • После добавления CSRF-защиты ломались пинги регистраторов (порядок загрузки скриптов)
  • После выхода из просмотра канала предпросмотр не возобновлял поток

Улучшено

  • Предпросмотр каналов, плеер, календарь и таймлайн теперь полностью адаптируются к светлой/тёмной теме
  • Кнопка «Войти» на странице логина: hover больше не сливается с фоном
  • IP регистратора в шапке: обводка-кнопка без подчёркивания, появляется только после выбора DVR
  • Архивный плеер: спиннер ожидания при загрузке потока (переключение режима, перемотка, клик по таймлайну)
  • Архивный плеер: отображение текущего времени воспроизведения обновляется каждую секунду
  • Таймлайн: убраны сегменты записей, метки каждый час (024) вместо каждых 3 часов
  • Скачивание клипа: поля времени разбиты на отдельные ЧЧ / ММ / СС — каждая часть редактируется независимо
  • Скачивание клипа: кнопка «Отменить» прерывает загрузку и завершает ffmpeg-процесс на сервере

[1.4] — 2026-04-05

Добавлено

  • Сохранение пользовательского порядка каналов предпросмотра (drag-and-drop, per-user)

[1.2] — 2026-04-05

Добавлено

  • Смена пароля веб-пользователей (включая admin)
  • Отключение/включение учётных записей (включая admin)
  • Docker-контейнер: dvr_admin_docker/ с Gunicorn, инструкция деплоя DEPLOY.md
  • Ключ шифрования Fernet через переменную окружения FERNET_KEY

Исправлено

  • Скачивание клипа всегда начиналось с начала сегмента — теперь с запрошенного времени (byte-range seek)
  • Колонки таблицы веб-пользователей съезжали при добавлении колонки «Статус»

[1.1] — 2026-04-03

Добавлено

  • Панель сохранения клипа: выбор времени начала/конца, формат mp4/mkv/gif
  • Быстрое скачивание клипов через ISAPI HTTP download (~14 MB/s вместо RTSP)
  • YouTube-подобный спиннер загрузки для предпросмотра, основного потока и архива
  • Адаптивный FPS основного потока и архива (подстраивается под DVR)

Исправлено

  • ffmpeg-процессы не завершались при переключении между DVR — утечка CPU
  • Предпросмотр не загружался на DVR со спецсимволами в пароле (;#{}])
  • Клипы скачивались с начала сегмента вместо запрошенного времени

Улучшено

  • Предпросмотр: 1 fps на канал через -skip_frame noref (снижение нагрузки на CPU)
  • SSE-поток предпросмотра ставится на паузу при открытии полноэкранного плеера

[1.0] — 2026-04-01

Добавлено

  • Централизованное управление регистраторами Hikvision
  • Авторизация с bcrypt, шифрование паролей DVR через Fernet
  • Предпросмотр каналов через SSE (Server-Sent Events)
  • Просмотр архива с календарём и треком записей
  • Управление пользователями и правами доступа к DVR/концепциям
  • Поддержка Hikvision SDK (libhcnetsdk, libPlayCtrl) для Hi-Watch HEVC+