Skip to main content

Purpose-built NLE timeline + scene compositor components for Dash 4 — frame-accurate scrubbing, draggable playhead, snapping, audio waveforms, and a hybrid DOM+Canvas preview scene with a background children slot for any Dash component.

Project description

Dash NLE Timeline

Non-linear-editor (NLE) timeline & scene compositor components for Plotly Dash.

Frame-accurate scrubbing · draggable playhead · snapping · audio waveforms · trim / split / delete · hybrid DOM + Canvas preview scene · full Dash callback interoperability.

PyPI version Python Dash 4.1+ License: MIT Discord YouTube

Documentation · Discord · YouTube · GitHub


Maintained by Pip Install Python LLC.


Overview

dash-nle-timeline brings a purpose-built video-editor timeline to Plotly Dash. A calendar/scheduler widget thinks in dates; a video editor needs an integer frame grid, a real draggable playhead, snapping to clip edges / markers / grid, audio waveforms, and edits expressed as data. This library is exactly that — written in TypeScript on React 18 and compiled with dash-component-boilerplate, so everything is driven from pure Python.

  • Frame-accurate timeline — integer frames are the canonical unit; seconds are derived from fps
  • Full editing surface — drag to move (cross-track), drag edges to trim/resize, split at the playhead, delete; every edit reported as a single lastEdit event
  • Audio waveforms — painted from precomputed peaks (minmax / magnitude); no audio decoding in the browser
  • Snapping — to clip edges, the playhead, markers, and the frame grid, with a pixel-space threshold for a constant feel at any zoom
  • Playback & transport — rAF playback loop, built-in transport bar with timecode, keyboard shortcuts, and an imperative command prop
  • Scene compositor — a hybrid DOM + Canvas preview (DashNleScene) that renders any Dash component as its background and overlays image/video/text layers with per-layer visibility windows
  • Control plane / media plane split — only small JSON crosses Dash callbacks; your media stays in a <video>, an audio engine, or a server render, driven off the timeline's outputs

The package ships the compiled JS bundle — a normal pip install needs no Node.

Installation

pip install dash-nle-timeline

Quick Start

import dash_nle_timeline as nle
from dash import Dash, Input, Output, callback, html

app = Dash(__name__)

app.layout = html.Div([
    nle.DashNleTimeline(
        id="tl", fps=30, duration=300,
        tracks=[
            {"id": "v1", "kind": "video", "label": "V1"},
            {"id": "a1", "kind": "audio", "label": "A1"},
        ],
        clips=[
            {"id": "c1", "trackId": "v1", "start": 0, "duration": 90, "label": "intro.mp4"},
            {"id": "c2", "trackId": "a1", "start": 0, "duration": 220, "label": "music.wav",
             "peaks": [...], "peaksFormat": "minmax"},
        ],
    ),
    html.Pre(id="out"),
])

@callback(Output("out", "children"), Input("tl", "playhead"))
def show(frame):
    return f"frame {frame}"

if __name__ == "__main__":
    app.run(debug=True)

Edits (move / trim / resize / split / delete) persist on their own — the component applies them to its optimistic clips state and reports each one as a single lastEdit event. Write clips back from a callback only when you want to validate or override.

Documentation

Full documentation, with live examples, lives at the open-source documentation index maintained by Pip Install Python LLC:

📚 pip-install-python.com

You can also run the bundled demo locally:

pip install -r requirements.txt
pip install -e .
python usage.py           # open http://127.0.0.1:8060

usage.py exercises the full surface: scrubbing, selection, move/trim/resize/split/delete, waveforms from precomputed peaks, the imperative command prop, playback, and the scene preview synced to the playhead.

Components

Component What it is
DashNleTimeline Multi-track, frame-accurate NLE timeline: playhead, playback, editing, snapping, waveforms, markers, keyboard shortcuts, and an imperative command channel.
DashNleScene Hybrid DOM + Canvas preview compositor: renders a background (any Dash component and/or a native XYZ tileset) plus overlay image/video/text layers at the current playhead, with a screen-space camera.

Both load from a single bundled JS file — no extra external_scripts, CSS, or React setup.

Wire the two together with a plain callback:

@callback(Output("scene", "playhead"), Input("tl", "playhead"))
def sync(frame):
    return frame

The data boundary

  • Frames are canonical. fps and duration (in frames) define the grid; playhead is an integer frame that round-trips both ways (scrub in the browser, or set it from Python).
  • tracks is a list of dicts — {"id", "kind": "video" | "audio" | "camera", "label", "color"}.
  • clips is a list of dicts — id, trackId, start, duration, plus optional inPoint, label, color, thumbnails, locked, and (audio) peaks / peaksFormat. It is both an input and optimistic round-trip state: user edits persist without any callback.
  • lastEdit (output) reports each user edit as one event — move, trim, resize, split, delete — so Python can validate, override, or mirror it into your own model.
  • selectedClipIds / selectedClipId round-trip; drive selection from Python too.
  • command (input) is the imperative channel — play, pause, seek, splitAtPlayhead, copy, paste, duplicate, selectAll, zoomToFit, … — de-duplicated by id.

