All posts

Trim Video in the Browser Without Uploading

7 min read
1348 words
On this page· 6 sections

You can trim a video in the browser without uploading it, because FFmpeg.wasm cuts the file in the tab. Whether that cut finishes depends on this machine: the file size, the codec, and how much memory the tab can hold.

Video Clipper is the trim UI for that job. You set the range, the format, and the quality. It does not scan the video for highlights.

What one recorded session showed

These figures come from one desktop session on 2026-08-25. The browser was Chrome 151.0.0.0 on macOS, in a Cursor DevTools tab on the local product page. navigator.deviceMemory was 32, which Chrome reports in gigabytes, and hardwareConcurrency was 12. This note is one session, not a benchmark suite. Raw notes: video-clipper-probe-2026-08-25.md.

The tab was not cross-origin isolated. window.crossOriginIsolated was false, and typeof SharedArrayBuffer was undefined. The page tried @ffmpeg/core-mt@0.12.6 first. That load failed with ReferenceError: SharedArrayBuffer is not defined, then the page loaded single-thread @ffmpeg/core@0.12.6. The local dev server sent cross-origin isolation headers, and this tab still did not become isolated. A normal Chrome window on the same origin may keep the multi-thread core. The timings below are the single-thread fallback in this tab. They are not a claim about every Chrome 151 install.

Cold start also fetched both wasm cores from jsdelivr, about 9.3 MB compressed each. Those downloads are the engine, not the video. They are not included in the encode times below.

Warm runs after the single-thread engine was already loaded used the product medium MP4 path: -ss before -i, -t, CRF 23, preset veryfast, libx264 and aac. Each job kept a 0 to 5 second window.

  • A 15 second 720p testsrc MP4 of 886,062 bytes wrote clip-0s-5s.mp4 at 121,940 bytes in 3.063s.
  • A 20 second 1080p CBR MP4 of 100,001,988 bytes (about 95.4 MiB) wrote 3,446,559 bytes in 9.204s. JS heap moved from 69.6 MB to 175.9 MB.
  • A 112 second 1080p CBR MP4 of 532,528,318 bytes (about 508 MiB) wrote 3,418,128 bytes in 11.003s. JS heap peaked at 616.3 MB.
  • A 226.368 second 1080p CBR MP4 of 1,070,342,314 bytes (1020.76 MiB) wrote 3,443,386 bytes in 10.254s. JS heap peaked at 1,145.2 MB.

performance.memory.usedJSHeapSize is the JS heap only. It does not include wasm linear memory, and it is not process RAM. The near-1GiB file still completed a 0 to 5 second trim in that tab. That is not a comfortable working size: the tab held the whole File, and the heap counter alone was about 1.15 GB.

The same near-1GiB file, trimmed 0 to 30 seconds on the medium path, wrote 20,685,166 bytes in 56.771s. JS heap peaked at 1,150.3 MB. That was the default window after the file loaded, not a second machine.

Host ffmpeg 9.0.1 on the same Mac, with the same style of argv, is a different process. It is not a browser result:

  • A 5 second re-encode of the 15 second 720p file took 0.19s and wrote 120,930 bytes.
  • The 100,001,988-byte file took 0.51s real, with max RSS about 603 MiB (632,471,552 bytes).
  • The 532,528,318-byte file took 1.83s, then 0.44s on a repeat, with max RSS about 602 MiB.
  • The 1,070,342,314-byte file took 1.84s, then 0.43s on a repeat, with max RSS about 604 MiB. Host output for that 0 to 5 second window was 3,443,273 bytes, close to the browser file and not the same bytes.

-ss before -i is why the host process does not decode the unused tail, and why the browser 0 to 5 second wall stayed near the 500 MiB job even for the near-1GiB input. Quote these numbers with the machine and the date, or remeasure.

Cut a clip without an upload

The video file stays on the device. For a browser video cutter, that is the privacy boundary: the bytes are not posted to a server. Video Clipper runs FFmpeg.wasm in the tab and returns a blob: URL. In the 2026-08-25 session the outputs never left the machine.

  1. Open Video Clipper in desktop Chrome.
  2. Choose a local file. The product page lists MP4, WebM, AVI, and MOV.
  3. Set the start and end, or use a quick range. The recorded jobs used a 0 to 5 second window and medium quality.
  4. Start processing and wait for the clipped file. Download it from the page. The tool does not post the video to zhanghe.dev.

Medium MP4 in the shipped argv is CRF 23, preset veryfast, libx264, aac, with -ss before -i. WebM output uses VP9 and Opus. The session timed the medium MP4 path only.

If the first click sits on "Loading FFmpeg engine...", the tab may still be fetching the wasm core. That fetch is separate from the video. A later trim in the same tab can skip it, which is why the times above use warm runs.

Limits for size, codec, and memory

The product FAQ states a per-file limit of 1GB, and says the practical limit also depends on device RAM, browser, and codec. The code guard is 1024 * 1024 * 1024 bytes. In this session a File whose size was 1,073,741,825 showed File size must be under 1GB for optimal performance. The 1,070,342,314-byte file (1020.76 MiB) was accepted. A file over 1 GiB was not generated.

  • Size. Under the guard is not the same as comfortable. The near-1GiB trim held the whole file in the tab.
  • Codec. Input on the product page is MP4, WebM, AVI, and MOV. Output is MP4 (H.264) or WebM (VP9). The timed jobs were H.264 medium MP4. This note has no separate timing for VP9, AVI, or MOV.
  • Memory. JS heap on the 100 MiB job peaked near 176 MB, on the 508 MiB job at 616.3 MB, and on the near-1GiB job around 1.15 GB. Add wasm memory on top, and expect a smaller machine to fail sooner. The FAQ already points at RAM, browser, and codec.
  • Isolation. This tab fell back to single-thread wasm. Another window can keep core-mt. Encode time will not match these figures when the core differs.
  • Not an editor. There is no multi-track timeline and no AI cut. The tool applies the range, equal split, format, and quality you choose. It does not analyze the picture.

When a desktop editor is the better tool

Leave the browser when the job is outside what this session could show.

  • The file is at or over the 1GB guard. The page stops at 1,073,741,825 bytes with the message above.
  • You need effects, a multi-track timeline, or an automatic highlight cut. Video Clipper does not do those.
  • The window is long on a large file. A 0 to 30 second re-encode of the 1,070,342,314-byte file took 56.771s in this tab, with the whole File resident. A full-length re-encode on a machine with less memory than this session is a desktop editor job. This session did not measure battery use.
  • You need a codec other than the MP4 or WebM outputs above.

Two other local tools

Cover Moment builds a social cover from a photo and a short title. The photo stays on the device. It does not trim a timeline.

HEIC to JPG converts iPhone HEIC stills to JPEG in the browser, with a quality slider. It does not open a video.

Trim the file on this device

To cut a range without uploading the video, open Video Clipper and choose the file locally. For a still cover, use Cover Moment. For iPhone stills, use HEIC to JPG.