Skip to main content

559 named video transitions across four render backends

Project description

cut-fx

559 named video transitions across four render backends, with GPU acceleration when available.

Built at Trollfabriken AITrix AB to make programmatic video rendering match the visual vocabulary of consumer video editors. Five-hundred-and-fifty-nine named transitions across eleven taxonomy buckets, mapped to thirty-four hand-written base engines and parametric variants. Four render backends: ffmpeg filter_complex, NumPy/OpenCV procedural, HTML/CSS via web-overlay, and GLSL shaders. GPU acceleration when available, CPU fallback when not. One API: apply_transition(clip_a, clip_b, transition="atomic_teleport", output=...).


What it solves

Programmatic batch video rendering — AIMOS Insight municipal report videos, civic-education explainers, pipeline-driven content — needs named, repeatable transitions. ffmpeg's xfade covers dissolves. It does not cover 559 named effects. Writing each effect from scratch is not feasible.

Problem What cut-fx does
Named transitions not in ffmpeg xfade 559 catalog entries map to 34 base engines
Different effects need different render tech Four backends; catalog picks the right one
GPU present on some machines, absent on others Runtime detection; CPU fallback always works
LLMs need a machine-readable transition spec JSON schema export via cut_fx.schema
Beat-aligned cuts require audio analysis cut_fx.beats wraps audio-arrange
Lyric-timed transitions Optional lyric-sync integration

Installation

pip install cut-fx

Runtime requirement: ffmpeg >= 6.0 must be on PATH.

# Ubuntu / Debian
sudo apt-get install ffmpeg

# macOS
brew install ffmpeg

# Windows
choco install ffmpeg

Extras:

Extra Installs Enables
overlay web-overlay HTML/CSS/SVG transitions (light_fx, particle_nature, graphic_stylized)
shader moderngl, moderngl-window GLSL shader transitions; requires OpenGL 3.3+
beats audio-arrange, librosa Beat-synced cut placement
lyrics lyric-sync Lyric-timed transitions
all all of the above Full feature set
dev pytest, ruff, build, pillow Development tools
pip install "cut-fx[overlay,shader,beats]"
pip install "cut-fx[all]"

Quick start

from cut_fx import apply_transition

apply_transition(
    clip_a="intro.mp4",
    clip_b="main.mp4",
    transition="atomic_teleport",
    output="combined.mp4",
    overlap_seconds=0.8,
)

List what is available:

from cut_fx import list_transitions, list_categories

list_categories()
# ['motion', 'rotation', 'shape_mask', 'optical_blur', 'light_fx',
#  'particle_nature', 'graphic_stylized', 'digital_glitch',
#  'grid_card_layout', 'film_retro', 'general_fx']

list_transitions(category="digital_glitch")
# ['Capture Glitch 2', 'Console Buzz', 'Cyber Beehive', 'Cyber Flare',
#  'Cyber Phantom', 'Hologram Shred', ...]

Inspect a specific transition:

from cut_fx import get_transition_info

info = get_transition_info("cyber_phantom")
# TransitionInfo(
#     name='Cyber Phantom',
#     slug='cyber_phantom',
#     category='digital_glitch',
#     base_engine='glitch_scan',
#     parameters={'intensity': 0.7, 'scan_lines': 12, 'color_shift': True},
#     backends=['procedural', 'shader'],
# )

The catalog

The catalog (cut_fx/data/transitions_catalog.json) lists 559 transition names across 11 taxonomy buckets. Behind those names are 34 base engine implementations. Each base engine accepts parameters: direction, easing, intensity, colour, shape, count, duration curve.

The 559 → 34 design: a named transition is a (base_engine, parameter_set) tuple. Adding a new named variant means adding one JSON entry — no new Python code.

