Overview
One app for your cameras and recorders, through a small server on your own network.
Kestrel is one app for your cameras and recorders: live view, recordings, events and each one’s health, from any browser or as an app on your phone. It talks to each system directly, so nothing goes through a vendor’s cloud and old hardware stays useful after its own apps stop working.
It starts with Raysharp-made recorders, which Swann, Lorex, Night Owl and others sell, and whose own apps and plugins have stopped working in modern browsers. Reolink cameras, a Bambu Lab printer’s camera, any stream address and recording to your own disk are on the way, as timmo001/kestrel#11 sets out.
A small server sits between your cameras and the page. Browsers can’t open a recorder’s control port or play its RTSP streams, so the server holds the sessions, passes on what they report, and runs go2rtc for the video. See Running it to set it up.
What it does
- Sources: each source’s connection and, for the recorder, its clock, its disks, and each camera’s signal, recording mode and motion.
- Recordings: which days have recordings, and each day’s clips on a channel, with why they were recorded (motion, PIR, alarm or normal) and their size. The player is laid out as the recorder’s own client lays out playback: the video, its controls (stop, a frame at a time, speed up to 32 times, the recordings either side, cut, a still, download, the same zoom as Live (fit, fill or a step at a time, only for the visit) and full screen, each with a key, listed under the help button), then a timeline of the day that zooms to ten minutes, where a click plays from that moment. Playback runs on from one recording into the next, any stretch of a day saves as an MP4, and the page remembers where it was, its speed and its timeline zoom in the browser. Up to four cameras play together on one clock, ticked in the camera picker: each one that recorded at that moment plays, the rest show a placeholder until their next recording, and the timeline has a track for each. They play the full stream while the recorder keeps up, about 14 times real time across them, and the sub stream past that.
- Pages: Live, Recordings, Events and Sources each have an address of
their own, such as
/recordings?camera=swann/1&date=2026-11-11, or/recordings?camera=swann/1&cameras=swann/1,swann/3,swann/4&date=2026-11-11for several cameras together. A camera’s id is its source’s and its own, such asswann/3for the recorder’s channel 3. Older addresses by channel number still work. - Events: motion, PIR, video loss and disk events as each source reports them, and today’s motion and PIR clips found by search.
- Live view: the cameras with a signal through go2rtc, all at once (A, shown as the count and All) or any number fewer at a time (from the sub stream past four), paged with Previous and Next (Page Up and Page Down) or picked from the page list, which names each camera when there’s one at a time. All is the default. The arrow keys move the pick around the page and on to the next page past the edge. Each picture keeps its shape, fitted whole into its tile. The zoom controls act on the picked camera, and each camera keeps its own zoom, once in the tiles and once on its own (so one zoomed in its tile still shows whole alone). It zooms 25% at a time (+, - and 0 to fit it whole), with Fill, where the picture covers its tile, one of the steps, so Fit or Fill (Z) jumps between whole and covering. Ctrl and the wheel or a pinch zooms the one under the pointer, and a drag moves around any picture bigger than its tile. Pause closes the streams and holds the last frames; a double click or Enter shows the picked camera alone, and Esc or Backspace goes back. S saves a still of it, and ? shows or hides the keys. The layout, the picked camera, each camera’s zoom and how many cameras there were are kept in the browser, so the loading placeholders already sit where the cameras will.
Parts
| Part | What it is |
|---|---|
packages/core |
What every source shares, in TypeScript with Effect |
packages/protocol-raysharp |
The Raysharp recorders’ control protocol |
packages/source-raysharp |
Raysharp recorders as a source, over that protocol and their RTSP |
packages/protocol-baichuan |
Reolink’s own protocol, for replaying recorded files |
packages/server |
The server: the API and go2rtc |
packages/web |
The web client, installable on a phone |
packages/cli |
The kestrel CLI, with Code Mode and MCP for agents |
docs |
This site |
Machine-readable docs
| URL | Use |
|---|---|
| https://kestrel.timmo.dev/llms.txt | Compact page index |
| https://kestrel.timmo.dev/llms-full.txt | Full docs bundle |
| https://kestrel.timmo.dev/mcp | Hosted MCP (search, page and navigation) |
/{route}.md |
One page as Markdown |