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>
- 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>
Первая волна: 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 в контейнере
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
- Раздел "Логи" переименован в "Админ панель": canvas-графики
в стиле Zabbix (CPU/RAM/диск/GPU, история 60 точек, обновление 3с)
- Таблица активности пользователей: онлайн-статус, последний запрос,
счётчик запросов через after_request хук
- GPU через nvidia-smi (появляется автоматически)
- Синхронизация времени DVR с автоопределением формата XML/plain text
и учётом локальной timezone (кнопка пока скрыта в UI)
- Колонка действий в таблице DVR: min-width 220px
- Выбор режима SDK (auto/shttp/native) для каждого регистратора
- Раздел «Логи» в сайдбаре (только для администраторов)
- Сворачиваемая боковая панель с сохранением состояния в localStorage
- Прошивка регистраторов на дашборде (firmwareVersion из ISAPI)
- Высота шапки 44 px — квадрат при свёрнутой панели
- Новые иконки: видеокамера (Просмотр), звёздочка (Мои виды)
- Дашборд пользователей: скрыты IP, модель и прошивка
- Исправлено дублирование кнопки «Добавить» на странице Регистраторов
- 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с на клиенте
SDK-over-HTTP протокол с PLAYFAST для ×2/×4/×16 без прыжков по таймлайну.
H.265: парсинг MPEG-PS → H.265 ES → ffmpeg. H.264: PlayM4.
Digest-аутентификация на сокете, автоопределение кодека по IMKH.
- Мои виды: создание именованных видов с произвольным набором камер
- Переименование каналов (per-user) в «Мои виды»
- Полноэкранный плеер доступен из «Мои виды»
- Архивный плеер: FPS с DVR через ISAPI, окно 24ч, без параллельных потоков при seek
- Исправлен плеер в /view (display:none override)
- Версия в APP_VERSION
Переведено скачивание клипов на Hikvision SDK (PlayBackByTime_V40 +
data callback) — точное время по часам DVR без seek-смещения.
Исправлена загрузка SDK-библиотек через self-restart с LD_LIBRARY_PATH.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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/
- Flask-приложение управления DVR Hikvision
- Предпросмотр каналов, архив, скачивание клипов
- Управление пользователями с правами доступа
- Docker-контейнер с Gunicorn