How to auto-detect scene boundaries before splitting
- Step 1Drop the video you want to split — Drag your
.mp4,.mov,.mkv,.webm,.avi,.m4vor.tsfile onto the detector. Everything runs locally — nothing uploads. Detection is the first half of the smart-split workflow; the actual cutting happens in a sibling tool. - Step 2Choose a threshold that controls segment count — Threshold is also a segment-count dial:
0.5yields fewer, coarser boundaries (fewer, longer segments);0.3(default) is balanced;0.1yields many boundaries (lots of short segments). Pick based on how granular you want the split, then re-scan to tune. - Step 3Run detection and download the boundary JSON — JAD logs each over-threshold frame's
pts_timeand writes<yourfile>-scenes.json:{ "threshold": <value>, "cuts": [<seconds>, ...] }. These seconds are your split points. - Step 4Decide: split everything, or extract one segment — To cut the file into every segment, use video-splitter with the boundary list. To pull just one segment between two boundaries (e.g. seconds 54.88 → 91.2), use lossless-trimmer with those start/end values.
- Step 5Account for keyframe snapping in lossless mode — The lossless trimmer uses FFmpeg
-c copyand snaps the start to the nearest prior keyframe, so a stream-copied segment may begin slightly before the exact boundary. If you need frame-exact cuts, choose a re-encoding split path instead (a sibling tool that re-encodes), accepting the quality/time cost. - Step 6Verify the split count matches the boundaries — N boundaries produce up to N+1 segments. If the count is off, the threshold likely caught false-positive boundaries (motion) or missed soft ones — adjust the threshold, re-scan, and re-split. Re-detection is free and read-only.
Threshold as a segment-count dial
How threshold maps to how many segments you'll end up with. Counts are illustrative.
| Threshold | Boundaries found | Resulting segments |
|---|---|---|
0.5 (conservative) | Few — only clear scene changes | Fewer, longer segments — good for chapter-level splits |
0.3 (default) | Most hard cuts | Balanced — one segment per shot in typical footage |
0.1 (aggressive) | Many — includes soft cuts + motion false-positives | Many short segments — prune the array before splitting |
Pick the right split tool for the boundaries
The detector finds boundaries; these siblings do the cutting. Choose by whether you need frame-exact cuts.
| Goal | Tool | Cut accuracy |
|---|---|---|
| Cut whole file at all boundaries | video-splitter | Depends on the splitter's mode |
| Extract one segment between two cuts | lossless-trimmer | Stream-copy: start snaps to prior keyframe |
| Re-assemble kept segments | video-merger | Concat (stream-copy if same codec, else transcode) |
| Visual check of the boundaries | frame-grid-maker | N/A — contact sheet only |
Tier limits (video family)
Source-size and batch caps for the detect-then-split workflow.
| Tier | Max file size | Batch files |
|---|---|---|
| Free | 1 GB | 1 |
| Pro | 10 GB | 5 |
| Pro-media | 100 GB | 50 |
| Developer | 100 GB | Unlimited |
Cookbook
Detect-then-split recipes. The detector produces the boundary JSON; a sibling tool performs the actual cut.
Scene-aligned split of a multi-shot clip
Instead of splitting every 60 seconds (which would chop shots), detect boundaries first, then split at them so each segment is a whole shot.
Step 1 scene-detector (threshold 0.3)
→ clip-scenes.json: cuts: [8.34, 27.1, 54.88, 91.2]
Step 2 video-splitter at those seconds
→ 5 segments, each a complete shot:
0–8.34, 8.34–27.1, 27.1–54.88, 54.88–91.2, 91.2–endExtract one scene with the lossless trimmer
You only need the third scene. Take its start/end from the boundary list and pull it losslessly — no re-encode, just stream copy.
Boundaries: [8.34, 27.1, 54.88, 91.2] Want scene 3 → start 54.88, end 91.2 lossless-trimmer: startSec 54.88, endSec 91.2, -c copy Note: start snaps to nearest prior keyframe, so the clip may begin a few frames before 54.88. Trade-off for zero re-encode and instant export.
Fewer, chapter-sized segments
For a course video you want chapter-level segments, not one-per-shot. Raise the threshold so only major scene changes become boundaries.
Threshold 0.3 → 22 boundaries (too granular) Threshold 0.5 → 6 boundaries (chapter-level) Split at the 6 → six chapter clips. Re-scanning to find the right granularity is free and read-only.
Prune motion false-positives before splitting
A handheld section adds spurious boundaries that would create tiny useless clips. Either raise the threshold, or remove boundaries closer than your minimum segment length from the JSON before feeding the splitter.
cuts: [..., 61.0, 61.4, 61.9, ...] ← shake cluster Min segment you want: 2 s Drop 61.4 and 61.9 (too close to 61.0). The tool has no min-scene-length option, so prune the array yourself, then split on the cleaned list.
Split, keep the good scenes, re-merge
Full smart-split pipeline: detect boundaries, split into segments, discard the bad takes, merge the keepers into one assembly.
scene-detector → boundaries video-splitter → scene_01..scene_05 (discard scene_02, a flubbed take) video-merger → final assembly of 01,03,04,05 Merger stream-copies if all segments share a codec, else transcodes. The detector only starts the chain.
Edge cases and what actually happens
The detector does not split the video
By designDetection finds boundaries and outputs a JSON timestamp list — it never cuts the file. The split is a separate step: feed the boundaries to video-splitter for a full split, or lossless-trimmer to extract one segment. Treating the two as a pipeline is the intended workflow.
Lossless split starts a few frames early
By designWhen you split with stream-copy (-c copy), the lossless trimmer snaps the segment start to the nearest prior keyframe, so a clip can begin slightly before the boundary in the JSON. This is inherent to keyframe-boundary cutting without re-encoding. For frame-exact starts, use a re-encoding split path and accept the time/quality cost.
Too many short segments from a low threshold
ExpectedA threshold near 0.1 produces many boundaries, some on motion, which split into lots of tiny clips. Raise the threshold to get coarser boundaries, or prune boundaries closer than your minimum segment length out of the cuts array before splitting. There is no min-scene-length control in the detector.
Soft transition not chosen as a boundary
ExpectedA cross-dissolve between two scenes changes gradually and may not exceed 0.3, so no boundary is recorded there and the two scenes end up in one segment. Lower the threshold toward 0.1–0.2 to surface the boundary, accepting extra false-positives elsewhere.
Boundary count vs segment count
ExpectedN detected boundaries yield up to N+1 segments when you split the whole file (the regions before the first cut and after the last cut are also segments). If your split tool produced a different count than you expected, recheck whether it treats the file start/end as implicit boundaries.
Empty boundary list
ExpectedIf cuts is [], no boundary exceeded the threshold — the source is effectively one continuous shot, and there is nothing to split on. Lower the threshold to find subtler boundaries, or accept that the file is a single scene.
Threshold clamped to 0.05–0.9
ClampedValues outside the range snap to the bounds. 0 would mark every frame as a boundary (splitting into single frames); 1.0 would find none. The applied threshold is stored in the JSON so your split is reproducible.
File over the tier cap
RejectedA source larger than your tier cap (Free 1 GB, Pro 10 GB, Pro-media/Developer 100 GB) is rejected before detection. Detect on a smaller proxy to get the boundaries, then split the original at the same seconds.
Slow scan on a large source before splitting
ExpectedBoundary detection decodes every frame (-f null -) with no fast-seek, so it is slower than the split itself when the split is a stream copy. Detect on a proxy of the same edit to speed up boundary-finding; the seconds map directly to the original for the split.
FFmpeg core fails to load
ErrorIf the FFmpeg.wasm core cannot be fetched, detection throws 'FFmpeg core failed to load.' Self-host the @ffmpeg/core assets on restricted networks. The splitter/trimmer use the same engine, so resolving this fixes the whole pipeline.
Frequently asked questions
Does this tool split my video at the scene boundaries?
No. It detects the boundaries and outputs a JSON list of timestamps. To actually split, feed those timestamps to video-splitter for a full split, or to lossless-trimmer to extract one segment between two boundaries.
How do I control how many segments I get?
Use the threshold as a granularity dial. 0.5 finds fewer boundaries (fewer, longer segments — chapter-level); 0.3 is balanced (roughly one per shot); 0.1 finds many (lots of short segments). Re-scan to dial it in, then split on the chosen list.
Why does my lossless split start slightly before the boundary?
The lossless trimmer uses -c copy and snaps the start to the nearest prior keyframe, so a stream-copied segment can begin a few frames before the exact boundary in the JSON. That's the trade for zero re-encode. For frame-exact starts, use a re-encoding split path.
How many segments will N boundaries create?
Up to N+1 when you split the whole file, because the regions before the first cut and after the last cut are also segments. Check whether your split tool treats the file start and end as implicit boundaries when reconciling counts.
What if I want chapter-sized segments, not one per shot?
Raise the threshold toward 0.5–0.6 so only major scene changes become boundaries. That collapses many shot-level cuts into a few chapter-level boundaries, giving you a handful of longer segments.
Can I remove tiny spurious boundaries before splitting?
Yes — edit the cuts array. The detector has no min-scene-length option, so to avoid tiny clips, drop any boundaries closer together than your minimum segment length, then feed the cleaned list to the splitter.
Is detection read-only? Will my source change?
Detection is strictly read-only — it decodes frames to score them but never rewrites the file. Your source is untouched during boundary-finding. Any change happens only in the separate split/trim step you run afterward.
Is the file uploaded during detection?
No. Detection runs in your browser via FFmpeg.wasm; the source never leaves your machine. Only the FFmpeg core is fetched (and can be self-hosted), so the entire detect-then-split workflow stays local.
Can I detect on a proxy and split the original?
Yes. The boundary seconds come from pts_time, which is timeline-relative, so they apply to the original media. Detect on a fast proxy, then split the full-resolution original at the same seconds.
What's the empty-array result mean for splitting?
An empty cuts array means no boundary exceeded the threshold — the file is one continuous shot, so there's nothing to split on. Lower the threshold to find subtler boundaries if you expected more.
Which formats can I split-prep?
MP4, MOV, MKV, WebM, AVI, M4V and TS for detection. The split tool you choose then handles the cut; same-codec concat in the merger lets you re-assemble kept segments without re-encoding.
How do I re-assemble the good segments after splitting?
Use video-merger. If all kept segments share the same codec, it concatenates them with stream-copy (no re-encode); otherwise it transcodes. The detector only starts the chain by finding the boundaries.
Privacy first
Every JAD Video tool runs entirely in your browser via WebCodecs and FFmpeg (WebAssembly). Your video files never leave your device — verified by zero outbound network requests during processing.