← All tools

Video Splitter

Cut a long video into clips that start where the video changes β€” not every thirty seconds. Everything happens on your machine.

Why cut on the shot, not on the clock

A thirty-second rule knows nothing about the video it is cutting. It will end a clip in the middle of a movement and open the next one on the tail of it, and the join is visible to anyone watching β€” the first second of a clip is the second that decides whether they stay.

A shot change is a boundary the footage already contains. Starting there means each clip opens on something new, which is what a person would do by hand. That is the only real difference here, and it is the whole point.

What it does not do

It does not read speech, so it cannot find the moment someone says something quotable β€” tools built around transcription do that, and they do it well. It does not track faces, so the vertical crop takes the centre of the frame and trusts you to look at the previews.

What it does have is the picture: where the shots are, and which of them are sharp, well-exposed and worth a viewer's attention. For footage without much talking β€” travel, action, b-roll, anything shot on a gimbal β€” that is the information that matters.

How it works

The scene detector finds the shot boundaries, the same per-frame scorer that Life2Film uses ranks them, and the clips are grouped so no cut ever lands inside a shot. Encoding uses the browser's own video pipeline, so the output is a normal MP4 with no watermark.

Your file is read and re-encoded by your own browser. No request carries it anywhere β€” this page has no upload endpoint to send it to.

Questions

How is this different from other video splitters?

Most cut every N seconds, so a clip can start halfway through a sentence and end mid-gesture. This one finds the cuts the video already has β€” the shot changes β€” and builds clips out of whole shots. You still choose roughly how long a clip should be; the boundaries land on the nearest real change instead of on a stopwatch.

Is my video uploaded?

No. The browser decodes it, WebAssembly analyses the frames, and the clips are re-encoded locally with WebCodecs β€” the same hardware path your browser uses to play video. Nothing is sent anywhere, which is also why there is no length limit imposed by a plan, no queue and no watermark.

What are the stars next to each clip?

The engine scores every sampled frame for sharpness, exposure, contrast, colourfulness and detail, and each clip gets the duration-weighted average of the shots inside it. The stars are relative to the best clip in this video, not an absolute scale β€” they are a suggestion of where to look first, not a verdict on what is interesting.

Will the vertical crop cut people out of frame?

It takes the centre of the frame, which is right most of the time and wrong when the subject is off to one side. There is no face tracking here yet, so check the previews before posting. If a clip is framed wide, it is usually better to crop it by hand.

How long does it take?

Analysis takes a few seconds per minute of video. Encoding is the slow part and depends on your machine β€” expect roughly real time or better for 1080p on a recent laptop, since it uses the GPU where available. Clips are written one at a time so you can start downloading before the rest finish.

Which files work?

MP4 and MOV with H.264, and WebM β€” whatever your browser can both decode and encode. Camera-native formats like ProRes or raw usually cannot be opened by a browser; transcode a proxy first.

The other tools

Build this into your own project

Splitting video at its shot changes β€” the same way this page does it, on the user's machine, with no server. Take the code, or hand the prompt to a coding agent.

// Shot detection uses the Life2Film engine:
// https://life2film.com/wasm/va_wasm.js
const engine = await import('https://life2film.com/wasm/va_wasm.js');
await engine.default({ module_or_path: 'https://life2film.com/wasm/va_wasm_bg.wasm' });

// pixels: centre-column mean RGB per sampled frame, timestamps in seconds
const { scenes } = JSON.parse(engine.detect_scenes_slick(JSON.stringify({
  pixels, timestamps, duration, algo: 'adjacent_diffs',
})));

The engine is documented for agents, and every tool page is available as markdown by adding .md to its address.