Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
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