Recording & Storage
SkyView records locally in segments by default, with the option to attach 115 Cloud for cloud backup. This chapter explains the recording mechanism, retention policies, and 115 integration.
How recording is written
SkyView cuts each camera's video into standard MP4 files by time, fixed at 60 seconds per segment. MediaMTX first writes out fMP4 segments; the instant a segment finishes, the runOnRecordSegmentComplete hook fires, and ffmpeg remuxes it in place with -c copy into a standard MP4 with faststart (moov at the head), so every player can seek directly. The on-disk path:
data/recordings/
<camera_id>/
2026-05-18_14-30-00.mp4
2026-05-18_14-31-00.mp4
2026-05-18_14-32-00.mp4
...Path after archiving
archived, it's atomically renamed under data/recordings/_archive/<camera_id>/, mirroring the directory structure and filename exactly, to distinguish it from the inbox being actively written. The _archive/ prefix is a convention; the uploader's discovery scan skips it so archived files aren't reprocessed. In 115 Cloud mode, whether the local copy is kept is governed by the delete_after_upload setting (default: delete on successful upload).Local storage path
Recordings are written to /app/data/recordings (nested mount, can be pointed at a large disk / NAS separately); small state like the database / cookies / logs lives in /app/data, and AI models are bundled in the image rather than in the data directory. For production, always point the recordings directory at a disk with ample capacity, and don't cram it onto the same partition as the system disk — a full recordings disk will keep your server from booting.
# Recommended: mount recordings on a separate large disk / NAS (small state stays in data/)
sudo mkdir -p /mnt/recordings
# One-line script: point --recordings-dir at the large disk
curl -fsSL https://cdn.yun-kan.com/yunkan-install.sh | bash -s -- --recordings-dir /mnt/recordings
# Or nest-mount the recordings volume in a manual docker run
docker run -v $(pwd)/data:/app/data -v /mnt/recordings:/app/data/recordings ...Retention policy and disk space
Web admin → Settings → Recording retention to enable and configure automatic cleanup (off by default, must be turned on manually). Once on, the two rules below both apply and either one triggers deletion; only archived recordings (uploaded successfully, or local mode) are cleaned, and pending / uploading / failed states are never touched:
- By days: recordings older than the retention days (default 30) → deleted; set 0 = don't trigger by time
- By capacity: when disk usage exceeds the threshold (default 90%) → delete starting from the oldest; set 100 = don't trigger by space
Off by default
[cleanup] service has enabled=false — left off, everything is kept; when the disk fills, writes fail but SkyView won't delete on its own. For home deployments we strongly recommend turning it on and letting the system handle your worries via the two rules above.| Resolution | Bitrate | Rough usage per stream per 24 hours |
|---|---|---|
| 1080p H.264 | 2 Mbps | ~21 GB / day |
| 1080p H.265 | 1 Mbps | ~10 GB / day |
| 4K H.265 | 4 Mbps | ~42 GB / day |
Capacity estimation formula
115 Cloud storage (optional)
Asynchronously upload local recordings to 115 Cloud, essentially a "cloud NVR". With instant-upload support, existing recordings don't consume bandwidth.
- 1
Scan to log in
Web admin → 115 → show the QR code and authorize by scanning with the 115 mobile app. SkyView saves the login info encrypted in the data directory.
- 2
Choose the target folder
Create an empty folder in 115 (e.g. "SkyView Recordings"), return to SkyView, and select it as the upload destination
- 3
Switch the storage backend
Settings → Storage → choose 115 → Save. The switch is a hot swap that doesn't restart the process, taking effect on the next upload
- 4
Verify it's working
The Web Admin currently has no upload queue / progress panel. To confirm recordings are uploading, pick any of three ways: ① the Settings → 115 page to check that VIP status and remaining capacity look right; ② the Logs page (sidebar → Logs), select the
uploaderservice on the left to watch each segment's start / finish / failure lines in real time; ③ open the 115 app or website and go into the target folder to see whether new recordings are arriving.
115 login expires
What if you don't use 115
Download / export
The playback page supports "export by time range" — choose a start and end time, and the backend re-encodes and trims it into a single MP4 for the client to download, with frame-level precision on the start/end (<40ms error). It auto-selects hardware: NVIDIA NVENC (50-200x real time, tens of seconds per hour on an RTX) → Intel iGPU VAAPI (25-50x, a minute or two per hour on an N100) → libx264 software encode (1.5-3x, ten-odd minutes per hour). Any tier that fails automatically falls back to the next. All three of Web Admin, Android, and iOS support it.
- 1
Open the playback page
Select the camera and date to export. Drag the timeline near the target range so the center marker lands on that recording segment.
- 2
Click the export button
Web Admin: the ⬇ icon at the far right of the playback control bar; Android / iOS: "Export" to the right of the "Speed" button on the control bar. A range-selection panel pops up, defaulting to the current playback position ±30 seconds.
- 3
Adjust the start/end → submit
Change the start/end times in the panel and it computes the estimated size in real time (1080p H.264 ≈ 250 KB/s). The maximum per export is 1 hour; longer is rejected. Click "Start export".
- 4
Watch the progress
A progress card appears at the bottom-right (Web) / below the control bar (Android/iOS). Web refreshes in real time via SSE; mobile polls every 2 seconds. Once queued, a task usually completes in seconds to tens of seconds (depending on the segment count + whether cloud segments must be pulled from 115).
- 5
Download
Once the progress card turns into a "Download" button, click it: Web downloads directly via the browser; Android uses the system DownloadManager to save to
Downloads/SkyView/with a status-bar notification; iOS opens a ShareSheet to "Save to Files / Photos" or share to WeChat.
Auto-selected hardware acceleration NVENC > VAAPI > libx264
--gpus all; ~30-60 seconds for 1h of video on RTX 30/40 series
- VAAPI (Intel/AMD iGPU): needs the openvino/all-in-one image + /dev/dri passthrough; ~1-2 minutes for 1h of video on an N100, etc.
- libx264 (CPU only): fallback when there's no GPU; ~20-40 minutes for 1h of video (depending on the CPU)
Any tier that fails at runtime (incompatible driver, session limit, etc.) automatically falls back to the next. To force a specific one, use recording.export.hwaccel = "nvenc" / "vaapi" / "none".Start/end times are frame-precise
qp=23 / VAAPI qp=23 / libx264 crf=23 — output is visually nearly identical across hardware (NVENC files may be slightly larger, <10%). Configure recording.export.{nvenc,vaapi}_qp to tune quality separately (0-51, lower = higher quality).115 Cloud storage mode is supported too
Exported files are kept for 24 hours
data/recordings/_exports/<job_id>.mp4 on the server and is auto-deleted by cleanup after 24 hours by default (to avoid filling the disk). Within that window you can re-click "Download" from any client at any time for the same file. After it expires, re-initiate to get it again.Want to grab raw segments, bypassing the UI
data/recordings/<camera_id>/<YYYY-MM-DD_HH-MM-SS>.mp4 (after local archiving, under data/recordings/_archive/<camera_id>/), each a standard MP4. You can also GET /api/recordings/<id>/download with a JWT to fetch a single segment.