arthur/clips
Your Name e26ad723fa Measure the frame rate rather than believing the container
`probe` took `r_frame_rate` whenever it was at or under the cap, on the
grounds that it is the rate that keeps every distinct source frame. It is
not a claim about frames at all: ordinary iPhone footage declares 120 over
a stream whose timestamps are 1/30s apart, and resampling it up turned an
11-second clip into 1293 proxy frames instead of 323 — four times the
encode, four times the tracing stills (91MB against 23MB), four times the
blobs and the rows, for 970 frames that are copies of their neighbours.

So `_measured_rate` reads the timestamps and `_choose_rate` keeps whichever
declared rate they bear out. Two details carry it: the times are sorted
before differencing, because an HEVC stream arrives in decode order and
differencing that measures the reordering delay instead of the rate; and
the statistic is the MEDIAN interval, which is what keeps the property the
nominal rate was being taken for — a take held on one frame still reports
the rate of the parts that move, so no distinct frame is dropped. A genuine
120fps capture still extracts at 120, and there is a test on that
specifically.

`Source.probe` also stopped being the place a reading goes to be preserved.
The facts are a pure function of bytes that are the row's own identity, so
a re-upload re-reads them: otherwise every already-uploaded source would
have gone on resampling to four times the frames with no way to correct it
short of deleting the row.

Already-extracted footage is untouched — `extraction_key` still says
scheme 3, so those jobs stay done and reachable. Bumping it re-extracts
everything at the corrected rate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 23:22:50 -04:00
..
management Stream block uploads and compress cached mouth crops 2026-09-28 14:37:09 -04:00
migrations Represent tracing media as symbols and add pool thumbnails 2026-10-04 00:02:12 -04:00
templates/clips Version static URLs by mtime; flatter tabs 2026-09-29 13:08:38 -04:00
tests Measure the frame rate rather than believing the container 2026-10-04 23:22:50 -04:00
__init__.py Serve the document from a Django backend, split into three tiers 2026-09-28 01:11:41 -04:00
admin.py Support multiple regeneratable footage analyses 2026-10-03 01:24:45 -04:00
apps.py Serve the document from a Django backend, split into three tiers 2026-09-28 01:11:41 -04:00
blobs.py Stream block uploads and compress cached mouth crops 2026-09-28 14:37:09 -04:00
consumers.py Projects live at URLs, have owners, and are edited together live 2026-09-29 22:04:03 -04:00
extraction.py Measure the frame rate rather than believing the container 2026-10-04 23:22:50 -04:00
models.py Represent tracing media as symbols and add pool thumbnails 2026-10-04 00:02:12 -04:00
routing.py Projects live at URLs, have owners, and are edited together live 2026-09-29 22:04:03 -04:00
urls.py Represent tracing media as symbols and add pool thumbnails 2026-10-04 00:02:12 -04:00
views.py Measure the frame rate rather than believing the container 2026-10-04 23:22:50 -04:00