Squash Review
Turns phone video of a squash match into a review based on where the players stood.
Squash Review turns ordinary phone video of a squash match into a post-match review. It tracks both players on a to-scale model of the court, works out positional stats such as time on the T, court coverage and pressure, and has a language model turn those into a few coaching notes. Each note cites the stat behind it.
- Status
- Runs end to end on real footage (upload, tracking, report), tested at one venue with one camera so far. An iOS app is written but not yet tried on a device.

Overview§
Club and recreational players rarely get a clear answer to why they lose points. Coaching is expensive and comes in occasional lessons, and watching a whole match back on video is slow. Patterns like never getting back to the T, or losing most rallies in one back corner, are hard to see by eye. Squash Review is for players who already film their matches on a phone.
There are three steps: upload the match, pick a frame, then tap the four floor corners, both ends of the short line, and yourself. Processing runs in the background and usually takes a few minutes, so you can leave and come back. The report starts with coaching notes sorted by priority, each with the evidence, why it matters and a drill. After that come a heatmap of where you stood, your time on the T, and your rally patterns and lengths.
It works end to end on real footage, but it has only been tested at one venue with one camera, and the iOS app hasn't been run on a device yet. The camera has to sit outside the court with the floor lines in view. The video is deleted once it is processed. Only each player's position in court metres is kept.
Key facts§
- Calibrating from the back corners plus the short-line ends measured about 0.14 m of position error, against a 0.5 m target; the four corners alone gave about 0.96 m.
- Moving the worker from a CPU box to a consumer GPU made processing about 8.5× faster.
How it works§
The court mapping (a homography) maps points, not pixels. You tap court landmarks on one frame, and each player's foot position (the midpoint of the ankle keypoints) becomes a position in metres on the court. The image itself is never warped, because only the floor is flat and the standing players would come out skewed.

Marking the court: four floor corners, both short-line ends and yourself. This is what turns pixels into metres. Code does the counting and the model only interprets. A deterministic stats engine writes a short stat sheet using named zones and everyday units, with handedness handled in code. The model never sees per-frame data and must cite a stat for every claim, so a bad note can be traced to bad data or bad reasoning.
Tracking assumes exactly two players on a known court. That makes it a two-target assignment problem, solved frame by frame with the Hungarian algorithm. When the players overlap it records a gap instead of guessing. Which player is you is fixed by your own tap on yourself.
Rallies are found from sound and position. Ball strikes picked out of the soundtrack mark where rallies start and end. Combined with the tracks, they give each rally's length, shot count and where each player stood at the deciding shot.

Where you stood, how long you held the T, and how much of the rally you spent attacking. The vision worker pulls jobs from a Postgres queue, claims them atomically and sends heartbeats. It needs no inbound ports. A scheduled task takes back jobs from workers that stop responding. The video is deleted once processed.
Screens§
Built with§
- Next.js 16, also used in Aethalides, Jarvis for Projects, Ocr-kb-matcher (KIP), and Meridian
- TypeScript, also used in Sisyphus, Aethalides, Jarvis for Projects, Ocr-kb-matcher (KIP), Meridian, and Ship It Tracker
- Supabase
- Cloudflare R2
- Python, also used in Datacenter Tracker, mcAI, lidfold, and Learning RL by Playing Games
- YOLO11 pose
- OpenCV, also used in lidfold
- React Native / Expo


