nas-media-archiver is a single-binary Go CLI that archives photos and videos
from an input directory into a date-based directory structure.
It is designed for NAS workflows first, especially QNAP-style environments, but it can also run on a regular Linux host.
- Archives files into
photos/YYYY/MM,videos/YYYY/MM, andpngs/YYYY/MM - Uses
YYYYMMDD_HHMMSS_size.extnaming - Preserves duplicate files safely
- Supports
scan,run,status,watch,files,retry, andexport - Supports
--dry-runbefore a real archive run - Stores per-job state as
job.jsonandevents.jsonl - Handles cross-filesystem moves safely with copy-then-rename fallback
- Photos:
jpg,jpeg,heic - Videos:
mp4,mov,3gp - Images via mtime fallback:
png
Current unsupported examples:
gifwebp
go build -o archive .
make build-linux-arm64
make build-linux-arm7- Scan an input directory.
./archive scan \
--path /path/to/input \
--state-dir /path/to/archive-state- Run a dry run first.
./archive run \
--job <job-id> \
--archive-base /path/to/archive \
--state-dir /path/to/archive-state \
--dry-run \
--workers 8 \
--snapshot-every 100- Run the real archive.
./archive run \
--job <job-id> \
--archive-base /path/to/archive \
--state-dir /path/to/archive-state \
--workers 8 \
--snapshot-every 100QNAP ACL behavior differs from a standard Linux host. In practice:
- run a dry run first
- use
sudo -u adminfor real writes into shared archive directories - ensure
exiftoolis available if you want HEIC fallback support - ensure
ffprobeorffmpegis available for video metadata fallback
Example:
sudo -u admin ./archive run \
--job <job-id> \
--archive-base /path/to/archive \
--state-dir /path/to/archive-stateBased on current ARM QNAP benchmarks:
--workers 8--snapshot-every 100
MIT