Skip to content

ucsandman/Magnetic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

49 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧲 Magnetic

A free, open-source, Final Cut Pro-style non-linear video editor for Windows.

License: MIT Platform Electron React TypeScript

Magnetic timeline Β· WebCodecs/WebGL2 playback Β· edit-by-transcript Β· auto silence removal Β· keyframe animation Β· smart-render export. Built for long-form creator workflows β€” multi-hour recordings play with a flat memory footprint and export at disk speed.

Magnetic β€” timeline with an edit

Portfolio project. The design is an homage to Apple's Final Cut Pro β€” the magnetic timeline, three-panel layout, JKL transport, and edit grammar are modeled on it as the design reference. Not affiliated with Apple; no Apple trademarks are used and "Magnetic" is an original product name.

New to Magnetic? Start with the User Guide β€” a five-minute first edit, the magnetic-timeline workflow, edit-by-transcript, and troubleshooting.

✨ Features

Organize & import

  • Library model β€” Libraries β†’ Events β†’ Projects; import copies media into the .mglib bundle (hardlinks instead of copies when source and library share a volume)
  • Filmstrip browser β€” hover-skim filmstrips, favorite/reject ratings, text search, background thumbnail/waveform generation
  • Missing-media relink β€” assets whose file vanished get an alert badge; relink accepts a replacement whose duration matches Β±1 frame

Edit

  • Magnetic timeline β€” spine + connected clips, lanes, gap clips, snapping, zoom, skimming; clips never overlap, edits ripple; minimap strip with drag-to-navigate when the sequence is wider than one screen, and the view pages along with the playhead during playback
  • Edit grammar β€” append E, insert W, connect Q, overwrite D, ripple delete, lift; select A / blade B / trim T tools; trim ripples, edit points roll, clip bodies slip; drag-rearrange with magnetic collision; full undo/redo
  • Viewer β€” JKL transport (tap again for faster), frame-accurate stepping (←/β†’, Β±10 with Shift), in/out marks with play-the-marked-range (/), source/sequence timecode you can click and type to seek, loop playback (Ctrl+L), fullscreen review (Shift+F), live audio meter, transport buttons in both source and sequence modes, and Space plays the browser selection when nothing else is up
  • Review grid β€” watch up to 9 selected clips side by side (browser "Watch N" button); click a cell for its audio, double-click to open it in the viewer
  • Resizable layout β€” drag the panel splitters (double-click one to reset it); Reset Layout button restores the defaults
  • Clipboard β€” copy/paste/duplicate clips (Ctrl+C/V/D), paste-connect (Ctrl+Shift+V), paste attributes incl. keyframes (Ctrl+Alt+V); one undo step per paste
  • Keyframe animation β€” animate transform, opacity, and color params from the Inspector (linear/smooth easing); diamonds on timeline clips; WYSIWYG in export
  • Transitions β€” cross dissolve, wipe left/right, fade-to-black
  • Titles β€” free text + 3 presets, rendered as live canvas layers
  • Color board β€” exposure / contrast / saturation / temperature per clip

Playback & long-form

  • Sequence playback β€” WebCodecs decode β†’ WebGL2 compositor; per-clip transforms (position/scale/rotation/opacity); AudioContext-clocked A/V sync
  • Multi-GB clips β€” streaming demux fetches samples on demand with bounded memory; a 10.85 GB, 4.2-hour clip plays video + audio with a flat ~87 MB renderer heap
  • Windowed audio β€” long clips stream 10-second audio windows double-buffered ahead of the clock instead of decoding whole files

Audio & transcript

  • Audio β€” mixing, per-clip volume/pan, fade in/out
  • Detach audio & split edits β€” pull audio onto its own lane and trim its edges independently for J-cuts and L-cuts
  • Loop to fill β€” loop a connected music bed to the end of the spine in one action; seam ticks on the timeline, whole-bed fade envelope, one undo step
  • Edit-by-transcript β€” local whisper.cpp transcription, word-click seek, select-text-and-delete-to-cut, filler-word removal, transcript search
  • Auto silence removal β€” background audio analysis, tunable dead-air detection with timeline preview, one-click jump-cuts, one-step undo
  • Captions β€” burned-in captions derived live from the transcript (pop-in / karaoke / block presets); SRT/VTT sidecar export

