How to find all scene changes in a long video
- Step 1Load the long video — Drop your
.mp4,.mov,.mkv,.webm,.avi,.m4vor.tsrecording onto the tool. The whole file loads into the browser; nothing uploads. For multi-hour 4K masters, prefer a 1080p proxy if you have one — detection results map back to the same timestamps and the proxy scans far faster. - Step 2Choose a threshold suited to long-form content — Leave Threshold at
0.3for a typical lecture or conference recording. For a single-camera talking-head VOD where you only want true scene breaks, raise to0.5. For a stream VOD with frequent overlay/scene swaps,0.3is usually right; lower toward0.1only if you must catch slow fades. - Step 3Start the full-timeline scan — JAD runs
select='gt(scene,T)',showinfo -f null -across the entire file. Every frame is decoded, so expect a long-form scan to take minutes, not seconds — there is no keyframe-only fast path. Keep the tab open; the work happens on your CPU. - Step 4Download the cut list — The detector parses every
pts_timeinto a numeric array and writes<yourfile>-scenes.json:{ "threshold": <value>, "cuts": [<seconds>, ...] }. For a long video this can be dozens of entries spanning the full duration. - Step 5Spot-check the density — Eyeball the count against the runtime. A 90-minute lecture with one camera might yield only a handful of cuts; a multi-cam panel could yield 50+. If the count looks implausibly high, motion/zoom false-positives are likely — raise the threshold and re-scan.
- Step 6Route the timestamps downstream — Convert the seconds into
HH:MM:SSchapter markers, or hand the list to video-splitter to segment the long file, or use thumbnail-extractor to grab a still at each cut. For a quick visual map of the whole video, run frame-grid-maker.
Long-form scan: what to expect
Realistic outcomes by content type. Cut counts are illustrative — your footage varies.
| Long-form type | Suggested threshold | Typical result |
|---|---|---|
| Single-cam lecture / webinar | 0.3 | Few cuts — mostly slide changes and the occasional B-roll insert |
| Multi-cam conference panel | 0.3 | Many cuts — one per angle switch; can be dozens over 90 min |
| Stream VOD with scene overlays | 0.3 | Frequent cuts at overlay/scene swaps; raise to 0.5 if intros over-trigger |
| Documentary with dissolves | 0.1–0.2 | Soft transitions caught at low threshold, plus false positives on motion |
| Static screen recording | 0.3 | Often [] — no scene changes in a locked-off capture |
Detection facts that matter for big files
The implementation details that govern long-video runs.
| Fact | Value | Why it matters for long videos |
|---|---|---|
| Decode coverage | Every frame (-f null -) | No fast-seek; runtime scales with duration and resolution |
| Memory model | Whole file read into memory | RAM, not the size cap, is the real ceiling on multi-hour 4K |
| Engine | FFmpeg.wasm MT, falls back to single-thread | Multithread is faster but needs cross-origin isolation; ST still works |
| Output size | Tiny JSON regardless of input | The cut list is just numbers — a 3-hour scan still yields a small file |
| Re-encode | None | Your long master is never rewritten |
Tier limits (video family)
File-size and batch caps. Long videos count as one file per run.
| Tier | Max file size | Batch files |
|---|---|---|
| Free | 1 GB | 1 |
| Pro | 10 GB | 5 |
| Pro-media | 100 GB | 50 |
| Developer | 100 GB | Unlimited |
Cookbook
Workflows for finding cuts in genuinely long footage. Timestamps are abbreviated examples.
Scan a 90-minute conference recording
A multi-cam panel switches angles throughout. At the default threshold the detector returns one entry per angle switch across the full 90 minutes.
Input: panel-keynote.mp4 (1:31:12, 1080p)
Threshold: 0.3
Output: panel-keynote-scenes.json
{
"threshold": 0.3,
"cuts": [ 12.4, 88.0, 201.7, 355.2, ... 4980.6 ]
}
(38 cuts spanning the full runtime)Use a proxy to scan a 4K multi-hour master fast
Scanning a 3-hour 4K file frame-by-frame in WASM is slow and memory-heavy. Detect on a 1080p proxy of the same edit; the timestamps map 1:1 back onto the 4K master.
Master: doc-final-4k.mov (2:47:00, 4K) ← slow, RAM-heavy Proxy: doc-final-1080.mp4 (same edit) ← scan this Threshold 0.2 on the proxy → cuts[] Apply the same seconds to the 4K master in your NLE. Detection times match because pts_time is identical.
Lecture with only slide changes
A single-camera webinar where the only visual changes are slide swaps. The default threshold catches each slide transition; the result doubles as a slide-change index.
Input: webinar.mp4 (58:20, single cam) Threshold 0.3 → cuts: [45.0, 312.8, 690.1, 1024.4, ...] Each timestamp ≈ a slide change. Convert to HH:MM:SS for a chapter list, or split at each for per-slide clips.
Over-triggering stream VOD — raise the threshold
A Twitch/YouTube VOD with animated scene overlays trips many cuts at 0.3 because animated intros/transitions move a lot. Raising to 0.5 isolates the true segment changes.
Threshold 0.3: 120 cuts (overlay animations counted) Threshold 0.5: 22 cuts (true scene swaps) For a clean chapter list, 0.5 is the better choice here. Re-scanning only changes the threshold; file untouched.
Chain into the splitter for highlight segments
Detection finds the boundaries across the long file; the splitter cuts it. This is the standard long-form pipeline — detector first, splitter second.
Step 1 scene-detector → panel-keynote-scenes.json
Step 2 feed cuts[] to video-splitter
→ one clip per detected segment
The detector alone returns JSON; it does not cut clips.Edge cases and what actually happens
Multi-hour 4K hits browser memory before the size cap
ExpectedScene detection reads the whole file into memory and decodes every frame, so a multi-hour 4K master can exhaust browser RAM even when it is under your tier's GB cap. Use a lower-resolution proxy of the same edit — the pts_time values are identical, so the cut list maps 1:1 back onto the 4K master.
Long scans take minutes, not seconds
ExpectedBecause detection forces a full decode (-f null -), runtime scales with both duration and resolution — there is no keyframe-only shortcut. A 90-minute 1080p file may take a few minutes in FFmpeg.wasm; a 4K multi-hour file far longer. Keep the tab focused so the browser does not throttle the worker.
Animated overlays in a VOD inflate the cut count
ExpectedStream VODs with animated scene transitions or moving overlays produce many false-positive cuts at the default threshold. Raise toward 0.5–0.6 to count only real segment changes. The tool has no min-scene-length filter, so trim short spurious gaps from the cuts array yourself after download.
Single-shot lecture returns an empty list
ExpectedA locked-off single-camera lecture with no slide changes can return cuts: [] — there were no scene changes to find. Lower the threshold if you want to catch subtle lighting drift, but for a genuinely static recording the empty array is the correct answer.
File over the tier size cap is rejected
RejectedFree caps source files at 1 GB, Pro at 10 GB, Pro-media and Developer at 100 GB. A long file over your cap is rejected before processing. For very long footage, re-encode a smaller proxy first (a different sibling tool) or upgrade the tier — but remember memory may still limit before the cap.
MT engine times out and falls back to single-thread
Falls backThe detector tries the multithreaded FFmpeg core first; if it does not initialise within 25 seconds (commonly because cross-origin isolation/SharedArrayBuffer is unavailable), it silently falls back to the single-thread core. Single-thread still produces the same cut list — just slower on a long file.
VFR or variable-runtime stream
PreservedStream recordings are often variable-frame-rate. pts_time reports each frame's true presentation time, so cuts land on accurate wall-clock seconds rather than an assumed constant grid — important when mapping a long VOD back onto its real timeline.
Threshold outside 0.05–0.9
ClampedAny value below 0.05 or above 0.9 is clamped to the bound. On a long video this guards against 0 (which would log every frame and produce a useless, enormous list) and 1.0 (which would log nothing). The threshold actually applied is recorded in the JSON.
FFmpeg core fails to load on a locked-down network
ErrorIf the browser cannot fetch the FFmpeg.wasm core (offline, or unpkg.com blocked by corporate policy), the run throws 'FFmpeg core failed to load.' Self-host the @ffmpeg/core assets, or use a network that permits the CDN fetch. This is the one and only network dependency.
Unsupported container in a long recording
Falls back to mp4Recognized containers are mp4, mov, mkv, webm, avi, m4v and ts. A long file with an unrecognized extension is treated as mp4 and may fail to decode if the true container differs (e.g. an old .flv capture). Remux to a supported container before scanning.
Frequently asked questions
Can it scan a multi-hour video?
Yes, within your tier's size cap (Free 1 GB, Pro 10 GB, Pro-media/Developer 100 GB) and your browser's memory. Because detection decodes every frame and loads the whole file into memory, a multi-hour 4K master may exhaust RAM first — scan a lower-resolution proxy of the same edit and map the timestamps back.
Why is the long scan slow?
Detection runs -f null -, forcing a full frame-by-frame decode of the entire file — there is no keyframe-only fast path. Runtime scales with duration and resolution, so long-form scans take minutes. Using a 1080p proxy dramatically speeds this up while producing identical timestamps.
Is my long recording uploaded?
No. The entire scan runs in your browser via FFmpeg.wasm. A private lecture, internal all-hands, or unpublished course recording never leaves your machine; only the FFmpeg core is fetched from the CDN (and you can self-host it).
What does the output look like for a long video?
A single JSON file <yourfile>-scenes.json containing { "threshold": 0.3, "cuts": [seconds...] }. Even a 3-hour scan yields a small file — it is just an array of numbers, one per detected cut across the whole runtime.
Does it split the long video at the cuts?
No. It only lists the cut timestamps. To actually segment a long file, pass the cuts array to video-splitter, or extract individual segments between cuts with lossless-trimmer.
What threshold should I use for a lecture?
Start at 0.3. A single-camera lecture usually returns only slide-change cuts, which is what you want. If a slow zoom or panning B-roll over-triggers, raise toward 0.5; if subtle slide dissolves are missed, lower toward 0.2.
My VOD returned 100+ cuts — is that wrong?
Probably over-triggered. Animated overlays and scene-transition effects in stream VODs inflate the count at the default threshold. Raise to 0.5–0.6 and re-scan to isolate true segment changes. There is no min-scene-length filter, so also prune short gaps from the array yourself.
Can I detect cuts on a proxy and apply them to the master?
Yes, and it is the recommended approach for big files. Detect on a low-res proxy of the same edit; pts_time is identical between proxy and master, so the seconds in cuts apply directly to the 4K master in your NLE or splitter.
How many cuts can it return?
As many as exceed the threshold — there is no cap. A static recording may return []; a busy multi-cam panel may return dozens or hundreds. If the count is implausible, motion false-positives are likely, so raise the threshold.
Which formats work for long recordings?
MP4, MOV, MKV, WebM, AVI, M4V and TS. Long captures in unsupported containers (e.g. legacy FLV/WMV) should be remuxed to one of these first, or detection may fail to decode.
Will scanning re-encode or degrade my master?
No. Detection is read-only — it decodes frames to score them but never writes a new video. Your long master is returned untouched; the only output is the JSON cut list.
How do I turn the long cut list into chapters?
Convert each second value in cuts to HH:MM:SS (the first must be 00:00) and paste into the description for YouTube chapters. The tool does not write chapter files; to read chapters already embedded in a file, use chapter-extractor.
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.