Skip to content

Repository files navigation

# -*- mode: org;  coding: utf-8; -*-
#+title: video utilities

Various utilities for video editing and manipulation.

* Install

Requires [[https://janet-lang.org/][Janet]] (>= 1.41) and =ffmpeg= installed somewhere on =$PATH=

The scripts can be run from the command line using janet
#+BEGIN_SRC shell
janet script.janet
#+END_SRC

or
#+BEGIN_SRC shell
./script.janet
#+END_SRC

compiled binaries can be created using =jpm= and installed somewhere on =$PATH=
 #+BEGIN_SRC shell
 jpm build
 # optionally move binaries from build/ folder to $PATH
 mv build/colourgrade build/colourstrip build/scenesplit build/slitscan build/slidestitch /usr/local/bin/.
 #+END_SRC

The scripts are written as wrappers around specific =ffmpeg= or =ffprobe= commands, and can be extended if required by directly editing the calls to =ffmpeg= and adding any required args (e.g. to change output quality or format).

* scenesplit

Split video files into individual scenes and generate an HTML overview.

Uses =ffmpeg= scene detection to find cut points in video files, extracts a JPEG thumbnail for each scene, and optionally cuts each scene into a separate video file. Outputs an HTML overview. Accepts either a single video file or a directory of videos.

[[file:img/scenesplit.webp]]

** Usage

#+begin_example
scenesplit [OPTIONS]
#+end_example

*Options*
|-----------------+--------------------------------------------------------+---------------|
| Flag            | Description                                            | Default       |
|-----------------+--------------------------------------------------------+---------------|
| =--input FILE=    | Single video file or directory containing videos       | =.=             |
| =--output DIR=    | Output directory for thumbnails, clips, and the HTML   | =scenes_output= |
| =--cut=           | Also cut each scene into a separate video file         | off           |
| =--ext EXT=       | File extension for cut scene clips                     | =.mp4=          |
| =--threshold NUM= | Scene detection threshold 0.0–1.0, lower = more splits | =0.3=           |
| =--light=         | Use light theme for HTML report                        | off           |
| =--dark=          | Use dark theme for HTML report                         | on            |
|-----------------+--------------------------------------------------------+---------------|

** Examples

Process all videos in the current directory, generate thumbnails only
#+begin_src sh
scenesplit
#+end_src

Process a single video file
#+begin_src sh
scenesplit --input clip.mp4
#+end_src

Process a single file with a custom output directory
#+begin_src sh
scenesplit --input vacation.mp4 --output ~/output/inferno
#+end_src

Process a specific folder with a custom output directory
#+begin_src sh
scenesplit --input ~/Videos/raw --output ~/Videos/scenes
#+end_src

Cut scenes into separate files and lower the detection threshold
#+begin_src sh
scenesplit --input ./footage --cut --threshold 0.2
#+end_src

Output cut scenes with a different container format
#+begin_src sh
scenesplit --cut --ext .mkv --input ./footage
#+end_src

Without =--cut=, only the =.jpg= thumbnails and =scenes.html= are generated

** Scene detection

The =--threshold= flag controls ffmpeg's scene detection sensitivity. It maps to the =select= filter's =scene= value.

- =0.1= -- very sensitive, many small scenes
- =0.3= -- generally balanced default
- =0.5= -- conservative, only large transitions
- =1.0= -- disables scene detection

* colourgrade

Automated colour grading using HaldCLUT (Color Lookup Table) with ffmpeg.

Generates a HaldCLUT identity image with a reference frame from the video. The image can be edited in any image editor to apply colour grading. The modified CLUT can then be applied to the entire video.

[[file:img/colourgrade.webp]]

Further reading: https://rawpedia.rawtherapee.com/Film_Simulation

** Usage

Generate a HaldCLUT identity image (outputs =VIDEO_clut.png=)
#+begin_src sh
colourgrade footage.mp4
#+end_src

Generate CLUT from a frame at a specific timestamp
#+begin_src sh
colourgrade --frame-time 0:01:30 footage.mp4
#+end_src

Apply an edited CLUT to a video
#+begin_src sh
colourgrade --lut footage.mp4_clut.png footage.mp4 graded.mp4
#+end_src


*Options*
|-------------------+--------------------------------------------------+---------|
| Flag              | Description                                      | Default |
|-------------------+--------------------------------------------------+---------|
| =--lut FILE=        | HaldCLUT PNG file (if provided, applies grading) |         |
| =--frame-time TIME= | Timestamp for reference frame (generate only)    | =0:00:04= |
|-------------------+--------------------------------------------------+---------|

** Workflow

The utility applies a CLUT to an entire video file. If there is more than one grading required in a video, cut into scenes and repeat the process for each scene.

Generate the HaldCLUT identity image
   #+begin_src sh
colourgrade footage.mp4
   #+end_src

Open =clut.png= in an image editor (GIMP, Photoshop, etc.)

Adjust the levels and/or curves for the entire image to create the desired look. The left side of the image is the CLUT and right side a reference frame from the video. Adjusting the image until the reference frame looks correct will also adjust the CLUT.

Save the edited PNG and apply to the video
   #+begin_src sh
colourgrade --lut footage.mp4_clut.png footage.mp4 graded.mp4
   #+end_src

* colourstrip

Create a colour strip visualization from a video.

Extracts a single pixel column from averaged frames and combines them into a horizontal strip showing the colour progression of the video. Useful for visualizing overall colour palette and transitions in a video.

[[file:img/colourstrip.webp]]

** Usage

#+begin_example
colourstrip VIDEO [OPTIONS]
#+end_example

*Options*
|------------------+----------------------------------------------+-----------|
| Flag             | Description                                  | Default   |
|------------------+----------------------------------------------+-----------|
| =--output FILE=    | Output PNG file                              | =strip.png= |
| =--frame-skip NUM= | Number of frames to average per pixel column | =15=        |
| =--blur NUM=       | Horizontal blur size for the final strip     | =3=         |
|------------------+----------------------------------------------+-----------|

** Examples

Create a strip with default settings
#+begin_src sh
colourstrip footage.mp4
#+end_src

Create a strip with custom frame skip
#+begin_src sh
colourstrip footage.mp4 --output the_strip.png --frame-skip 30
#+end_src

Create a strip with more blur
#+begin_src sh
colourstrip footage.mp4 --blur 5
#+end_src

* slitscan

Create temporal smear videos from a video file.

Generates horizontal and vertical "slitscan" effects by extracting individual pixel slices from each frame and tiling them together.

Based on [[https://github.com/zzkt/slitscan]]

** Usage

#+begin_example
slitscan VIDEO [OPTIONS]
#+end_example

*Options*
|------------------+--------------------------------------------------------------+----------|
| Flag             | Description                                                  | Default  |
|------------------+--------------------------------------------------------------+----------|
| =--output FILE=    | Output file prefix (prepended to horizontal/vertical suffix) | =slitscan= |
| =--width NUM=      | Resize width for processing                                  | =160=      |
| =--height NUM=     | Resize height for processing                                 | =90=       |
| =--cleanup=        | Remove temporary files after completion                      | off      |
| =--verbose=        | Show frame extraction progress                               | off      |
| =--loglevel LEVEL= | ffmpeg log level (quiet/error/warning/info)                  | =error=    |
|------------------+--------------------------------------------------------------+----------|

** Examples

Create slitscan videos with default settings
#+begin_src sh
slitscan footage.mp4
#+end_src

Create with custom dimensions
#+begin_src sh
slitscan footage.mp4 --width 320 --height 180
#+end_src

Clean up temporary files after completion
#+begin_src sh
slitscan footage.mp4 --output slitscan_atemporal --cleanup
#+end_src

** Output

The script produces two MKV files:

- =<output>_horizontal-smear.mkv= — horizontal frame smearing effect
- =<output>_vertical-smear.mkv= — vertical frame smearing effect

* scenephash

Split video into scenes using perceptual hashing.

Uses pHash DCT hashing on keyframes to detect scene changes and split video at those points into separate files.

** Usage

#+begin_example
scenephash VIDEO [OPTIONS]
#+end_example

*Options*
|---------------------+------------------------------------------------------+-----------|
| Flag                | Description                                          | Default   |
|---------------------+------------------------------------------------------+-----------|
| =--output PREFIX=     | Output file prefix                                   | =scenes=    |
| =--threshold NUM=     | Hamming distance threshold (0-64, lower=more scenes) | =10=        |
|---------------------+------------------------------------------------------+-----------|

** Examples

Split video into scenes with default threshold
#+begin_src sh
scenephash footage.mp4
#+end_src

Split with lower threshold for more scenes
#+begin_src sh
scenephash footage.mp4 --output my_scenes --threshold 5
#+end_src

* slidestitch

Create video from still images with crossfades.

Takes a directory of images and creates a video with smooth crossfade transitions between them. Supports lead-in/out fades, configurable fade duration, and optional displacement maps for effects.

** Usage

#+begin_example
slidestitch IMAGES OUTPUT [OPTIONS]
#+end_example

*Options*
|---------------------+------------------------------------------------------+-----------|
| Flag                | Description                                          | Default   |
|---------------------+------------------------------------------------------+-----------|
| =--scale MODE=       | Scale mode: stretch, contain, cover                  | =contain=   |
| =--lead-in SEC=      | Fade-in duration at start                            | =0=         |
| =--lead-out SEC=     | Fade-out duration at end                             | =0=         |
| =--fade SEC=         | Crossfade slope duration between images              | =1.0=       |
| =--duration SEC=     | Total video duration                                 | =10=        |
| =--displacement FILE=| Displacement map video for effects                   |             |
| =--fps NUM=          | Output frame rate                                    | =24=        |
|---------------------+------------------------------------------------------+-----------|

** Examples

Create a 60 second slideshow with 1 second crossfades
#+begin_src sh
slidestitch ./frames output.mp4 --duration 60 --fade 1
#+end_src

Create with lead-in/out fades and cover scaling
#+begin_src sh
slidestitch ./frames output.mp4 --scale cover --lead-in 2 --lead-out 2 --duration 30
#+end_src

Create with custom frame rate
#+begin_src sh
slidestitch ./frames output.mp4 --duration 20 --fps 30
#+end_src

About

Utilities for video editing and manipulation. scene splitting, colour grading, etc.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages