Skip to main content

Declarative video compilation engine — write timelines in .ktx text, compile to .mp4

Project description

English 中文版

KinetiX logo

KinetiX

License: MIT Python 3.10+

The LaTeX of Video — a declarative video compilation engine.

Goodbye drag-and-drop, hello code-first.
No AI magic — pure logic-driven timelines.
Ditch the GUI, embrace hacker workflows.

KinetiX demo

Quick Start

Prerequisites: Python ≥ 3.10. ffmpeg (optional, for --live preview only).

pip install kinetix-video

Grab the demo.ktx and test assets, then:

kinetix demo.ktx                # compile to demo.mp4

To hack on the source:

git clone git@github.com:Bruce-lhq/kinetix-video.git
cd kinetix-video
pip install -e .

CLI

kinetix <input.ktx> [output.mp4] [options]

Options:
  --live                Live preview via ffplay (no encoding)
  --preview START-END   Render a time slice, e.g. --preview 00:30-01:00
  --graph               Generate timeline topology PNG (no video render)
  --no-subtitles        Skip SRT subtitle rendering

Template Variables

.ktx files support Jinja2-style {{ variables }} for batch video generation:

[t1]: text("Hi {{ user.name }}, score: {{ score }}", font: heiti, size: 56)
[v1]: {{ bg_video }}
[v1] @ 00:00 | duration: {{ duration }}s
# From CLI — single vars
kinetix template.ktx --var user.name=Alice --var score=95

# From CLI — JSON file
kinetix template.ktx --data vars.json

# From Python
from kinetix.main import compile_template
compile_template("template.ktx", {"user": {"name": "Alice"}, "score": 95})

Install with template support: pip install kinetix-video[template]

VS Code Extension

Syntax highlighting + frame snapshot preview for .ktx files.

cp -r vscode-ktx ~/.vscode/extensions/ktx-syntax-0.2.0/

Then Cmd+Shift+PDeveloper: Reload Window. Open any .ktx file:

Feature How
Syntax highlighting Automatic on .ktx files
Snapshot preview Ctrl+Shift+K → enter time → frame renders in side panel
Command palette Cmd+Shift+PKinetiX: Snapshot Frame at Time

The snapshot command renders a single frame at any timecode (e.g. 5, 1:30, 00:05) as a full-resolution PNG for quick visual inspection.

.ktx Syntax

Asset Declarations

[v1]:  clips/video.mp4 [tag1, tag2]     # video with tags
[img]: clips/photo.jpg [overlay]        # image
[bgm]: clips/music.mp3                  # audio
[t1]:  text("Line 1\nLine 2", font: songti, bg_opacity: 0.5)

Supported formats: .mp4 .mov .avi .mkv | .jpg .jpeg .png .bmp .gif | .mp3 .wav .aac .flac .m4a

Style Macros

Define Style("intro"):
  fadein: 1s
  layer: 0
  transition: "crossfade", dur: 0.5s
  filter: "blackwhite"

[v1] @ 00:00 | style: "intro" | mute: true

Style properties: fadein fadeout transition volume mute layer anchor filter speed. Entry values override style defaults.

Timeline

# Expression time — anchor to any named clip
[v2] @ v1.end - 1s | layer: 0
[a1] @ v1.start + 2s | layer: 0

# prev.end chains (audio/video tracked independently)
[v3] @ prev.end | layer: 0

# Split: same asset, different segments
[v_part1] @ 00:00 | trim_start: 0s | trim_end: 5s
[v_part2] @ prev.end | trim_start: 5s | trim_end: 10s

# Audio ducking roles
[voice] @ 00:00 | role: voice
[bgm]   @ 00:00 | role: bgm | volume: -20

Timeline Properties

Property Value Description
duration 10s Override asset duration
layer 0, 1, … Z-order (0 = bottom)
pos (x, y) or (50vw, 30vh) Pixel or relative position
anchor (0, 0) Relative anchor point
style "intro" Reference a Style macro
crop (x, y, w, h) Frame crop
trim_start 2s Start time trim
trim_end 8s End time trim
filter "blackwhite" Global filter
transition "crossfade" Entrance transition
fadein / fadeout 1s Fade in/out (video + audio)
mute true Mute video track
speed 2 Playback speed (affects timeline)
volume -28 Volume in dB
role voice / bgm / sfx Audio role (for ducking)

