tams-keyframe-generator — visual index
tams-keyframe-generator — visual index
Section titled “tams-keyframe-generator — visual index”A store you can only play is a store you have to watch. This produces a picture per second of every recorded video flow, so material can be looked at — browsed, scanned, and found — instead of scrubbed through in real time.
- Produces: a derived TAMS flow of JPEG keyframes, one per second of media time
- Default size: 240 × 120, configurable
- Addressed by: a companion JSON frame-index flow
How it works
Section titled “How it works”Discover. On startup it registers a webhook on the TAMS server for flow and segment creation, and reconciles existing flows by polling. New segments arrive by webhook; a periodic reconcile pass backfills anything missed. As with the transcode watcher, that redundancy is deliberate — webhook delivery is best-effort, and the poll turns a missed event into a delay rather than a permanent gap in the index.
Queue. Each observed source segment becomes a de-duplicated job, so the same segment seen twice is not processed twice.
Process. A pool of workers downloads the source segment, decodes it, picks the decoded frame at each whole-second point inside that segment’s time range, encodes each as a JPEG at the configured size, packs them into a single object with a frame index, and registers a keyframe segment covering the same time range as the source.
Why the cadence is measured in media time
Section titled “Why the cadence is measured in media time”Keyframes land on a global integer-second grid in media time, not wall-clock time.
This matters more than it sounds. A segment boundary is an arbitrary place in the material — it falls where the recorder happened to close a segment. If the one-second cadence were counted from the start of each segment, the grid would shift at every boundary, and two adjacent segments would disagree about where a second begins. Anchoring to a global grid means the nth keyframe of a flow is always the same moment of that flow, regardless of how the material happened to be segmented, and regardless of when the generator got round to processing it.
Why the derived flow mirrors the source
Section titled “Why the derived flow mirrors the source”One derived segment per source segment, covering the same time range. The keyframe flow therefore has the same shape as the material it describes: ask for a time range and you get the pictures for exactly that range, with no mapping step and nothing to go out of sync when the source is trimmed by retention.
Configuration
Section titled “Configuration”Connection and authentication follow the usual TAMS client pattern — basic auth, a bearer token, or OAuth2 client credentials.
Beyond that the useful knobs are the keyframe width, height and quality, the interval in media seconds, and include/exclude flow filters for restricting which flows get an index at all. The webhook receiver needs a publicly reachable callback URL and takes a shared-secret header, so the TAMS server can prove it is the one calling.
Sizes are the one place to be careful: width must be a multiple of 16 and height a multiple of 8.