Bucket Transitions Base engines Example named variants
motion 119 4 180 Wipe, Block Slides, Push Right
light_fx 93 5 Basic Flash, Bright Flash, Crescent Sparks
grid_card_layout 47 3 3-block Swing, 3D Card 2, Bizarre Rubik
rotation 46 3 3-flap Turn, 3D Flip, Calendar Flip
shape_mask 44 4 Circle, Comic Cutout, Blast Door
film_retro 35 3 B&W Arrows, Black Smoke, Black Fade
optical_blur 31 3 Auto Focus, Blur & Zoom, Blur Focus
particle_nature 22 3 Bubble Blur, Crystal Energy, Dust Flurry
digital_glitch 16 4 Cyber Phantom, Hologram Shred, Console Buzz
graphic_stylized 12 2 Comic Cut, Glowing Graffiti, Light Graffiti I
general_fx 94 (composed) 3D Glass, Atomic Teleport, Acrylic Fades

The general_fx bucket entries are composed from existing base engines. "Atomic Teleport" is a light_fx flash + shape_mask radial + motion zoom-out, assembled in sequence.

Inspect catalog totals at runtime:

from cut_fx.catalog import catalog_summary

print(catalog_summary())
# {'total': 559, 'categories': 11, 'base_engines': 34, ...}

Render engines

Each catalog entry specifies which backend handles it. The dispatch is automatic.

Engine Handles Implementation
ffmpeg motion, rotation, optical_blur, simple wipes filter_complex with crop/scale/translate/rotate expressions; xfade for cross-dissolves
procedural digital_glitch, film_retro, custom pixel math NumPy + OpenCV; frame-by-frame in Python
overlay light_fx, particle_nature, graphic_stylized, shape_mask HTML/CSS/SVG via web-overlay; alpha-composited over ffmpeg base
shader Premium light_fx variants, refraction, fluid sim GLSL via moderngl; optional; CPU fallback to procedural when absent

The overlay engine requires pip install "cut-fx[overlay]" and a headless Chromium install (playwright install chromium). The shader engine requires pip install "cut-fx[shader]" and OpenGL 3.3+ context support.

Force a specific backend:

apply_transition(
    clip_a="a.mp4",
    clip_b="b.mp4",
    transition="basic_flash",
    output="out.mp4",
    backend="procedural",  # override automatic selection
)

Hardware acceleration

At import time, cut_fx probes for hardware encoders and GPU context.

from cut_fx.gpu import gpu_status

print(gpu_status())
# {
#   'ffmpeg_hwaccel': 'nvenc',       # or 'videotoolbox', 'qsv', None
#   'opengl_available': True,
#   'opengl_renderer': 'NVIDIA GeForce RTX 3080',
#   'shader_backend': 'moderngl',    # or 'procedural' (fallback)
# }

Acceleration paths:

  • ffmpeg hardware encoders: NVENC (NVIDIA), VideoToolbox (Apple), QSV (Intel). Detected via ffmpeg -hwaccels. Falls back to libx264/libx265 when none is found.
  • GLSL shader engine: requires a real GPU context. Falls back to the procedural (NumPy/OpenCV) implementation automatically — output is identical, speed is lower.

Print a summary from the CLI:

cut-fx gpu

No GPU is required. All 559 transitions render on CPU.


Beat-synced cuts

Requires pip install "cut-fx[beats]".

from cut_fx.beats import transitions_on_beats

transitions_on_beats(
    clips=["clip1.mp4", "clip2.mp4", "clip3.mp4", "clip4.mp4"],
    audio="track.mp3",
    transition="cyber_phantom",
    output="beat_video.mp4",
    beats_per_cut=2,       # place a cut every 2 beats
    overlap_seconds=0.4,
)

transitions_on_beats uses audio-arrange to extract beat timestamps, then places transitions at beat boundaries. The beats_per_cut parameter controls cut density. Fractional values are supported: beats_per_cut=0.5 cuts on every half-beat.

For lyric-timed cuts, add pip install "cut-fx[lyrics]":

from cut_fx.beats import transitions_on_lyrics

transitions_on_lyrics(
    clips=["verse.mp4", "chorus.mp4"],
    lyrics_file="song.lrc",
    transition="light_burst",
    output="lyric_video.mp4",
)

LLM integration

cut_fx.schema exports a JSON Schema describing every valid transition call. Pass it to an LLM as a tool definition.

