Thumbnail output
Generate JPEG previews with current status and metrics, optional HTTP serving and S3 publication.
output.thumbnails
Generate immutable local JPEG previews from verified H.264 IDR pictures on local SRT push and managed source-pull streams. Cascade input, cascade serving, outbound target-push and closed VOD do not start this branch. The interval is a target on the normalized 90 kHz media timeline: the first eligible IDR after it becomes due is selected.
"thumbnails": {
"enabled": true,
"interval": "10s",
"resize": {
"width": 400,
"height": 225
},
"sessionMaxBytes": 1073741824,
"sessionMaxArtifacts": 10000,
"retention": "0s",
"ffmpegPath": "ffmpeg",
"maxWorkers": 4
}
Omit resize to preserve the SPS display dimensions exactly. When resize is present, both positive dimensions are required and the JPEG is exactly that width and height. There is no implicit aspect-ratio preservation, crop policy or prohibition on scaling up or down. Input and output dimensions must fit within 1920 by 1080 and 2,073,600 pixels.
The feature can run while HLS and recording are disabled. It still requires output.root and the viewer-facing output.http.listener. Producing thumbnails requires local push or managed pull input. A cascade-only node accepts output.thumbnails.enabled: true with publication disabled, but builds no thumbnail runtime and performs no thumbnail FFmpeg probe. Each eligible stream instance reserves an independent output.root/thumbnails/YYYY/MM/DD/{encoded-streamId}/{HHmmssSSS}[~NNN]/ session. JPEG names use {ordinal12}-{pts20}.jpg; thumbnail sessions do not share identity or ownership with vod/ recording sessions.
The defaults allow 1 GiB and 10,000 committed JPEGs per session. Configurable limits are 4 MiB through 1 TiB and 1 through 10,000,000 artifacts. Decoder admission is process-wide, defaults to four workers and has no waiting queue. A candidate is dropped when no worker or storage budget is immediately available, so this branch cannot build a frame backlog or block the media path.
Each JPEG becomes visible only after bounded write, file sync, close and atomic rename; the parent directory is then synced for crash durability. Startup recovery scans only the canonical thumbnails/ tree, removes process-owned incomplete temporary state, rebuilds committed byte and artifact accounting and conservatively closes a session left open by a crash. It does not use recording metadata.
retention defaults to 0s, which disables deletion. A positive duration can remove only a durably closed thumbnail session as one whole-root tombstone operation. With publication enabled, the session must also satisfy its own publication closure. It never targets vod/.
Stream close freezes selector and storage admission before finalization. A late decoder result cannot commit after that boundary. A caller deadline may let Close return before an uninterruptible filesystem sync finishes, but Drained is not reached until the inner output, selector and session finalizer have all returned. Session reservation, decoder or persistence failure degrades only that stream's thumbnail branch; local ingest, HLS and recording continue.
The example above is local-only. Set output.thumbnails.publish to true and configure the shared output.s3 destination to publish committed JPEGs. Current stream detail and process metrics expose the observation surfaces described below.
FFmpeg dependency
This output needs FFmpeg for JPEG generation. The unsuffixed container has no FFmpeg binary; use the matching -transcode image or a compatible custom build. See image variants.
Supported H.264 pictures
Eligible pictures are complete Baseline, Main or High IDR frame pictures with 8-bit 4:2:0 samples. Progressive and complete interlaced frames, including MBAFF, are supported. Levels through 4.1, plus 4.2, 5.0 and 5.1, are admitted within the existing 1920 by 1080 display limit.
Levels 4.2, 5.0 and 5.1 and every interlaced sequence require at most 120 by 68 coded macroblocks and 48,960 decoded-picture-buffer macroblocks. Interlaced coded height includes both fields. The buffer check includes reference pictures, the current picture and any larger SPS VUI declaration. A Level 5.1 signal never enables 4K input, even when resizing to a small JPEG.
Every IDR slice in a non-frame-only sequence must describe the same complete frame (field_pic_flag=0). Separate fields, incomplete pairs, higher levels, other chroma formats and higher bit depths are rejected. Missing IDRs and recovery-point-only inputs cannot produce thumbnails.
For non-frame-only sequences, each isolated JPEG job applies yadif=mode=send_frame:parity=auto:deint=interlaced before optional exact scaling. Decoder frame flags decide whether and how to deinterlace. This does not enable stream transcoding or alter HLS and recording. FFmpeg must provide yadif; the startup probe checks the same filter chain.
Serve committed JPEGs
Generation alone does not expose a public JPEG endpoint. Opt in separately on the existing media listener:
"http": {
"listener": {"host": "0.0.0.0", "port": 8080},
"thumbnails": {"enabled": true}
}
output.http.thumbnails.enabled defaults to false and requires enabled thumbnail generation plus local push or managed pull. It adds GET and HEAD /thumbnails/{sessionId}/{fileName} on the media listener, not the operational listener. Use the committed descriptor's path; the session ID contains its canonical date and stream path. The route adds no thumbnail-specific authentication, so apply the deployment's normal media access boundary and browser-reachable HTTPS endpoint.
Only final regular JPEGs of at most 4 MiB are served. Symlinks, special files, temporary files, metadata, listings, redirects and query strings are rejected. At most 16 reads run with no waiting queue and a five-second response deadline. Deletion before open may return 404; deletion after open does not change the selected bytes.
Status and metrics
GET /api/v1/streams/{streamId} can return thumbnailState and latestThumbnail. The state has an instanceId, decimal revision and nullable sessionId; it also carries a withdrawal watermark when no latest JPEG is available. The optional descriptor has the same complete shape as thumbnail webhooks. Revisions belong to the thumbnail domain, not stream-state or LL-HLS readiness revisions. Consumers must not let an older event restore a withdrawn artifact.
When the local thumbnail runtime is enabled, /metrics exports fixed-label dispergo_thumbnail_* candidate, admission, generation, commit, drop, failure, worker and processing-duration metrics. Publication backlog uses dispergo_thumbnail_publication_pending_items with dispergo_thumbnail_publication_snapshot_ready; zero pending with snapshot readiness zero means unknown, not an empty backlog.
Configuration reference
Use the shared output settings with this module. The complete field reference covers every accepted option; the maximal composition shows how modules fit together.