Skip to main content

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

Project description

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.git
cd kinetix
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

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

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.0.tar.gz (28.6 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.0-py3-none-any.whl (28.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kinetix_video-0.2.0.tar.gz
  • Upload date:
  • Size: 28.6 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.0.tar.gz
Algorithm Hash digest
SHA256 786dc39b289d442bc84be6dc1bf816e375290dd128302858f5ef2e04b1f49ab7
MD5 26a0c78166138b9d6488655285945d77
BLAKE2b-256 4dfbd668f8b6898c546187ff1690cae3df59e81b7e5ad2eeab05a4cddb0aedec

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on Bruce-lhq/kinetix

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.0-py3-none-any.whl.

File metadata

  • Download URL: kinetix_video-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 28.7 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4aab6144dce1814544d07669b4e0941bf52fda46e2708cc579b9d5a339fe37af
MD5 ed12e092837532a097b8a06361891e02
BLAKE2b-256 c6337f934ecc4a55ccb2d3535a48463ab6cf5a1541f95c9d4ea9c30fc163fa23

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on Bruce-lhq/kinetix

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