from cut_fx.schema import transition_spec_schema

schema = transition_spec_schema()
# {
#   "$schema": "https://json-schema.org/draft/2020-12/schema",
#   "title": "TransitionSpec",
#   "type": "object",
#   "properties": {
#     "transition": {"type": "string", "enum": ["atomic_teleport", "cyber_phantom", ...]},
#     "overlap_seconds": {"type": "number", "minimum": 0.1, "maximum": 5.0},
#     "backend": {"type": "string", "enum": ["auto", "ffmpeg", "procedural", "overlay", "shader"]},
#     ...
#   },
#   "required": ["transition"]
# }

Feed the schema to an LLM as a function spec. The LLM returns a valid TransitionSpec object. Pass it directly to apply_transition:

from cut_fx import apply_transition
from cut_fx.config import TransitionConfig

spec = TransitionConfig(**llm_response)
apply_transition(clip_a="a.mp4", clip_b="b.mp4", output="out.mp4", **spec.model_dump())

CLI

Apply a transition between two clips:

cut-fx apply intro.mp4 main.mp4 --transition atomic_teleport --output combined.mp4

List all transitions in a category:

cut-fx list --category digital_glitch

List all categories with transition counts:

cut-fx categories

Show detail for a named transition:

cut-fx info cyber_phantom

Render a short preview (3-second synthetic clips):

cut-fx preview atomic_teleport --output preview.mp4

Show GPU and hardware encoder status:

cut-fx gpu

Package structure

cut-fx/
├── src/
│   └── cut_fx/
│       ├── __init__.py          # public API re-exports
│       ├── api.py               # apply_transition, apply_sequence, list_*
│       ├── catalog.py           # loads transitions_catalog.json
│       ├── config.py            # TransitionConfig (pydantic model)
│       ├── schema.py            # JSON schema export for LLM tool use
│       ├── gpu.py               # hardware detection
│       ├── beats.py             # beat-synced and lyric-synced cuts
│       ├── cli.py               # cut-fx command-line entry point
│       ├── data/
│       │   ├── transitions_catalog.json   # 559 entries
│       │   └── engine_mapping.json        # slug → base_engine lookup
│       └── engines/
│           ├── base.py          # abstract BaseEngine
│           ├── dispatcher.py    # selects engine per catalog entry
│           ├── ffmpeg/          # filter_complex builder
│           ├── procedural/      # NumPy + OpenCV per-frame
│           ├── overlay/
│           │   └── templates/   # HTML/CSS/SVG transition templates
│           └── shader/
│               └── glsl/        # .vert / .frag shader sources
├── tests/
├── pyproject.toml
├── README.md
└── LICENSE

© Trollfabriken AITrix AB — MIT licensed

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cut_fx-0.1.2.tar.gz (69.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cut_fx-0.1.2-py3-none-any.whl (89.4 kB view details)

Uploaded Python 3

File details

Details for the file cut_fx-0.1.2.tar.gz.

File metadata

  • Download URL: cut_fx-0.1.2.tar.gz
  • Upload date:
  • Size: 69.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cut_fx-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5bccbd66235e498d46d54b83ec32b567d9914312d3d772e13e14a47912075f4a
MD5 78db9683c77ae78e7fca90330f183069
BLAKE2b-256 faee0ff5cbb16e0c30dc80dc2fa10767d67358b98902c07bc0be9bc0805f0f5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for cut_fx-0.1.2.tar.gz:

Publisher: release.yml on tomastimelock/cut-fx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cut_fx-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cut_fx-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 89.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cut_fx-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b6ffd5f90b7e77ef1622f7e98760ab104d03e7c2c366cdea59f30a451e3d0e90
MD5 786837e094863aa26f5932f7949df5f0
BLAKE2b-256 4913d6f457d2e1a24ec7ed3fbf627f5804b68fc516f663fbf33c32d0801025df

See more details on using hashes here.

Provenance

The following attestation bundles were made for cut_fx-0.1.2-py3-none-any.whl:

Publisher: release.yml on tomastimelock/cut-fx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page