Finish & export

  • Export β€” H.264/AAC MP4 at 1080p/720p/source via bundled ffmpeg, with progress and cancel; WYSIWYG (exported pixels match the live compositor)
  • Smart-render export β€” when the video track is a single, possibly trimmed, visually untouched asset, export stream-copies the H.264 bitstream and renders only the mixed audio: a 6-hour VOD exports at roughly disk speed, bit-identical video
  • Keyboard-shortcut overlay β€” Shift+? lists every live binding
  • NSIS installer β€” npm run package, binaries bundled

Explicitly out of scope: multicam, color wheels/curves/scopes, proxy workflow (preview proxies for non-decodable codecs only), compound clips, 360Β°/HDR, plugins, Motion templates, ProRes encode, object tracking, collaboration.

πŸ–₯️ Requirements

  • Windows 10/11 x64
  • Node.js 24+, npm 10+

πŸš€ Setup

# 1. Install dependencies
npm install

# 2. Fetch native binaries (ffmpeg, ffprobe, whisper.cpp, base.en model)
#    into resources/bin/ β€” pinned URLs, sha256-verified, idempotent
npm run fetch-binaries

# 3. Generate test media into fixtures/ (uses the fetched ffmpeg + Windows SAPI TTS)
npm run fixtures

Development

npm run dev          # start electron-vite dev server + app (HMR)

Build & test

npm run typecheck    # tsc across main, preload, renderer, shared, e2e
npm run lint         # eslint
npm test             # vitest unit tests
npm run build        # electron-vite production build -> out/
npm run test:e2e     # Playwright Electron E2E (requires `npm run build` first)
npm run package      # NSIS installer + win-unpacked -> dist/ (bundles resources/bin)

The installer bundles ffmpeg/ffprobe/whisper and the base.en model (~250 MB of binaries), so the packaged app has no first-run download. e2e/packaged.spec.ts boots dist/win-unpacked/Magnetic.exe and verifies the bundled binaries resolve; it is skipped until npm run package has produced that output.

Scripts

Script What it does
dev Run the app in development with HMR
build Production build to out/
typecheck Typecheck node (main/preload/shared/e2e) and web (renderer) projects
lint ESLint over the repo
test Vitest unit tests (src/**/*.test.ts)
test:e2e Playwright _electron E2E suite against the built app
package electron-builder NSIS installer into dist/
fetch-binaries Download + sha256-verify ffmpeg/ffprobe/whisper/model into resources/bin/
fixtures Generate deterministic test media into fixtures/
format Prettier write

⌨️ Keyboard shortcuts

Generated from the live shortcut registry (scripts/dump-shortcuts.mjs); Shift+? in the app shows the same list. Shortcuts are suppressed while typing in text fields. J/K/L and Space are contextual β€” they drive the source viewer when it has a clip open, otherwise the timeline.

Shortcut Action
Space Play / pause (viewer or sequence)
J Viewer: play reverse (again: faster) Β· Timeline: pause
K Pause
L Play forward (again: faster)
← / β†’ Step back / forward one frame
Shift+← / Shift+β†’ Step back / forward 10 frames
Home / End Go to the start / end (viewer or timeline)
↑ / ↓ Jump to the previous / next edit point
I / O / X Mark in / mark out / clear in-out points
/ Play the marked range (in to out)
Ctrl+L Loop playback on / off
Shift+F Fullscreen viewer
E Append browser selection to the spine
W Insert browser selection at the playhead
Q Connect browser selection at the playhead
D Overwrite at the playhead with browser selection
Delete Ripple delete the selected clips
Shift+Delete Lift the selected clips, leaving a gap
A Select tool
B Blade tool
T Trim tool (edges ripple, edit points roll, body slips)
Ctrl+B Blade at the playhead (selected clips, or the clip under it)
Ctrl+T Add a 1 s cross dissolve at the edit point nearest the playhead
Ctrl+Z / Ctrl+Shift+Z Undo / redo
N Toggle snapping
S Toggle skimming
= / - Zoom the timeline in / out
Shift+Z Zoom the timeline to fit the sequence
Ctrl+4 Show or hide the Inspector
Ctrl+E Export the sequence as a movie
Ctrl+Shift+T Show or hide the timeline transcript
Ctrl+Shift+D Show or hide binary diagnostics
Shift+? Show the keyboard shortcut overlay
Escape Return focus to browser Β· close the clip grid Β· exit fullscreen