DashNleTimeline in depth

  • Timefps, duration (frames), playhead (round-trips), playing, loop; rAF playback loop with a throttled playhead round-trip.
  • ViewpixelsPerSecond (zoom), scrollX (pan); Ctrl/⌘ + wheel zooms anchored at the cursor.
  • Editing — drag to move (cross-track), drag edges to trim/resize, S to split at the playhead, Delete to delete; snapping via snapping / snapThreshold.
  • Waveforms — precomputed peaks painted on a per-lane canvas; formats minmax (interleaved [min0, max0, …]) and magnitude.
  • Markers & keyframesmarkers ({"id", "frame", "label", "color"}) on the ruler; camera-keyframe diamonds on camera tracks via cameraKeyframes.
  • Keyboard — the keyboard prop (default on) toggles all shortcuts: Space, arrows (Shift = 1s), S split, Delete, ⌘/Ctrl + C/V/D copy/paste/duplicate, ⌘/Ctrl + A select all, Home/End, + / - zoom.
  • Transport bar — the controls prop (default on): to-start / step / play-pause / step + timecode above the ruler.
  • Themingtheme="dark" / "light", plus style / className passthrough.

API reference

DashNleTimeline props (selected)

Prop Type Description
fps / duration int Frame rate and total length in frames — the canonical time grid
playhead int Current frame — input and output
playing / loop bool Playback state (rAF loop inside the component)
tracks list Track dicts (video / audio / camera)
clips list Clip dicts — input and optimistic round-trip state
lastEdit output The most recent user edit as a single event
selectedClipIds / selectedClipId list / str Selection — round-trips both ways
markers list Ruler markers {"id", "frame", "label", "color"}
cameraKeyframes list Keyframe diamonds rendered on camera tracks
snapping / snapThreshold bool / int Snap to edges / playhead / markers / grid; pixel-space threshold
pixelsPerSecond / scrollX number Zoom and horizontal pan
command dict Imperative channel (seek, togglePlay, zoomToFit, …), de-duped by id
keyboard / controls bool Toggle shortcuts / the built-in transport bar
theme / style / className Appearance and sizing

DashNleScene props (selected)

Prop Type Description
playhead int Frame to render — drive it from the timeline
resolution list Design-space [width, height] of the scene
children Dash components Background slot — a map, a plot, a video feed, anything
tileset dict Native XYZ tile background
layers list Overlay layers (image / video / text) with [start, end) visibility windows
camera dict Screen-space camera (pan / zoom over the scene)

The full prop tables are generated into dash_nle_timeline/DashNleTimeline.py and dash_nle_timeline/DashNleScene.py docstrings by dash-generate-components.

Development

# Install dependencies
npm install                  # TypeScript + webpack toolchain
pip install -r requirements.txt

# Build the JS bundle + regenerate the Python wrappers
npm run build                # webpack UMD bundle + dash-generate-components → dash_nle_timeline/*.py
npm run watch                # JS-only rebuild loop (when prop signatures don't change)

# Standalone smoke test
python usage.py              # http://127.0.0.1:8060

# Build a distribution
python -m build
  • TypeScript source of truth: src/ts/components/ holds the two public components, internal/ the subcomponents, and time.ts / snap.ts / waveform.ts / edits.ts / tiles.ts are pure helpers.
  • The built bundle and generated wrappers are committed, so pip install -e . works without npm.
  • dash_nle_timeline/__init__.py is hand-maintained (it registers the UMD bundle) — dash-generate-components does not regenerate it.
  • Keep the version in package.json and pyproject.toml in sync when cutting a release.

Requirements

  • Python >= 3.8
  • Dash >= 4.1
  • Node.js >= 16 (for development / rebuilding the JS bundle only)

Community & support

Come build with us:

More from Pip Install Python LLC

dash-nle-timeline is one of several tools built and maintained by Pip Install Python LLC:

Project What it is
📚 Pip Install Python Open-source documentation index for the Python & Dash ecosystem
🔀 PiratesBargain.com E-commerce / digital commerce
🧠 ai-agent.buzz Infinite AI canvas
🎬 2plot.media Videography application

License

MIT — see LICENSE. Built by Pip Install Python LLC to bring a real video-editing timeline into the Dash framework.

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

dash_nle_timeline-0.0.1.tar.gz (173.3 kB view details)

Uploaded Source

Built Distribution

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

dash_nle_timeline-0.0.1-py3-none-any.whl (177.0 kB view details)

Uploaded Python 3

File details

Details for the file dash_nle_timeline-0.0.1.tar.gz.

File metadata

  • Download URL: dash_nle_timeline-0.0.1.tar.gz
  • Upload date:
  • Size: 173.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dash_nle_timeline-0.0.1.tar.gz
Algorithm Hash digest
SHA256 abe016e696595d03da6e12688948a79d56a8e9d46bb24da44055f9fe3a3347da
MD5 5f01eeaf3e2bd5e1f4e4dda2d92c57da
BLAKE2b-256 eed3890ed339b7380a4273810014d7bd6eced7a36bde90dba43bec3ba7ecdba2

See more details on using hashes here.

File details

Details for the file dash_nle_timeline-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for dash_nle_timeline-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 32606a542012bc613b24af34071f58e8b5c5ebbd583718a52104d13c83b6e455
MD5 35e2061748c254b09557ca87416131a1
BLAKE2b-256 1be6b115dcf703cff6e799628c0e22c8da2f7f63430437a5a9a18b80f51abbcc

See more details on using hashes here.

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