commit 02a1b32f6354d21c58f4d2bd92c608b2ec120336
parent 155c468d6c81a5f1a7d352f27ffd8f354dcad6c2
Author: Kris Yotam <krisyotam@protonmail.com>
Date: Fri, 20 Feb 2026 09:35:16 -0600
Add README
Diffstat:
| A | README.md | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 116 insertions(+), 0 deletions(-)
diff --git a/README.md b/README.md
@@ -0,0 +1,116 @@
+# Simple Frame
+
+A lightweight command-line tool for extracting unique frames from video
+files. Built for research workflows where you need to dissect video
+content into distinct, non-duplicate images with timestamps.
+
+Simple Frame uses perceptual hashing to compare consecutive frames and
+only saves those that are visually distinct, drastically reducing the
+manual sorting required when working with extracted video stills.
+
+Written in C following the [suckless philosophy](https://suckless.org/philosophy/).
+
+## Usage
+
+```
+sframe [-v] [-t threshold] [-f png|jpg] [-o outdir] video [video...]
+```
+
+### Options
+
+| Flag | Description | Default |
+|------|-------------|---------|
+| `-t N` | Hash threshold (0–64). Lower = stricter, fewer duplicates pass through. 0 removes only exact duplicates. | `8` |
+| `-f fmt` | Output image format: `png` or `jpg` | `png` |
+| `-o dir` | Output directory | `~/frames` |
+| `-v` | Print version and exit | |
+
+### Examples
+
+Extract unique frames from a video:
+
+```sh
+sframe lecture.mp4
+```
+
+Use a stricter threshold with JPEG output:
+
+```sh
+sframe -t 4 -f jpg documentary.mkv
+```
+
+Process multiple videos into a custom directory:
+
+```sh
+sframe -o /tmp/research clip1.mp4 clip2.webm
+```
+
+## Output Structure
+
+```
+~/frames/
+└── lecture/
+ ├── lecture-00-00-01.234.png
+ ├── lecture-00-00-15.678.png
+ ├── lecture-00-01-02.345.png
+ └── ...
+```
+
+Each video gets its own subdirectory. Frames are named as
+`<video-name>-HH-MM-SS.mmm.<ext>` where the timestamp corresponds to
+the frame's position in the video.
+
+## How It Works
+
+1. Decodes every frame of the video using FFmpeg
+2. Scales each frame to 8x8 grayscale
+3. Computes a 64-bit average perceptual hash
+4. Compares the hamming distance against the previously saved frame's hash
+5. Saves the frame only if the distance exceeds the threshold
+
+This approach is fast and effective at eliminating duplicate and
+near-duplicate frames (static shots, slow pans, talking heads with
+minimal movement) while preserving genuine scene changes and visually
+distinct content.
+
+### Threshold Guide
+
+| Value | Behavior |
+|-------|----------|
+| `0` | Only removes pixel-identical frames |
+| `4` | Very strict — catches near-identical frames |
+| `8` | Balanced — good default for most content |
+| `16` | Loose — aggressive duplicate removal |
+| `32+` | Very aggressive — only major scene changes |
+
+## Dependencies
+
+- FFmpeg libraries: `libavformat`, `libavcodec`, `libavutil`, `libswscale`
+- `libpng`
+- `libjpeg`
+
+### Arch Linux
+
+```sh
+pacman -S ffmpeg libpng libjpeg-turbo
+```
+
+### Debian/Ubuntu
+
+```sh
+apt install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libpng-dev libjpeg-dev
+```
+
+## Building
+
+```sh
+make
+sudo make install
+```
+
+Edit `config.mk` to change compile-time defaults (output format,
+default threshold).
+
+## License
+
+MIT