πŸ—οΈ Architecture

flowchart TB
    subgraph rendererBox["Renderer (src/renderer)"]
        ui["React UI<br/>browser Β· viewer Β· timeline Β· inspector"]
        store["zustand timeline store<br/>undo / redo"]
        engine["Playback engine<br/>streaming WebCodecs demux + decode β†’ WebGL2 compositor<br/>AudioContext-clocked sync"]
    end
    subgraph sharedBox["Shared (src/shared)"]
        kernel["Magnetic timeline kernel<br/>pure TS Β· immutable Sequence<br/>every op returns its inverse"]
    end
    subgraph mainBox["Main process (src/main)"]
        ipc["IPC<br/>zod-validated handlers"]
        lib["LibraryStore<br/>.mglib JSON + media"]
        jobs["JobQueue<br/>filmstrip Β· waveform Β· proxy<br/>transcribe Β· envelope"]
        exp["Export sink<br/>rawvideo pipe β†’ ffmpeg<br/>or smart-render stream-copy"]
    end
    ui --> store
    store --> kernel
    store --> engine
    ui -->|window.api preload bridge| ipc
    ipc --> lib
    ipc --> jobs
    ipc --> exp
Loading
  • src/shared/timeline/ β€” the magnetic-timeline kernel: pure functions over an immutable Sequence; clip positions are derived by summation so overlaps are unrepresentable; every op returns its inverse for undo
  • src/main/ β€” Electron main process: window, menu, library persistence, background jobs, export (including the smart-render planner); every IPC handler zod-validates its payload
  • src/preload/ β€” contextBridge bridge exposing the typed window.api
  • src/renderer/ β€” React UI (dark FCP-style 3-panel shell), zustand state, and the playback engine (streaming WebCodecs demux + decode, WebGL2 compositing, AudioContext-clocked sync)
  • scripts/ β€” binary fetcher, fixture generator, shortcut-table dump
  • e2e/ β€” Playwright Electron tests; resources/bin/ and fixtures/ are gitignored artifacts

The visual language is documented in DESIGN.md (tokens, type scale, spacing, motion β€” Apple dark-mode chrome where the footage is the hero) and PRODUCT.md (register, users, brand personality).

Renderer security: contextIsolation: true, nodeIntegration: false, sandbox: true, CSP set in index.html, no remote URLs; library files are served over a custom mfile:// protocol scoped to the library, except video/audio playback, which goes through a token-guarded loopback HTTP server (src/main/media-server.ts) because Chromium's media pipeline cannot seek large files through Electron custom-protocol responses. Ctrl+Shift+D toggles a diagnostics overlay that spawn-verifies the bundled binaries.

πŸ“Έ Screenshots

Filmstrip browser Filmstrip browser β€” hover-skim, ratings, background jobs Viewer Viewer β€” JKL transport, frame stepping, in/out marks
Edit-by-transcript Edit-by-transcript β€” word-click seek, delete text to cut Export dialog Export β€” H.264/AAC MP4 with progress + cancel
Shortcut overlay Shift+? overlay β€” every live binding 500-clip timeline 500-clip timeline β€” 0.7 ms median draw

Known limitations

  • The "Explicitly out of scope" list above (multicam, scopes, compound clips, …) is deferred by design
  • Reverse playback: J in the timeline pauses; true reverse playback is viewer-only
  • 4K media plays at degraded fidelity (frame drops accepted; no proxy editing pipeline)
  • Codecs WebCodecs cannot decode natively (e.g. ProRes) play through an auto-generated H.264 preview proxy; export always re-renders from source
  • Export encodes H.264/AAC MP4 only; no ProRes/HEVC encode
  • Auto-transcribe skips assets over 30 minutes (manual transcribe still works at any length)
  • Windows-only: packaging, binary fetching, and E2E are wired for win32

πŸ“„ License

MIT β€” free for everyone, for any use.

The fetch-binaries script downloads third-party tools that are not part of this repository and carry their own licenses: FFmpeg/FFprobe (GPL builds from gyan.dev), whisper.cpp (MIT), and the Whisper base.en model (MIT).

About

🧲 Free, open-source Final Cut Pro-style video editor for Windows (MIT). Magnetic timeline, edit-by-transcript, silence removal, keyframes, smart-render export.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors