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>
This commit is contained in:
deeily 2026-04-23 00:38:49 +03:00
parent 8b9936df01
commit 593afa8cbb
2 changed files with 1033 additions and 169 deletions

View File

@ -4,6 +4,66 @@
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/).
## [2.3.0] — 2026-04-23
Фаза 3 раздела «Воспроизведение»: wide layouts, drag-drop, deep-links, ускоренное сохранение клипов, оптимизации под multi-pane, обширные UX-фиксы.
### Добавлено — Phase 3 playback
- **Wide layouts 6 / 8 / 13** (grid-template-areas как в iVMS) — большой тайл + маленькие по краям. Включены в division popup
- **Drag-and-drop камер из дерева** прямо в нужный pane (не только в активный/первый пустой)
- **Drag-and-drop pane ↔ pane** — перетаскиванием меняется содержимое двух окон, потоки рестартуются на новых позициях. `activeIdx` следует за контентом
- **Подсветка drop-зоны** (синяя обводка + фон) при dragover; пустой pane тоже принимает drop
- **Переименование favorite в UI** — ✎ на hover, inline-input с Enter/Esc/blur, PUT `/api/playback/views/<id>`
- **Favorite upsert по имени** — повторное сохранение с существующим именем не крашит БД, а обновляет layout + камеры
- **Полный сброс pane'ов при applyFavorite** — ручные камеры больше не «залипают», повторное применение не даёт чёрные экраны
- **Layout 2×2 по умолчанию** при открытии `/playback` (раньше 1×1)
- **Авто-подгрузка таймлайна** при добавлении первой камеры — сегменты грузятся даже в live-режиме, оператор сразу видит когда есть архив
### Добавлено — Deep-links / share moment
- **Кнопка 🔗 «Поделиться моментом»** в playback контролах (popup с URL + «Скопировать») и в view_dvr archive toolbar (inline кнопка)
- **URL формата** `/playback?dvr=<id>&ch=<chId>&iso=<ISO>` — при открытии автоматически: layout 1×1, камера в pane 0, дата из ISO, archive mode, seek к моменту
- **Серверный access check** — если DVR не в списке доступных пользователю → flash `«Нет прав просмотра этого регистратора»` + redirect на dashboard
### Добавлено — Clip save with speed
- **Слайдер скорости** ×1 / ×2 / ×4 / ×8 в clip popup (и в playback, и в view_dvr archive). При ×1 — чистый remux (`-c:v copy`, быстро). При ×>1 — re-encode через ffmpeg `setpts=PTS/N` + `libx264 -preset veryfast -crf 23`. Поддерживаются mp4 / mkv / gif
- Имя файла получает суффикс `_xN` (`clip_20260423_114000_x4.mp4`)
- RTSP-fallback пайплайн также учитывает speed
### Добавлено — Quality / performance
- **Переключатель качества (FPS cap)** в playback контролах: Авто / 5 / 10 / 15 / 25 fps. Значение хранится в `localStorage`, передаётся в `?fps=N` на `/view/<dvr>/stream` и `/view/<dvr>/playback`, сервер рейт-лимитит отдачу кадров клиенту
- **Backpressure на MJPEG producer**`ChannelBuffer._unread` + `mark_served()`: если клиент не забрал предыдущий кадр, производитель пропускает `PlayM4_GetJPEG` (самая дорогая операция). Адаптивная деградация при медленных клиентах, CPU падает линейно
- **Seek ±1 мин / ±5 мин** вместо ±10с / ±30с — более удобно для навигации по длинным записям (и в playback, и в view_dvr)
### Добавлено — Native SDK playback channel auto-detect
- **Retry с альтернативным offset** в `_sdk_playback_reader`: если `PlayBackByTime` упал с ошибкой, автоматически пробуется `cam_num``32+cam_num`. Фикс NVR где offset отличается от DVR (10.10.13.40)
### Добавлено — view_dvr archive timeline
- **Синие сегменты записей** на таймлайне (раньше был только пустой бар) с клиппингом по границам выбранного дня — нет «тонкой полоски на стыке суток»
- **Красный курсор** с мягким свечением (было — белая полоска 0.6 opacity)
- **Без дубликатов часов** — только один ряд подписей (00, 01, …, 24)
### Добавлено — playback timeline
- **Aggregate по всем pane'ам** — клик по таймлайну работает на все камеры с активным потоком; календарь показывает union дней записей всех pane'ов
- **Клиппинг сегментов к границам дня** через UTC-diff — устраняет артефакты на границе суток
- **«Запись не найдена»** в pane когда в выбранный день архива нет (вместо глобального статуса)
- **Подсветка активного pane** переделана — 3px обводка + внешнее свечение (видно на любой теме)
- **Шаг разметки** каждый час вместо 2
### Изменено
- **Mobile nav** — убран пункт «Архив» (остались «Просмотр» и «Мои виды»)
- **ffmpeg clip builder** унифицирован между SDK и RTSP-fallback путями
### Инфраструктура (feature-flag, неактивно)
- **Multiplexed wine PlayCtrl server** (`wine_playm4/playm4_mux_server.exe`) — один wine-процесс обслуживает до 64 playback-сессий с мультиплексированным протоколом (OPEN/DATA/FAST/NORM/CLOS по sid). Python-менеджер `_MuxWine` (singleton, thread-safe stdin, stdout-демультиплексор). Флаг `PLAYBACK_MUX_WINE=False` — при проверке выяснилось что главный bottleneck — SDK-логины DVR на 4+ каналов, а не wine-процессы. Решили отложить до следующих релизов
### Отложено (планы, не делаем сейчас)
- MSE/fMP4 пайплайн (decode на клиенте, серверный remux) — решение серверного bottleneck multi-pane. Откладывается до возможного апгрейда сервера (GPU)
- HikClient WPF — Windows-клиент с нативным декодом
- Timeline notes — заметки привязанные к моменту архива (схема БД + UI план в memory)
- RTSP fallback в view_playback — отключён сознательно, чтобы не маскировать баги SDK-пути
---
## [2.2.0] — 2026-04-21
Раздел **«Воспроизведение»** — новый пункт sidebar с кастомным мульти-канальным плеером архива по образцу iVMS-4200. Виден всем авторизованным пользователям, DVR отфильтрованы по правам (`dvr_access`/`concept_access`). Иконка в sidebar — круговая стрелка «назад» со стрелками часов внутри.

File diff suppressed because it is too large Load Diff