The whole NVR, in one window
A live camera wall, recorded playback, PTZ control, snapshots and on-demand recording — covering the parts of a vendor desktop client that matter day to day, on a platform those clients skip. One AppImage, no root, no system ffmpeg.
x86-64 Linux · 9.7 MB · MIT / Apache-2.0
Everything you reach for daily
Configuration stays in your device's own web UI. Kestrel is the window you leave open.
Live wall
A paged grid of 1, 4, 6, 9 or 16 cameras across every device and NVR channel at once. Sub streams in the grid, main stream when a camera is expanded, so a full wall stays cheap.
Expand and fullscreen
Double-click a camera to fill the viewing pane; F11 then takes the whole screen, hiding the sidebar and controls. Esc unwinds one level at a time.
Digital zoom
Scroll to zoom into any tile and drag to pan, on top of whatever optical zoom the camera itself offers.
PTZ and presets
Hold-to-move pan and tilt, zoom, focus and adjustable speed, with the presets stored on the camera re-read each time you select it. Home returns to the guard position; Calibrate runs the pan/tilt sweep, after asking.
Playback
A calendar of days that have footage, a clip list per day, streamed playback with scrubbing and variable speed, and download to disk.
Snapshots and recording
Full-resolution stills pulled from the device, and on-demand recording of the live stream straight to MP4 without re-encoding.
Events
Motion and AI detection — person, vehicle, pet, face — shown as a live feed, with the tile and the sidebar entry highlighted and a desktop notification raised.
Follow motion
An optional mode that points the view at whatever is detecting: one camera fills the pane, several appear as a grid, and each is held for a dwell period so the view does not flick away the moment someone stops moving.
Dual-lens as one camera
TrackMix and similar appear as a single camera rather than two. Scrolling up, or the PTZ zoom-in button, switches to the telephoto lens; zooming back out returns to the wide one.
An app shell, not a document window
Header
The wordmark, a segmented Live / Playback switch, then grid layout, page controls and
the snapshot, record, expand and fullscreen buttons. Everything else lives behind the
⋯ overflow button.
Sidebar
Devices and their channels with a status dot each. Click a channel to jump to it, double-click a device to return to the full grid, fold an NVR's channel list away with the chevron. Collapsed groups are remembered.
Right rail
Camera control above, event feed below. Both side panels can be hidden, and every divider drags.
Toasts, not a status bar
Transient messages appear over the video and then leave, rather than occupying a strip of window forever.
Shortcuts
| Key | Action |
|---|---|
| Ctrl + 1 / 2 | Live / Playback |
| Ctrl + S | Snapshot the selected camera |
| Ctrl + R | Toggle recording on the selected camera |
| ← / → | Page through the grid, or step camera to camera when one is expanded |
| F11 | Fullscreen |
| Esc | Leave fullscreen, then leave the expanded view |
Double-click a tile to expand it to fill the pane; double-click again to go back. Right-click a tile for per-camera actions.
Why cameras appear instantly
Opening an RTSP stream is expensive. Measured against an RLN36, connecting takes about three seconds and the first decodable picture arrives around seven — roughly half RTSP setup, half waiting for the camera's next keyframe. Tuning the client only trims the first half, so the real work is never reconnecting.
| Showing a camera | Time to first frame |
|---|---|
| Cold connect | 6.10 s |
| Adopting a warm stream | 0.07 s |
Off-screen cameras stay warm
Cameras you cannot currently see remain connected and demuxing, without decoding, holding the most recent keyframe. Showing one then costs a fourteenth of a second instead of six, because the session already exists and there is a keyframe to decode from immediately.
Tiles survive rebuilds
A camera that stays on screen through a layout change, page turn or follow-motion update keeps the connection it already has. Tiles that leave the screen are parked, still streaming, for twenty seconds.
Expanding upgrades in place
The sub stream keeps playing — live, not a frozen frame — while the main stream connects behind it, and the swap happens only once the main stream has decoded a picture. Leaving early simply cancels it.
Cheap at rest
All fifteen online channels of an RLN36 held warm at once measured 2.0 Mb/s in total and about nine per cent of one CPU core — against roughly 2.7 per cent per camera when actually decoding.
The remaining keyframe wait on a genuinely cold camera is set by the camera, not by Kestrel: lowering its I-frame interval in the Reolink settings shortens it directly.
On your disk, in the obvious places
| What | Where |
|---|---|
| Devices and preferences | ~/.config/kestrel/config.json, mode 0600 |
| Passwords | System keyring via Secret Service, falling back to the config file if no keyring is available |
| Snapshots, recordings, downloads | ~/Videos/Kestrel/, changeable in preferences |
The About dialog reports which password store is actually in use, so the fallback is never silent. Nothing is written anywhere else, and nothing is sent anywhere — see the privacy policy.
Get Kestrel for Linux
AppImage
One self-contained file: the binary plus ffmpeg's shared libraries. Nothing to install, no root, and no system ffmpeg, GStreamer or VLC dependency.
Download AppImageTarball
The same two components unpacked, for anyone who would rather not run an AppImage. The
binary carries an rpath of $ORIGIN/lib, so it finds its libraries beside it.
Verify what you downloaded against SHA256SUMS:
sha256sum -c SHA256SUMS
Running it
chmod +x Kestrel-0.1.0-x86_64.AppImage
./Kestrel-0.1.0-x86_64.AppImage
Release builds are linked against an older glibc than the machine that produced them, so the same file runs on distributions older than the build host.
Adding a device
Press + in the Cameras sidebar, enter the address, username and password, then use Test connection to confirm before saving — it reports the model, firmware and channel list it found. Point it at an NVR and every channel appears as its own tile.
Licensing
Kestrel for Linux is licensed under the MIT and Apache 2.0 licences, at your option. It bundles ffmpeg 7.1, built LGPL-only and shipped as shared libraries so the licence's replacement requirement is met by the shared-library mechanism itself. No GPL encoders are built in — Kestrel decodes; it never calls them. The full terms of use are in the Terms of Service.