Field notes
Every tool for this asks for a healthy clip from the same camera, and the advice everywhere is that you cannot proceed without one. For most recordings that is not true, and this explains why.
When a camera loses power mid‑recording, the video is all on the card but the index describing where each frame lives was never written. Rebuilding that index means finding the frames again, and writing a header that says how to decode them.
That header needs the codec configuration: the picture size, the profile and level,
and the parameter sets a decoder initialises from. In an MP4 those live in a box
called avcC, inside the index that was never written. So the usual
reasoning goes: the configuration is gone, therefore it must be copied from a
recording made the same way, therefore you need a second clip.
Encoders also write the parameter sets into the video stream, next to the pictures, in H.264 and in HEVC. They are there so that a decoder joining a broadcast partway through can start decoding without any container at all, and cameras write them because that is what their encoders do.
So in a great many recordings the configuration is sitting in the damaged file the whole time. A sequence parameter set gives the picture size directly, and its optional timing section gives the frame rate. That is everything the missing header needed.
Measured, not assumed. On nine GoPro recordings — HERO5, HERO6, HERO7, HERO8, Karma, Fusion, MAX and a HERO6 with BLE — the parameter sets were present in every one, and the header rebuilt from them came out byte‑identical to the one the camera originally wrote.
Drop the file into the checker below. It reads the media, looks for a real parameter set, and if it finds one it reports exactly how many frames are recoverable and how many seconds that is. If it does not find one, it says so and asks for a clip from the same camera, because that is the honest answer rather than a guess.
It runs in your browser on any computer, nothing is uploaded, and only the parts of the file that decide the answer are read.
A parameter set is a short run of bytes with no marker announcing it, and a large recording contains millions of positions where telemetry or compressed picture data happens to look like one. A search that accepts the first plausible match will report a configuration for files that carry none at all — confidently, and wrongly.
Three things have to agree before a match counts:
That last one carries most of the weight, and it has to be a four‑byte length. A one‑byte length agreeing is a one in 256 coincidence, and a search across tens of millions of positions manufactures thousands of those: in testing it reported a 656×16 picture in a QuickTime file that carries no parameter sets, and a 448×32 one in a drone recording. Four bytes agreeing is roughly one in four billion, which a search that size cannot invent.
Some muxers strip the parameter sets out of the stream, because the container is supposed to hold them and repeating them is redundant. Files written by Apple's QuickTime muxer and by some drones are like this, and no amount of searching will find what was never written.
A reference clip is the ordinary answer for those, and a tool that offers a configuration it cannot read is guessing at your footage. The clip does not need to be related to your recording in any way: any clip from the same camera in the same mode will do, and a few seconds recorded right now is enough.
A phone strips its parameter sets like any other Apple muxer, so by the rule above it ought to need a reference clip. It does not, because it writes something better, and for its own reasons: a phone cannot know it is about to be dropped. About ten seconds into a take, iOS lays a complete index into the middle of the recording itself, filed under a box type players are required to step over, and keeps extending it while recording continues. A take that ends normally appends the real index at the end and abandons that scaffold. A take that ends in a drained battery leaves it behind.
That is the camera's own account of what it wrote and where, so there is nothing to search for and nothing to infer. Every frame comes back at the offset, the size and the display time the phone recorded — and unlike a scan, the sound comes back with it, sample for sample.
| iPhone 11, no reference clip | Frames | Audio | Decode errors |
|---|---|---|---|
| take cut at 50% | 297 / 297 | 431 / 431 | 0 |
| take cut at 60% | 297 / 297 | 431 / 431 | 0 |
| take cut at 85% | 596 / 596 | 862 / 862 | 0 |
| second take, cut at 85% | 300 / 300 | 431 / 431 | 0 |
The limit is worth knowing before you need it. The index describes the recording as of its last checkpoint, so a take that ended before the first one has nothing to read: on both takes above that threshold fell at about ten seconds. Cut shorter than that, and the file is refused with a request for a reference clip rather than a guess at what it might have held.
It also means a reference clip still recovers more where you have one, because a scan reaches past the last checkpoint and an index cannot. The take cut at 60% above gives 297 frames from its own index and 484 with a clip from the same phone. Cinesalve says which route it took and how much footage lies past the checkpoint, so that choice is yours to make rather than one quietly made for you.
If the recording in question came off a phone, the iPhone steps in detail, starting with getting the original off the device unconverted.
A Mac app that does this. Drop in the recording that will not play: it reads the camera's own index where the camera left one, reads the configuration out of the video where that is there instead, and asks for a clip only when the file truly carries neither. Every recovered frame lands at the byte offset and size the camera originally wrote.
| Recovered from the damaged file alone | Frames | Exact | Decode errors |
|---|---|---|---|
| GoPro HERO5 | 456 / 456 | 100% | 0 |
| GoPro HERO6 | 425 / 425 | 100% | 0 |
| GoPro HERO7 | 170 / 170 | 100% | 0 |
| GoPro HERO8 | 323 / 323 | 100% | 0 |
| GoPro Karma | 200 / 200 | 100% | 0 |
| GoPro Fusion | 160 / 160 | 100% | 0 |
| GoPro MAX | 175 / 175 | 100% | 0 |
| GoPro MAX, 360 mode (dual lens) | 175 / 175 | 100% | 0 |
| GoPro HERO6 with BLE | 181 / 181 | 100% | 0 |
Send it to cinesalve@proton.me (or use the contact form) and you will get a straight answer about what is in it, and it will be added to the test suite.