trim_start + duration can be combined without trim_end: the clip will span [trim_start, trim_start + duration].

Position Units (CSS-like)

pos supports mixed units that auto-scale when you change output resolution:

Unit Meaning Example
vw % of canvas width 50vw = half canvas width
vh % of canvas height 30vh = 30% canvas height
pw % of asset width 10pw = 10% of image/video width
ph % of asset height 5ph
px / number Absolute pixels 200px = 200px
[img] @ 00:05 | pos: (50vw, 30vh)    # relative
[img] @ 00:05 | pos: (100, 200)      # absolute pixels

Anchor Coordinates

anchor: (x, y)   # x, y ∈ [-1, 1], screen coords (y↓)
Coord Position Coord Position Coord Position
(-1,-1) Top-left (0,-1) Top-center (1,-1) Top-right
(-1, 0) Mid-left (0, 0) Center (1, 0) Mid-right
(-1, 1) Bot-left (0, 1) Bot-center (1, 1) Bot-right

Keyframe scale is applied before anchor. pos takes priority over anchor.

Keyframes & Easing

[img1]:
  scale:  { 0s: 0.5, 5s: 1.2, curve: "ease_in_out" }
  pos:    { 0s: (0,0), 5s: (200,100) }
  opacity:{ 0s: 0.0, 1s: 1.0, 4s: 1.0, 5s: 0.0 }
  rotate: { 0s: 0, 5s: 90 }

Easing curves: linear (default) | ease_in | ease_out | ease_in_out

Filters

Value Effect
blackwhite Grayscale
invert Invert colors
mirror_x Horizontal flip
mirror_y Vertical flip
painting Oil-painting effect

Text Cards

[t]: text("Content", font: songti, size: 64, bg_opacity: 0.3, color: "#FFFFFF", stroke_width: 2, stroke_color: "#00000060")

Parameters can appear in any order. Defaults:

Parameter Default Description
font heiti songti / heiti
size Auto Font size in px
bg_opacity 0.0 0=transparent, 1=solid background
color #FFFFFF Text color
bg #000000 Background color
stroke_width 0 Text outline width in px
stroke_color #000000 Stroke color (supports alpha: #00000060)

Auto word-wrap with \n for hard line breaks. Text clips render at natural size (transparent RGBA), centered on canvas by default. Use opacity keyframes for true transparent fade-in/out.

Subtitles

Subtitles: subtitles.srt

Standard SRT format, rendered at the bottom of the frame.

Output Config

Format: mp4, Res: 1080p, FPS: 30

Res options: 480p 720p 1080p 4k

Complete Example

See the full demo.ktx in the repo — a multi-scene promotional clip with text overlays, easing keyframes, and live preview support. Run it with:

kinetix demo.ktx              # compile to demo.mp4
kinetix demo.ktx --live       # real-time preview via ffplay
kinetix demo.ktx --graph      # generate timeline topology PNG

Minimal example showing all core features:

Define Style("cinematic"):
  layer: 0
  transition: "crossfade", dur: 2.4s

[v1]: test_assets/v_chaos.mp4
[v2]: test_assets/v_order.mp4
[logo]: test_assets/logo.png
[bgm]: test_assets/bgm_epic.mp3
[t1]: text("Goodbye drag-and-drop, hello code-first editing", font: songti, size: 64,
           stroke_width: 2, stroke_color: "#00000060")

[bgm] @ 00:00 | volume: -10 | trim_start: 24s | duration: 16s | fadein: 1s | fadeout: 3s
[v1]  @ 00:00 | style: "cinematic" | mute: true | duration: 7.5s
[t1]  @ 1s    | duration: 3s
[v2]  @ v1.end - 2.4s | style: "cinematic" | mute: true | duration: 7.5s
[logo] @ v2.end - 2.5s | layer: 1 | duration: 5s

