PlayoutItem records. The streaming engine reads these records in real time to decide what to transcode and deliver to viewers.
The Role of a Playout
Channels and schedules do not interact directly. The playout is the joining entity between them. AChannel has a List<Playout> — meaning one channel can have multiple active playouts simultaneously — and each playout references both the channel and the schedule that drives it.
Schedule Kinds
TheScheduleKind property (PlayoutScheduleKind) identifies which type of schedule is powering this playout:
For Classic schedules, the schedule definition lives in the database. For Sequential, Scripted, and ExternalJson schedules, it lives in a file on disk referenced by
ScheduleFile.
Playout Items
EachPlayoutItem represents one media item placed at a specific point in time in the playout:
The Playout Anchor
ThePlayoutAnchor is ErsatzTV’s bookmark into the current state of the playout build. It tracks:
The anchor is persisted to the database so that incremental playout builds can resume from the correct position rather than rebuilding from the beginning every time.
Playout Build Process
ErsatzTV builds playouts as a background service. The build process:1
Resolve the Schedule
ErsatzTV reads the schedule definition — from the database for Classic schedules, or from the file system for YAML/Scripted/ExternalJson. For Block schedules, it evaluates which templates apply to the current date based on day-of-week, day-of-month, and date range rules.
2
Enumerate Collections
Each schedule item’s collection, multi-collection, smart collection, playlist, or search query is resolved into a concrete ordered list of media items. Playback order (
Chronological, Shuffle, SeasonEpisode, etc.) is applied at this step.3
Place Items on the Timeline
Items are assigned
Start and Finish timestamps. Fixed-time slots snap items to clock times; dynamic (flood/back-to-back) items are placed end-to-end. Filler items are inserted to fill gaps.4
Persist the Playout
The resulting
PlayoutItem records are written to the database. Gaps (PlayoutGap) are recorded for any spans of time in the playout that have no coverage. The PlayoutBuildStatus record is updated with the build result and timestamp.DailyRebuildTime property (TimeSpan?) can be set to force a full playout rebuild at a specific time of day — useful for Block schedules where each day’s programming is determined by template matching.
Playout Build Status
ThePlayoutBuildStatus entity tracks the outcome of the most recent build for each playout:
If
Success is false, check the Message for details about what went wrong — common causes include missing media files, empty collections, or invalid schedule configurations.
Playout History
For Block schedules, ErsatzTV maintains aPlayoutHistory table that records which item from each collection was most recently played in each block:
Playout history is maintained exclusively for Block schedules. It enables ErsatzTV to resume playback of each block’s collection from the correct position after a daily rebuild or playout reset, preserving your channel’s continuity across rebuilds.
Playout Seed
TheSeed property (int) is a random seed stored on the playout. It is used to initialize shuffle and random operations during playout builds, ensuring that a given playout always produces the same random ordering when rebuilt with the same seed. You can change the seed to produce a different shuffle sequence.
Playout Templates (Block Schedules)
For Block schedule playouts, theTemplates collection holds PlayoutTemplate entries that map programming templates to calendar conditions:
ErsatzTV evaluates templates in index order and selects the first matching template for each day.
Playout Offset
The EPG display times for a playout’s items can be shifted by configuringPlayoutOffset (TimeSpan?) on the channel — not the playout itself. This channel-level setting is applied when generating XMLTV guide data, allowing the displayed program times to be offset from the actual playout timestamps. See Channels for details on setting this property.
On-Demand Playouts
When a channel’sPlayoutMode is set to OnDemand, the playout behaves differently from a continuous channel:
- Items are added to the playout queue when a viewer requests content
- After a viewer finishes watching an item, that item is automatically removed from the playout
- The
OnDemandCheckpoint(DateTimeOffset?) property tracks the last-acknowledged position for resuming on-demand playback
Fill Group Indices
TheFillGroupIndices collection (List<PlayoutScheduleItemFillGroupIndex>) tracks the current position within each schedule item’s filler group. This enables ErsatzTV to continue cycling through filler content correctly across playout rebuild boundaries, rather than restarting from the first filler item each time.
Alternate Schedules on Playouts
For Classic schedule playouts,ProgramScheduleAlternates allows override schedules to be evaluated before the primary schedule. Alternate schedules can target specific days of the week, date ranges, or other conditions — enabling seasonal or special-event programming without creating a separate playout for each variant.
Resetting a Playout
You can force a full playout rebuild via the API. Resetting discards all existingPlayoutItem records and rebuilds the timeline from scratch:
Gaps
When the playout builder cannot fill a span of time — because a collection is empty, a file is missing, or filler runs out — it records aPlayoutGap:
FallbackFiller (if configured) is the last line of defense against gaps. Monitor the build status and any recorded gaps after a rebuild to diagnose scheduling or library issues.