DEV Community

Samlee Phiput
Samlee Phiput

Posted on

How We Built MedleyKit: Private Video Editing in the Browser

Most “online” video tools begin with the same step: upload your file to a remote server.

That works, but it also means waiting for the upload, trusting another server with the original file, and downloading the result afterward. For private recordings, internal demos, family videos, or large files, that workflow is not always ideal.

We built MedleyKit around a different idea:

The interface runs in the browser, and the media-processing pipeline runs there too.

There is no media upload step, no account to create, and no branded watermark added to the exported video.

What can MedleyKit do?

MedleyKit currently provides six focused video tools:

  • Video Trimmer — select a range using a visual timeline or precise timecodes. Fast mode avoids unnecessary re-encoding when possible, while Precise mode re-encodes the selected range for exact boundaries.
  • Video Compressor — choose a target file size, receive a resolution recommendation, and export a smaller MP4.
  • Video Cropper — use common aspect ratios or a freely adjustable crop area to create square, vertical, or widescreen video.
  • Video Speed Changer — slow down or speed up video from 0.1× to 16×, with options to preserve audio pitch, change it with the speed, or remove audio.
  • Video Reverser — reverse the complete visual sequence and optionally reverse the audio track too.
  • Video Watermark Tool — add text or image watermarks with live positioning, opacity, size, margins, nine anchor positions, free dragging, and tiling.

The tools accept common containers such as MP4, MOV, M4V, WebM, and MKV, depending on the codecs supported by the browser. Results are exported as MP4 files.

MedleyKit itself does not add a logo, intro, outro, or branded watermark. The watermark tool only adds the text or image explicitly chosen by the user.

Why local processing matters

Local processing provides more than a privacy label.

1. Media files stay on the device

The source video and generated result are not uploaded to a remote media-processing server. The browser reads, transforms, and writes the media locally.

This is an intentionally precise privacy promise: the media-processing path does not require transferring the video file to our backend.

2. There is no upload round trip

With a server-side editor, the workflow usually looks like this:

Upload → Wait → Process remotely → Download
Enter fullscreen mode Exit fullscreen mode

With MedleyKit, it becomes:

Choose a local file → Process locally → Download
Enter fullscreen mode Exit fullscreen mode

Processing time still depends on the device, codec, resolution, and selected operation, but users do not have to transfer the complete file before work can begin.

3. The exported result stays clean

There is no account requirement or paid export step, and MedleyKit does not insert its own branding into the result.

Continue editing without downloading and importing again

A video workflow rarely ends after one operation.

Someone may want to trim a recording, crop it to a vertical aspect ratio, compress it for sharing, and then add a watermark. Treating every tool as an isolated page would force the user to download and reselect the result after every step.

MedleyKit instead provides a local “Continue editing” workflow.

After an operation finishes, the user can send the result directly to another compatible tool:

Trim
  ↓
Crop
  ↓
Compress
  ↓
Add watermark
  ↓
Download once
Enter fullscreen mode Exit fullscreen mode

The media does not travel through a server during these transitions. The next page opens the locally stored result from the same browser workspace.

Under the hood, large results are streamed into the browser’s Origin Private File System (OPFS). IndexedDB stores artifact metadata and lease state, while lightweight session state records which tool should receive the result next.

The destination tool acquires a lease before opening the artifact. This prevents temporary cleanup from deleting a result while another page is using it. Expired artifacts can later be reconciled and removed safely.

Instead of copying a large video between pages, we pass a reference to a locally managed media artifact.

The browser-based media architecture

The processing pipeline looks roughly like this:

Local File / Previous Tool Result
                │
                ▼
       Inspect and demux media
           with Mediabunny
                │
        ┌───────┴────────┐
        │                │
        ▼                ▼
  Copy encoded       Decode frames
  samples when       with WebCodecs
  possible                │
                          ▼
                 Transform video/audio
                 using Canvas, timing,
                 crop, scale, or effects
                          │
                          ▼
                    Re-encode with
                      WebCodecs
        │                │
        └───────┬────────┘
                ▼
       Mux the result as MP4
           with Mediabunny
                │
                ▼
      Memory or streamed OPFS output
                │
        ┌───────┴─────────┐
        ▼                 ▼
     Download       Continue editing
Enter fullscreen mode Exit fullscreen mode

Application layer

The interface is built with Next.js, React, TypeScript, and Tailwind CSS.

We use the Next.js App Router for page structure, localization, metadata, canonical URLs, and server-rendered content. The actual video-processing code runs only in the client.

The application is built through Vite and vinext and deployed on a Cloudflare Worker. The worker serves the application and static assets; it is not used as a video-processing backend.

Container handling and conversion

Mediabunny handles media inspection, demuxing, conversion orchestration, and MP4 muxing.

For operations that change frames or timing, the browser’s WebCodecs APIs provide hardware-aware video decoding and encoding when supported by the current platform.

Trimming has two different paths:

  • Fast mode prioritizes copying existing encoded samples. It avoids a quality-changing re-encode, although the start may align with a nearby keyframe.
  • Precise mode decodes and re-encodes the selected range so that visual boundaries can match the chosen frames.

Audio processing

When a browser does not expose the AAC encoder required for MP4 output, MedleyKit can load a WebAssembly AAC fallback on demand.

For speed changes, SoundTouchJS provides time stretching so that audio can remain synchronized while preserving its original pitch. Users can also choose a traditional pitch-shifting effect or export without audio.

Bounded local storage

Large outputs should not require holding the complete generated file in JavaScript memory.

MedleyKit therefore prefers streaming output into OPFS. Before an operation begins, the site estimates the required browser storage, includes room for temporary working data, and rejects operations that clearly exceed the available quota.

Smaller results can fall back to memory when persistent browser storage is unavailable.

The reverse-video implementation also processes bounded segments rather than buffering the complete decoded video. This keeps memory usage more predictable for longer clips.

Local-first does not mean unlimited

Moving video processing into the browser introduces real constraints:

  • WebCodecs support varies by browser, operating system, and installed codec capabilities.
  • Large or high-resolution videos still require CPU, memory, and local disk space.
  • Re-encoding operations can consume significant power on laptops and mobile devices.
  • The page must remain open until processing finishes.
  • Fast trimming may start at a nearby keyframe; exact cuts require Precise mode.

For the most consistent experience, we currently recommend a recent version of Chrome or Edge and common H.264/AAC source files.

These limitations are preferable to hiding the trade-offs. A local-first tool should explain when an operation is fast, when it requires re-encoding, and when browser capabilities may affect the result.

What we learned

The most interesting part of MedleyKit was not placing a file input next to a video element. It was treating the browser as a complete media runtime.

Three principles shaped the project:

  1. Privacy should come from architecture.

    If media processing is genuinely local, the product does not need an upload endpoint for the video-processing path.

  2. An output should also be a reusable input.

    Local artifact handoff turns a collection of small tools into a practical editing workflow.

  3. Use native capabilities, but design for their boundaries.

    WebCodecs, OPFS, IndexedDB, Canvas, and the Storage API are powerful, but codec support, quotas, cancellation, cleanup, and recovery must all be treated as first-class concerns.

If you need to make a quick edit without uploading the original file, you can try MedleyKit in your browser.

We would love to hear how local-first browser media tools could fit into your workflow.

Top comments (0)