sframe

Simple Frame — extract unique frames from videos
git clone git clone https://git.krisyotam.com/krisyotam/sframe.git
Log | Files | Refs | README | LICENSE

README.md (2868B)


      1 # Simple Frame
      2 
      3 A lightweight command-line tool for extracting unique frames from video
      4 files. Built for research workflows where you need to dissect video
      5 content into distinct, non-duplicate images with timestamps.
      6 
      7 Simple Frame uses perceptual hashing to compare consecutive frames and
      8 only saves those that are visually distinct, drastically reducing the
      9 manual sorting required when working with extracted video stills.
     10 
     11 Written in C following the [suckless philosophy](https://suckless.org/philosophy/).
     12 
     13 ## Usage
     14 
     15 ```
     16 sframe [-v] [-t threshold] [-f png|jpg] [-o outdir] video [video...]
     17 ```
     18 
     19 ### Options
     20 
     21 | Flag | Description | Default |
     22 |------|-------------|---------|
     23 | `-t N` | Hash threshold (0–64). Lower = stricter, fewer duplicates pass through. 0 removes only exact duplicates. | `8` |
     24 | `-f fmt` | Output image format: `png` or `jpg` | `png` |
     25 | `-o dir` | Output directory | `~/frames` |
     26 | `-v` | Print version and exit | |
     27 
     28 ### Examples
     29 
     30 Extract unique frames from a video:
     31 
     32 ```sh
     33 sframe lecture.mp4
     34 ```
     35 
     36 Use a stricter threshold with JPEG output:
     37 
     38 ```sh
     39 sframe -t 4 -f jpg documentary.mkv
     40 ```
     41 
     42 Process multiple videos into a custom directory:
     43 
     44 ```sh
     45 sframe -o /tmp/research clip1.mp4 clip2.webm
     46 ```
     47 
     48 ## Output Structure
     49 
     50 ```
     51 ~/frames/
     52 └── lecture/
     53     ├── lecture-00-00-01.234.png
     54     ├── lecture-00-00-15.678.png
     55     ├── lecture-00-01-02.345.png
     56     └── ...
     57 ```
     58 
     59 Each video gets its own subdirectory. Frames are named as
     60 `<video-name>-HH-MM-SS.mmm.<ext>` where the timestamp corresponds to
     61 the frame's position in the video.
     62 
     63 ## How It Works
     64 
     65 1. Decodes every frame of the video using FFmpeg
     66 2. Scales each frame to 8x8 grayscale
     67 3. Computes a 64-bit average perceptual hash
     68 4. Compares the hamming distance against the previously saved frame's hash
     69 5. Saves the frame only if the distance exceeds the threshold
     70 
     71 This approach is fast and effective at eliminating duplicate and
     72 near-duplicate frames (static shots, slow pans, talking heads with
     73 minimal movement) while preserving genuine scene changes and visually
     74 distinct content.
     75 
     76 ### Threshold Guide
     77 
     78 | Value | Behavior |
     79 |-------|----------|
     80 | `0` | Only removes pixel-identical frames |
     81 | `4` | Very strict — catches near-identical frames |
     82 | `8` | Balanced — good default for most content |
     83 | `16` | Loose — aggressive duplicate removal |
     84 | `32+` | Very aggressive — only major scene changes |
     85 
     86 ## Dependencies
     87 
     88 - FFmpeg libraries: `libavformat`, `libavcodec`, `libavutil`, `libswscale`
     89 - `libpng`
     90 - `libjpeg`
     91 
     92 ### Arch Linux
     93 
     94 ```sh
     95 pacman -S ffmpeg libpng libjpeg-turbo
     96 ```
     97 
     98 ### Debian/Ubuntu
     99 
    100 ```sh
    101 apt install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libpng-dev libjpeg-dev
    102 ```
    103 
    104 ## Building
    105 
    106 ```sh
    107 make
    108 sudo make install
    109 ```
    110 
    111 Edit `config.mk` to change compile-time defaults (output format,
    112 default threshold).
    113 
    114 ## License
    115 
    116 MIT