Building vidgrep

grep, but for video — scan hours of footage for text or visual patterns and get back short, padded clips of every match, or data showing you the timestamps of search occurrences. Comes with a resumable batch worker.

July 8, 2026

grep, but for video — scan hours of footage for text or visual patterns and get back short, padded clips of every match, or data showing you the timestamps of search occurrences. Comes with a resumable batch worker.

The problem

Finding one moment in hours of recorded video is miserable. Text is searchable; video is not. I kept scrubbing through recordings looking for the few seconds where a specific word appeared on screen, and every time I thought the same thing: I should be able to grep this.

picture of video files in a folder
Video files in a folder

vidgrep is that idea taken literally — point it at a directory of video files, give it a search term (or a template image), and it hands back a folder of short clips or data containing every match.

Data of full line text within region
Data of full line text within region

How it works

The pipeline is deliberately boring: FFmpeg samples frames at a configurable interval, OpenCV preprocesses them, then either an OCR pass looks for the search text or template matching looks for a reference image. Hits that fall within a merge window collapse into a single event, and FFmpeg cuts a padded clip around each one.

python main.py worker videos.csv --text "uwdivad" --region 132 476 592 388 --interval 2 --batch-size 32
  • Frame sampling instead of full decode — scanning stays orders of magnitude faster than playback
  • Matches within a merge window become one clip instead of dozens of near-duplicates
  • Padding is applied on both sides of a match so clips keep their context
marked region for ocr
Marked regions

The batch worker

Scanning a big library takes a while, and long jobs get interrupted. The batch worker journals its progress per file, so a killed run resumes where it stopped instead of starting over — finished files are skipped, half-scanned files restart cleanly.

Im running this all locally, using the scanner I generated a csv file of all of the videos I want to process. The process updates the csv to keep track of has or hasnt been scanned

The TUI dashboard (in progress)

A long-running CLI with no feedback feels broken. Although there is stats / metrics logging, the live dashboard shows per-file progress, match counts as they land, and throughput — enough to tell at a glance whether a scan is worth waiting on or worth re-tuning.

What I am working on next

  • De-normalizing the data

The code is on [GitHub](https://github.com/uwdivad/vidgrep) — issues and ideas welcome.

Back to David Wu's portfolio