[v1]:
  scale: { 0s: 1.0, 7.5s: 1.12, curve: "ease_in" }

[t1]:
  scale: { 0s: 0.85, 3s: 1.0, curve: "ease_out" }
  opacity: { 0s: 0.0, 0.6s: 1.0, 2.4s: 1.0, 3s: 0.0, curve: "ease_in_out" }

[logo]:
  scale: { 0s: 0.22, 1.8s: 0.35, curve: "ease_out" }
  rotate: { 0s: -18, 1.8s: 0, curve: "ease_out" }
  opacity: { 0s: 0.0, 1.0s: 1.0, curve: "ease_out" }

Format: mp4, Res: 1080p, FPS: 30

Architecture

parse(.ktx) → apply_styles → resolve_timeline → render(.mp4) | live_preview(ffplay) | graph(.png)

Generate a timeline topology graph with kinetix demo.ktx --graph:

Timeline graph

Roadmap & Contributing

KinetiX is a lean, focused MVP right now — a timeline engine that does one thing well. The fun stuff is planned. If any of these excite you, PRs are wide open.

Template-driven video ✅

Jinja2-style {{ variables }} in .ktx files, with a Python API to feed data in.

[t1]: text("Hi {{ user.name }}, your score is {{ score }}", font: heiti, size: 56)

Batch-render thousands of personalized clips from a CSV. Think: marketing, recruiting, onboarding — every SaaS company's dream.

Plugin system

Expose a hook interface so developers can ship custom effects without touching KinetiX core.

[v1] | plugin: "edge_glow", radius: 5, intensity: 1.2

CV researchers get a timeline engine; KinetiX gets their visual algorithms. Everyone wins.

Hardware-accelerated render backend

Right now KinetiX renders frame-by-frame via moviepy on CPU. The goal: a compiler that translates .ktx directly into an FFmpeg filtergraph, hitting NVENC / VideoToolbox for native-speed GPU encodes. C++ and Rust performance nerds, this one's for you.

Web playground

Monaco editor on the left, Wasm-powered preview on the right. Write .ktx in the browser, see the result instantly. No Python install required. Frontend hackers, assemble.

Native LLM bindings

kinetix.ask("speed up this video by 2x and add a fade-out at the end")

A programmatic API that lets LLMs read and mutate the KinetiX AST in memory. If you're building AI agents, this is your playground.


Something click? Open an issue, start a discussion, or send a PR. The core is intentionally small — that's where you come in.

License

MIT

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

kinetix_video-0.2.1.tar.gz (32.0 kB view details)

Uploaded Source

Built Distribution

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

kinetix_video-0.2.1-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file kinetix_video-0.2.1.tar.gz.

File metadata

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

File hashes

Hashes for kinetix_video-0.2.1.tar.gz
Algorithm Hash digest
SHA256 b7eda90d2d06ae1a5c625a03a46621d9195c97e57931984c4fc0aa2ac8cf1e7c
MD5 76c4f28f5f771b7ff21e080758052737
BLAKE2b-256 867de740d8229a3fbee4fc5afa49dd2dfe3f2e78b5c1b92d4d71dd1f88cb316d

See more details on using hashes here.

Provenance

The following attestation bundles were made for kinetix_video-0.2.1.tar.gz:

Publisher: publish.yml on Bruce-lhq/kinetix-video

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

File details

Details for the file kinetix_video-0.2.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for kinetix_video-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 35aca89d6fd8e632e5b5d984df9a3d9f36da02914ffe6d2df0a632f6e086c0ac
MD5 db3f811bb2331f7fecb4ac0eae5f099a
BLAKE2b-256 2e4f2656b5b04e0f4c5de4604effd26b7f5ab05aa59e844ad34e04683a4a0ce1

See more details on using hashes here.

Provenance

The following attestation bundles were made for kinetix_video-0.2.1-py3-none-any.whl:

Publisher: publish.yml on Bruce-lhq/kinetix-video

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