The video engine in this repository has five rungs of evidence. Four of them can never fire — including the only one that runs a model. The single rung that can decide anything reads a cryptographic signature, never the pixels.
The reason is written into the file. `inference/app/engines/video_ladder.py` opens with a docstring headed **WHY THIS FILE DOES NOT CLASSIFY VIDEO**, and the first line under it is: "The deployable open video-classifier set is empty."
That is a stronger claim than "we haven't built it yet," so here is the survey behind it.
Three ways an open video detector fails
Every candidate we looked at fails on one of three grounds. Not a mix of small problems — one disqualifying problem each.
| Detector | Fails on | What we found | | --- | --- | --- | | GenConViT | Licence | MIT code, CC-BY-NC-4.0 weights | | SBI | Licence | Non-commercial by its own terms | | DeepfakeBench (36-detector zoo) | Licence | Non-commercial by its own terms | | DeMamba | Weights | Apache-2.0 code, no checkpoints released | | TALL4Deepfake | Weights | No checkpoints shipped | | FTCN | Accuracy | AUC 0.50 on Deepfake-Eval-2024, an independent in-the-wild evaluation |
The licence column is the one people wave away, and it is the one that actually decides the matter. GenConViT's code is MIT — take it, sell it, do what you like. Its weights are CC-BY-NC-4.0, which means no commercial use. The code is the recipe. The weights are the only part that has learned anything. Shipping the recipe without the learning gets you a model that outputs noise.
So the licence is not paperwork sitting between a company and a working product. It is the reason a whole category of product cannot legally exist on top of the open state of the art. Anyone charging money for synthetic-video detection built on these weights is either not using them, or is not entitled to.
The accuracy row needs one piece of vocabulary. AUC is the probability that a detector scores a randomly chosen synthetic clip above a randomly chosen genuine one — 1.0 is perfect, and 0.50 is a coin flip. Off-the-shelf FTCN measures 0.50 on Deepfake-Eval-2024. Not "degraded." Chance.
The escape hatch is closed too
The obvious answer to a survey like that one is: fine, then fine-tune your own. Collect the labelled video, train a detector nobody else's licence encumbers, publish your numbers.
The obvious corpus to do it with is gated behind terms stating, verbatim:
> Users may only use this dataset for evaluation. Use of this dataset for training goes against the terms of use.
Evaluation only. You may measure against it and you may not learn from it.
You can defend that rule — an evaluation set stays honest exactly as long as nobody trains on it — but you cannot route around it and still call the result licensed. Between weights you may not sell and data you may not train on, the open path to a commercial video classifier does not currently have a legal exit.
Why you cannot just score the frames
The next idea is the intuitive one: a video is a stack of images, and image detectors do work. Sample some frames, score them with the image model, aggregate.
Vahdati et al. measured this directly (CVPRW 2024, arXiv 2404.15955). They put eleven synthetic-image detectors onto synthetic video frames. On images the detectors sat at roughly 0.97 AUC. On video frames the best of the eleven managed 0.698, and one scored exactly 0.500 — chance, from a detector that works on stills.
The natural explanation is compression: video is H.264, images are not, and the artefacts a detector reads get smeared. So they retrained eight of them with H.264 augmentation. The best result recovered to 0.744.
That residual is the finding. The gap is not compression, it is domain. Video generators leave different traces than image generators do, and a model trained on the second set is not looking for the first. No threshold, however carefully chosen, converts 0.744 into a video verdict.
Newer numbers are worse, not better. RA-Bench (arXiv 2608.14391) ran seven traditional detectors against nine video generators and reports their AUC falling from 67.6–98.6% in the published references to source-level means of 43.9–57.3% on its own clips — written on a 0–100 scale, so the bottom of that range sits below the 50 that marks a coin flip, and against some sources the detector does worse than guessing.
And Community Forensics, the still-image model this service actually runs, has never been benchmarked on video frames by anyone. Not badly. Not at all.
What happened when we tried it anyway
We ran the pilot regardless, because a survey of other people's numbers is not a measurement of ours. Rung 5 decodes I-frames, scores up to eight of them with the image model, and publishes the scores while deciding nothing. The question was whether it could ever be promoted to deciding something.
Nine videos: three genuine camera captures and six from generators. Every file, its source, its licence and how much of its attribution is actually proven is recorded in `evidence/video-corpus.md`.
| Source | Frames scored | At or above the 0.5 firing threshold | Highest score | | --- | --- | --- | --- | | Truepic attested capture | 8 | 0 | 0.13 | | NASA ISS footage | 8 | 0 | 0.004 | | Commons CC0 bird close-up | 6 | 0 | 0.0001 | | **All genuine footage** | **22** | **0** | **0.13** | | All six AI clips | **0** | — | — |
Zero false fires across 22 frames of genuine footage reads like a good result. It is not one, and the asymmetry is the point: a high false-fire rate could have retired the idea outright, while a clean run cannot establish the reverse.
Those 22 frames come from three clips, and frames within a clip are heavily correlated, so the effective sample is nearer three than twenty-two. Our own evidence file previously quoted a 95% upper bound of about 13% here. That was the bound for 22 *independent* frames — the exact assumption the sentence beside it said did not hold. At n = 3 the bound is about 63%. Sixty-three percent is not a number anything can be built on, and correcting it in public is cheaper than being wrong quietly.
Then there is the last row. The rung could not sample a single one of the six AI clips. Each decoded to exactly one I-frame, below the four that the rung requires before it will claim to have spread samples across a video. A rung that cannot sample the media it would have to fire on cannot be promoted whatever its scores are.
Even where it does sample, the reading is narrow in ways worth stating. Each frame is scored alone, so nothing temporal is visible — flicker, identity drift and impossible physics, the artefacts that actually give AI video away, are invisible to a still-image model. The model's 384×384 centre crop keeps roughly 43% of a 16:9 frame, so anything off-centre was never looked at. No audio is examined anywhere in this lane, so a cloned voice or an AI dub passes untouched.
What runs on a video instead
The verdict stays `uncertain` at 50, with an interval of [20, 80]. That band is deliberately wider than the image lane's [25, 75], because four of five rungs can never fire here — "nothing fired" on a video means strictly less was ruled out than the same words mean on an image.
Underneath the verdict, the rungs that are honest on a video container all run and all report. C2PA manifests get real signature validation. Rung 3 parses ISO-BMFF container structure — box order, index placement, timestamps, writer strings — and is capped so it can never decide, because container ballistics attribute the *last writer* of the file, which for video is nearly always a transcoder rather than the origin of the pictures. We tested that cap rather than assuming it: across the corpus, 0 of 6 generators self-identified in the container, and a single stream copy — `-c copy`, not even a re-encode — on a signed file replaced its writer string and destroyed its C2PA box outright. Rung 4 hashes each keyframe into a timeline. Rung 5 publishes its frame scores with the caveats above attached to them.
Only rung 1 can move the answer. A clip signed by Google's generative pipeline — first-party bytes, confirmed by the BMFF hash matching, which any re-encode would have broken — returns `ai`, 97, tier `proof`, decided by C2PA. That is n = 1: one generator, one file. It demonstrates the path works end to end on real bytes and it is not a coverage rate.
The clearest case is the one that goes the other way. The Truepic clip from the C2PA public test files verifies against its exact bytes and names a hardware-attested capture SDK. You can fetch it yourself:
```bash curl -sL -o truepic.mp4 \ https://raw.githubusercontent.com/c2pa-org/public-testfiles/main/legacy/1.4/video/mp4/truepic-20230212-zoetrope.mp4 ```
It returns `uncertain`. Its active manifest carries no `c2pa.actions` and no `digitalSourceType` — a valid signature over a file that never says how the content was made, which is not provenance of capture. Its signer also sits on the C2PA's frozen interim list rather than the conformance list, so it reads `untrusted-chain`: it could still accuse, and may never exonerate.