Editor Guide
How the 2plot Media browser video editor works — upload, place, scrub, trim and split media on a frame-accurate timeline.
---
What the editor is
The [Editor](/editor) is a browser non-linear video editor (NLE) built on the dash-NLE-timeline package — DashNleTimeline (the timeline controller) and DashNleScene (a hybrid DOM + Canvas compositor). It follows one governing rule: heavy bytes never pass through Dash callbacks. Media uploads straight to the server; only small JSON (the clip list, the playhead, play/pause) crosses callbacks.
.. toc::
The workflow
1. Upload — drop files on the dropzone, or click to pick them. Each file is POSTed to /api/media/upload (multipart fetch, not a Dash callback) and stored under assets/media/. The browser then probes its duration (<video>.duration, <audio>.duration, or an image's natural size) and the asset appears in the Library. Files the browser can't decode are flagged *unsupported — transcode to H.264/AAC mp4* and can't be added. 2. Add to the timeline — each library item has an Add button. The clip is placed at the end of its matching track (Images, Video, or Audio) so uploads don't stack and occlude. Every placement gets a fresh unique clip id. 3. Edit — scrub the ruler, drag clips to move them, drag edges to trim, and use the transport buttons (or keyboard) to play/pause, split at the playhead, delete, and zoom-to-fit. The timeline applies edits optimistically, so editing is instant. 4. Preview — the scene composites the visible layers at the current playhead.
Time is measured in frames
Everywhere in the editor, time is an integer frame; seconds = frame / fps. The project runs at a single frame rate (PROJECT_FPS, default 30) wired into both the timeline and the scene — they must match or the preview lands on the wrong frame.
Keyboard shortcuts
Click the timeline to focus it, then:
| Key | Action | |---|---| | Space | Play / pause | | ← / → | Step one frame (hold Shift for one second) | | S | Split the selected clip at the playhead | | Delete | Delete the selection | | Cmd/Ctrl + C / V / D | Copy / paste-at-playhead / duplicate | | + / - | Zoom in / out |
The EDL
The in-memory clip list is the edit decision list. Export EDL serializes the project — fps, tracks, and every clip {id, trackId, start, duration, inPoint, src} — as JSON. A future phase turns that EDL into a deterministic server-side render.
Audio
Audio is fully wired. Upload an audio file (mp3, wav, m4a, …) and it lands on the Audio track with a waveform computed in your browser (Web Audio decodeAudioData → peaks — the timeline only paints them, it never decodes audio server-side). On playback, a separate audio engine plays both audio-track clips and the audio of your video clips, synced to the playhead (the scene's video is visually muted for browser autoplay policy, so its sound comes from the engine). The mute button in the transport silences the preview.
Known v1 limits
- Slight A/V drift is possible on long clips, because the visible (muted) video and
the audio engine are separate elements seeking to the same playhead. Good enough for editing; a unified render is a later phase.
- One active video track for compositing. Overlapping video clips occlude by
track order rather than blending; picture-in-picture and multi-video compositing come later.
- Project-frame accuracy. When a source file's true frame rate differs from the
project's, scrubbing is accurate to project frames (a server-side probe + resample is a later phase).
- Local storage. Uploads live in
assets/media/(gitignored). Cloud (R2) +
resumable (tus) uploads are deferred.
---
*Source: /editor-guide*
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /editor-guide/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt