storage: per-camera target + date subfolders; move active-storage widget
- Camera.storage_id: each camera chooses its storage ("" = active/default).
supervisor resolves per-camera (storage_by_id → active fallback); cameras
API (body/payload) + /toggle accept storage_id and repoint the recorder.
- Recordings now go to <root>/<cam>/<YYYY-MM-DD>/<file>.mp4. This ffmpeg build
lacks -strftime_mkdir, so recorder_task pre-creates today+tomorrow dirs at
start and the indexer re-ensures them each tick (survives midnight).
- indexer: scan date subdirs + legacy flat files; sort by basename so the
in-progress segment is detected correctly when both layouts coexist.
- frontend: per-camera "Хранилище" dropdown in the camera table (inline) and
in the add/edit + bulk forms. Move the active-storage summary widget from
the Система tab into the Хранилища tab.
VERSION 0.0.129.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,9 +22,10 @@ class Supervisor:
|
||||
return go2rtc.restream_main_url(self.config, cam.id)
|
||||
|
||||
def _new_task(self, cam: Camera) -> RecorderTask:
|
||||
# пишем в активное хранилище; смена активного → restart_all репойнтит все задачи
|
||||
active = self.config.active_storage()
|
||||
return RecorderTask(cam, active, self.config.storage.segment_seconds,
|
||||
# хранилище камеры: её storage_id, иначе активное (по умолчанию). Несуществующий
|
||||
# id (удалённое хранилище) → тоже откат на активное.
|
||||
store = self.config.storage_by_id(cam.storage_id) or self.config.active_storage()
|
||||
return RecorderTask(cam, store, self.config.storage.segment_seconds,
|
||||
on_status=self.on_status, input_url=self._input_url(cam))
|
||||
|
||||
def start_all(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user