Fast, local-only review of trail camera media on Windows. No cloud. No Docker. Safe deletes.
- One-at-a-time review with Keep / Delete / Favorite
- Swipe gestures and big buttons (mobile-first)
- Undo last action
- Arrow-key browsing + on-screen arrows (no decision required)
- Desktop library drawer with search/filter + critter columns
- Desktop-only batch detect with live per-image feedback
- Resizable library pane on desktop
- Safe deletes (moves into dated
Trash_YYYY-MM-DD/) - Favorites, Keeps, and Deletes move into dated folders immediately
- Persistent JSON metadata
- Video streaming with phone-friendly fallback
- Optional AI batch critter detection (desktop)
- Optional AI captions with editable text
- Copy config:
copy config.example.json config.json- Edit
config.jsonand setmediaRootto your trailcam folder. - Install dependencies:
npm install- Start the server:
npm startThe app listens on http://0.0.0.0:3000. On your phone, open http://<your-lan-ip>:3000.
For auto-reload during development:
npm run dev- Swipe right = Keep
- Swipe left = Delete
- Swipe up = Favorite
- Buttons always work
- Arrow keys browse the queue
- K = Keep, D = Delete, F = Favorite
- Desktop view is power-user mode: library drawer, resizable pane, batch detect, full keyboard shortcuts, and hover hints.
- Mobile view is streamlined: big buttons + swipes, minimal chrome, and no batch detect to keep it fast and thumb-friendly.
- Desktop plays the original MP4 with sound. Mobile uses a lighter preview stream when playback is flaky, so it may look choppier but stays reliable.
- Both views share the same review queue, metadata, and safe delete behavior.
- No filename changes or renaming.
- No permanent deletes (everything is a move you can undo in Explorer).
- No auto-organized albums or collections.
- No cloud sync, accounts, or multi-user features.
- No editing, filters, or color adjustments.
- Delete moves files immediately into
Trash_YYYY-MM-DDundermediaRoot. - Favorite moves files immediately into
Favorites_YYYY-MM-DDundermediaRoot. - Keep moves files immediately into
Keep_YYYY-MM-DDundermediaRoot. - No permanent deletes in v0.
The metadata file is trailcam_review.json and is SQLite-friendly (flat rows). It stores:
sessionDatepathstatusreviewedAtcaptionai(reserved)critter,critterConfidence,critterCheckedAt,critterModel
sessionDate is created automatically on the first review action and is used for
the dated folder names.
If the metadata file is corrupt, a backup copy is created and a fresh file is used.
- If a video fails on mobile, CamReview auto-creates a smaller H.264 MP4 on the server
(requires
ffmpeg) and plays that version. - Previews are generated at
previewFpsup topreviewMaxFrames. - You can also drop a sidecar preview image (
.gif,.jpg,.jpeg,.png) with the same base name or inside.camreview/previews/.
CamReview can call OpenRouter in batch mode (desktop only). It runs through images without critter data, moves no-animal photos into Trash immediately, and writes captions for the animal photos.
Captions are always editable inline after generation.
Requirements:
- Set
OPENROUTER_API_KEYin the server environment. - Optional: set
OPENROUTER_MODELto override the default model.
Results are stored as critter and critterConfidence fields in the metadata.
See config.example.json. Options:
mediaRoot(required)ffmpegPath(optional, full path toffmpeg.exe)previewFps(optional, default 2)previewMaxFrames(optional, default 24)openrouterModel(optional, defaultopenai/gpt-4o-mini)
GET /api/items-> list unreviewed itemsPOST /api/action-> keep/delete/favorite and move immediatelyPOST /api/undo-> undo last actionGET /api/preview-frames?path=...&generate=1-> list or generate preview framesPOST /api/transcode-> create phone-friendly H.264 MP4GET /media?path=...-> stream image/videoPOST /api/detect-critters-> detect animal presence for the current imagePOST /api/caption-> save a caption for a filePOST /api/caption/generate-> generate a caption for the current image
API tests run against a temporary copy of a few sample files from your
C:\Users\danny\iCloudDrive\trailcam folder (originals are never modified).
Run:
npm test- If
ffmpegis installed but not found, setffmpegPathinconfig.json. - If mobile video still fails, check the server console output for ffmpeg errors.