Skip to main content
Classic schedules provide traditional time-slot based scheduling, similar to conventional TV programming. Each schedule consists of a series of items that play in order, with support for both fixed and dynamic start times.

Creating a Classic Schedule

Classic schedules are managed through the web UI under Scheduling > Program Schedules.

Schedule Configuration

The ProgramSchedule model (ErsatzTV.Core/Domain/ProgramSchedule.cs:5) supports the following options:
Name
string
required
The name of your schedule
KeepMultiPartEpisodesTogether
boolean
default:false
When enabled, multi-part episodes will always play together even if shuffled
TreatCollectionsAsShows
boolean
default:false
When enabled, collection items are treated as episodes of a single show for EPG purposes
ShuffleScheduleItems
boolean
default:false
Shuffle the order of schedule items themselves (not the content within items)
RandomStartPoint
boolean
default:false
Start playback at a random point in the schedule
FixedStartTimeBehavior
enum
Controls how fixed-time items behave when they can’t start exactly on time
  • Strict (0) - Must start exactly on time
  • Flexible (1) - Can start late if previous content overruns

Schedule Items

Each schedule contains multiple ProgramScheduleItem objects. There are three types:

One Item

ProgramScheduleItemOne plays a single item from the collection.

Multiple Items

ProgramScheduleItemMultiple (ErsatzTV.Core/Domain/ProgramScheduleItemMultiple.cs:3) plays multiple items based on a mode:
Play a fixed number of items:
{
  "MultipleMode": 0,
  "Count": "5"
}

Duration Items

ProgramScheduleItemDuration (ErsatzTV.Core/Domain/ProgramScheduleItemDuration.cs:3) fills a specific duration with content:
PlayoutDuration
TimeSpan
required
The duration to fill with content
TailMode
enum
What to do when content doesn’t exactly fill the duration
  • None (0) - Stop scheduling, leave gap
  • Offline (1) - Show offline slate
  • Slate (2) - Show custom slate
  • Filler (3) - Use filler content
DiscardToFillAttempts
int
default:0
How many times to try finding content that fits before giving up

Schedule Item Properties

All schedule items (ErsatzTV.Core/Domain/ProgramScheduleItem.cs:7) share common properties:

Start Time Configuration

StartTime
TimeSpan?
Fixed start time (e.g., “14:30:00” for 2:30 PM). When null, the item starts dynamically after the previous item.
StartType
enum
Automatically determined:
  • Fixed (2) - When StartTime is set
  • Dynamic (1) - When StartTime is null
FixedStartTimeBehavior
enum?
Override the schedule-level fixed start time behavior for this item

Content Source

One of the following must be set:
CollectionId
int?
Standard collection reference
MediaItemId
int?
Single media item reference
MultiCollectionId
int?
Multi-collection reference
SmartCollectionId
int?
Smart collection reference
PlaylistId
int?
Playlist reference
SearchQuery
string
Ad-hoc search query

Playback Configuration

PlaybackOrder
PlaybackOrder
How to order content from the collection. See Overview for options.
CollectionType
enum
The type of collection being scheduled

Marathon Options

MarathonGroupBy
enum
How to group episodes in marathon mode
MarathonShuffleGroups
boolean
default:false
Shuffle the order of groups in marathon mode
MarathonShuffleItems
boolean
default:false
Shuffle items within groups in marathon mode
MarathonBatchSize
int?
How many items per group in marathon mode

Filler Content

Classic schedules support multiple types of filler:
PreRollFillerId
int?
Filler to play before the main content
MidRollFillerId
int?
Filler to play during the main content
PostRollFillerId
int?
Filler to play after the main content
TailFillerId
int?
Filler to use when content doesn’t fill the scheduled time
FallbackFillerId
int?
Filler to use when scheduled content is unavailable

Display Options

GuideMode
enum
How to display this item in the EPG guide
CustomTitle
string
Override the title shown in the EPG

Media Preferences

PreferredAudioLanguageCode
string
Preferred audio language (e.g., “eng”, “spa”)
PreferredAudioTitle
string
Preferred audio track by title
PreferredSubtitleLanguageCode
string
Preferred subtitle language
SubtitleMode
enum?
Subtitle display mode

Graphics and Watermarks

Watermarks
List<ChannelWatermark>
Watermarks to display during this item
GraphicsElements
List<GraphicsElement>
Graphics overlays to display during this item
FillWithGroupMode
enum
Controls fill group behavior

Example Schedule

1

Morning News Block

Fixed start at 06:00, play 3 news episodes chronologically
  • Start Time: 06:00:00
  • Collection: Morning News
  • Multiple Mode: Count = 3
  • Playback Order: Chronological
2

Cartoons Block

Fixed start at 08:00, fill 2 hours with cartoons
  • Start Time: 08:00:00
  • Collection: Saturday Cartoons
  • Duration: 2 hours
  • Playback Order: Shuffle
  • Tail Mode: Filler
3

Movie

Fixed start at 10:00, play one movie
  • Start Time: 10:00:00
  • Collection: Action Movies
  • Item Count: 1
  • Playback Order: Random
4

TV Series Marathon

Dynamic start after movie, play 5 episodes
  • Start Time: (none)
  • Collection: Sci-Fi Series
  • Multiple Mode: Count = 5
  • Playback Order: Chronological

Alternate Schedules

Classic schedules support alternates through ProgramScheduleAlternate (ErsatzTV.Core/Domain/ProgramScheduleAlternate.cs), which allows switching between different schedules based on date ranges or other criteria.
Schedule items are played in order by their Index property. Use the web UI to reorder items by dragging and dropping.

Context Tracking

Classic schedules use ClassicSchedulingContext (ErsatzTV.Core/Scheduling/ClassicSchedulingContext.cs:3) to track:
  • Current schedule and item being played
  • Enumerator state (position in collection)
  • Random seed for reproducible randomization
  • Index within the current collection
This context is saved as part of the playout anchor to resume correctly after restarts.

Build docs developers (and LLMs) love