Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<img src="frontend/public/cutmark-logo-transparent.png" alt="Cutmark logo" width="160">

Cutmark is a browser-based video editor for trimming clips and polishing them with optional scene detection and captions. Set precise in and out points, review the result, and export an MP4.
Cutmark is a local browser-based video editor for precise trims, joined ranges, named clips and small multi-source assemblies. Correct captions, reframe footage, adjust audio, add titles/logos, and export a reviewed MP4.

**Try it live:** [cutmark.dev](https://cutmark.dev)

Expand All @@ -12,10 +12,25 @@ Cutmark is a browser-based video editor for trimming clips and polishing them wi

- Import MP4, MOV, WebM, and MKV videos.
- Set an exact trim range by dragging the timeline or entering timecodes.
- Preview the selected range and jump to detected scene changes.
- Export clips as MP4.
- Optionally detect scene changes and generate editable captions.
- Reopen recent projects saved in the current browser.
- Review decoded source thumbnails and audio peaks, zoom the timeline, and navigate long footage.
- Preview and loop a selection, review cut context, step decoded frames, and change preview speed/volume.
- Keep, split, remove and reorder source sections with exact video/sample timing.
- Export named clips sequentially with independent captured formats and safe cancellation.
- Assemble up to four local sources, including mixed dimensions/frame rates and missing-media relinking.
- Reframe landscape, square and portrait versions with fit/fill, drag/scale, rotation/flips and preview-only guides.
- Adjust exported gain/mute/fades separately from listening volume; review measured pause suggestions.
- Add timed titles/lower thirds and transparent local image/logo layers.
- Capture source/composed PNGs and download a timecoded edit report.
- Scan source or selected footage with recorded coverage, sensitivity and frame refinement; confirm, move or dismiss scene candidates safely.
- Add searchable named source markers with color and notes, independent of scene detection.
- Independently transcribe English captions for the selection or full source.
- Correct, search, split, merge, shift and replace captions with undo and readability guidance.
- Import/export reviewed SRT/VTT, style captions, and choose actual burned-in MP4 captions or subtitle files.
- Save portable project files/source-inclusive bundles and reusable output/naming presets.
- Autosave unfinished projects and reopen them in the current browser.
- Undo and redo range, caption, marker, framing, audio, title/image and assembly decisions.
- Inspect actual source frames, enter hour timecodes, and cancel processing safely.
- Keep previous exports downloadable while revising or retrying.
- Keep video processing on the device; source clips are not uploaded to an application server.

## Technologies
Expand All @@ -31,7 +46,7 @@ Cutmark is a browser-based video editor for trimming clips and polishing them wi

I built Cutmark as a static Next.js app so the editor can run without a video-processing backend. The browser uses WebCodecs when available and falls back to FFmpeg WebAssembly for trimming and encoding. Scene detection and speech transcription are optional steps, so the basic export workflow can stay lightweight.

Recent projects are stored in IndexedDB in the browser. New projects keep the source clip and edit settings so they can be reopened and edited later. The source clip stays on the user's device; the English speech model is downloaded from Hugging Face the first time captions are generated. Repeated word sequences are limited to prevent speech recognition loops from filling the transcript.
Unfinished drafts and exports are stored separately in IndexedDB in the browser. Projects keep source media, editable captions, scene cuts, selections, and the last successful output. Projects remain until explicitly deleted; browser storage is not a backup. The source clip stays on the user's device; the English speech model is downloaded from Hugging Face the first time captions are generated. Caption corrections remain in source time across trims and exports. Recognition text is preserved for review rather than automatically deleting repeated words.

For deployment, the site is exported as static files and served from a private S3 bucket through CloudFront. GitHub Actions builds the frontend and deploys it when changes reach `main`.

Expand Down Expand Up @@ -62,3 +77,24 @@ Caption generation downloads the Whisper Tiny English model on first use. It tra
## License

MIT. See [LICENSE](LICENSE).


## Implementation verification and backlog

See the [Phase 1 safety checklist](docs/phase-1.md), [Phase 2 visual-editing checklist](docs/phase-2.md), [Phase 3 caption-delivery checklist](docs/phase-3.md), [Phase 3 export-settings checklist](docs/phase-3-export.md), the [Phase 3 recovery/storage checklist](docs/phase-3-recovery.md), [Phase 4 repurposing checklist](docs/phase-4.md), [Phase 5 workflow checklist](docs/phase-5.md), and [complete item-status matrix](docs/backlog.md) for implemented, verified and deferred work.

Frontend checks: `npm test`, `npm run lint`, and `npm run build`. Builds and development use Next.js Webpack because the default bundler emitted the processing workers as TypeScript assets rather than executable JavaScript.

The browser suite at `frontend/tests/browser.mjs` generates local fixtures with FFmpeg and exercises the production export in Edge. It requires Playwright, an installed Edge browser, FFmpeg/ffprobe on PATH, and a local static server. Set `CUTMARK_TEST_URL` to that server, `CUTMARK_PLAYWRIGHT_PATH` to an installed Playwright package if it is not available normally, and optionally `CUTMARK_ARTIFACTS` to a folder for fixtures, outputs, and screenshots; then run `node tests/browser.mjs` from `frontend`.

The Phase 2 suite at frontend/tests/phase2.mjs exercises decoded thumbnails/waveforms, native transport, source-based transcript operations and adaptive layout. It uses the Phase 1 fixture directory via CUTMARK_ARTIFACTS. The real-English speech suite also verifies cached recognition and full-source transcription before export.

The scene-tools suite at frontend/tests/scenes.mjs verifies recorded/refined scene analysis, preserved cut corrections, marker notes, interrupted scans and a long source-timed transcript follow/browse workflow. It reuses CUTMARK_ARTIFACTS from the other browser suites.

The caption-delivery suite at frontend/tests/caption-delivery.mjs verifies reviewed SRT/VTT import, persistent styles, actual burned-in MP4 captions, native/compatible paths, portrait wrapping and recovery after cancellation/font/overflow failures. It reuses CUTMARK_ARTIFACTS and requires FFmpeg/ffprobe. Export presets and actual resolution/quality/audio controls are now implemented; portable project backups/relinking, project titles/duplication and targeted cache management are now implemented in Phase 3C.

The export-settings suite at frontend/tests/export-settings.mjs measures native/compatible quality and file-size changes, output dimensions/audio, target-sized caption parity, preset undo/reopening and persisted measured output metadata. It uses the same test environment and writes artifacts under export-settings.

The project-backups and storage-tools suites verify fresh-profile portable recovery, exact-media relinking, shared-media duplication/deletion, version-2 migration, quota rollback, protected downloads and scoped model-cache cleanup. See docs/phase-3-recovery.md for the portable format and completed Phase 3 scope. The Phase 4/5 flows are now implemented; the item-status matrix separates completed core flows from conditional extensions and manual verification gaps.

The new suites are frontend/tests/sequences.mjs, assembly.mjs, framing.mjs, finishing.mjs, images.mjs and join-precision.mjs. They verify actual joins, continuous audio, framing/layer pixels, per-job recovery, multi-asset backups and 100 off-grid VFR ranges without accumulated drift. Build once before starting browser tests; replacing frontend/out while pages load hashed chunks invalidates a run. Exact composed/joined exports require a supported browser video encoder; compatible preparation adapts source codecs locally. See the current checklists for limits rather than assuming all 100 conditional backlog ideas or all browsers are supported.
52 changes: 52 additions & 0 deletions docs/backlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Cutmark implementation checklist

The five recommended phases have working core user flows in the local build. This is a product backlog: completion of those phases does not mean every conditional/P3 extension or every device has been implemented or verified. The distinctions below are intentional; deferred controls are not exposed as working features.

## Phase status

| Phase | Delivered scope | Status |
| --- | --- | --- |
| 1 — Trust/revision safety | Independent drafts/artifacts, preserved wording, named undo, consistent timing, actual frame inspection, validation, cancellation, autosave/quota safety and legacy recovery | Implemented; regression coverage retained |
| 2 — Everyday usability | Real thumbnails/waveform, zoom/navigation, transport/shortcuts/context, transcription and transcript tools, scenes/notes, adaptive and keyboard-accessible workspace | Implemented; regression coverage retained |
| 3 — Deliverable quality | Shared caption burn-in/style, SRT/VTT import/export, real output settings/validation, names/duplicates/backups/relinking and scoped storage tools | Implemented; regression coverage retained |
| 4 — Repurposing/richer edits | Exact ordered ranges, split/remove, named clip extraction, static reframing/aspect versions, gain/mute/fades/meters, reviewed pauses, titles/logos and frame capture | Implemented; see [Phase 4](phase-4.md) |
| 5 — Advanced workflow | Small multi-source assembly, linked/independent source corrections, transcript proposals, clip queue/presets/naming and local review/handoff artifacts | Implemented selected P3 flows; see [Phase 5](phase-5.md) |

## Item coverage

| Items | Status and limits |
| --- | --- |
| 1–10 | Implemented: revision safety, timing, named/coalesced undo, previous downloads, strict boundaries and decoded frame navigation. |
| 11–20 | Implemented core timeline/transport/shortcuts/context/synchronization. J/K/L shuttle is conditional and not exposed. |
| 21–29 | Implemented transcription/editor operations/readability and caption/subtitle delivery. Native accessibility preview is an explicitly separate source view. |
| 30 | Deferred: animated word emphasis requires trustworthy editable word timings. Segment timestamps are not presented as word timing. |
| 31–32 | Implemented supported English/local-download/cache workflow. Additional languages/larger models await measured compatibility/performance; none are advertised. |
| 33–40 | Implemented repetition preservation, no-audio/silence/cancel/retry, recorded scene workflow, candidate correction and editorial notes. Scene scans remain reviewable estimates, not guaranteed editorial truth. |
| 41–44 | Implemented kept ranges, split/remove/reorder, named clips and explicit source/sequence mappings. Ripple closes gaps; no gap-retaining mode. |
| 45 | Hard cuts implemented. Optional dissolves/crossfades deferred. |
| 46–49 | Implemented ratios, fit/fill/solid background, drag/scale/keyboard/numeric placement/reset and non-exported adjustable guides. Blurred backgrounds deferred. |
| 50 | Deferred: crop keyframes and automatic tracking. Static reframing is complete. |
| 51–54 | Implemented listening/export distinction, gain/mute/fades, sample-meter/peak feedback and reviewable padded pause removal. No standards-compliant loudness/true-peak claim. |
| 55 | Deferred: optional local music and ducking. |
| 56–58 | Implemented timed titles/lower thirds, real transparent raster overlays, orientation/flip/reset/undo and asset recovery. |
| 59 | Deferred: grading/white balance pending separately verified color/performance behavior. Unverified HDR/wide-color re-encoding is blocked. |
| 60–65 | Implemented source/composed PNGs, output-oriented rendering, useful quality/resolution/audio/framing settings, presets and actual result metadata. Encoding intent is shared, not a promise of identical codec output bytes. |
| 66–70 | Implemented cancellation/stale guards/stage progress, relevant failure/retry messages and actual output checks. No invented ETA or success from a bare worker-complete message. |
| 71–80 | Implemented drafts, names/duplicates, portable references/bundles, exact-source relinking, versioned legacy recovery, explicit retention, shared assets, quota safety and requested durable storage. Browser retention remains a policy decision, not a backup guarantee. |
| 81–84 | Implemented media/capability checks, special-source guards and bounded native processing/resource cleanup. FFmpeg preparation and final in-memory MP4s still have real device limits. |
| 85 | Deferred conditional proxy/resource modes; no fake “light preview” switch. Rendered previews explicitly use export settings. |
| 86–95 | Implemented adaptive/progressive workspace, relevant guidance, keyboard/text alternatives, coarse-pointer sizing and reduced motion. Real screen-reader/touch-hardware and broader-device audits remain manual. |
| 96 | Implemented up to four sources, explicit IDs/joins, common framing, source captions and missing-video/image recovery. Verified representative mixed dimensions/rates; not a universal codec/device guarantee. |
| 97–98 | Implemented review-before-apply transcript passage edits and measured pause/peak suggestions. Automated filler/black-frame analysis remains optional future work. |
| 99 | Implemented sequential primary-source clip jobs, individual cancellation/failure recovery and local reusable style/output/naming presets. Not a crash-resumable background publishing queue. |
| 100 | Implemented local source/composed images and actual timecoded JSON edit/marker report. Professional interchange formats await target-app verification. |

## Verification record

The current test inventory is 50 unit tests and fourteen production-browser scripts. Tests inspect actual media frames, timestamps, dimensions, tracks, audio gain/fades, text/logo pixels, saved state, cancellations, quota rollback and recovery. The 100-range VFR case detects cumulative join drift rather than relying on approximate total duration alone.

Run npm test, npm run lint and npm run build in frontend. Serve the completed frontend/out directory, then run the browser scripts listed in Phase 5 using CUTMARK_TEST_URL, CUTMARK_PLAYWRIGHT_PATH and CUTMARK_ARTIFACTS. The speech suite also uses CUTMARK_SPEECH_FIXTURE. Do not rebuild the static directory while tests are loading hashed browser chunks.

Available target: Windows Edge. Firefox/Safari, actual phone rotation metadata/touch hardware, screen readers, other-script font fallback, multi-gigabyte/high-resolution sources and sustained heap/GPU profiling remain explicitly unverified. No universal compatibility, unlimited-file-size or error-free guarantee is made.

Final local run: **50 unit tests and all 14 browser suites passed**, with lint, TypeScript and production build successful. See the [dated verification record](verification-2026-10-14.md) for scope and limits.
Loading
Loading