### Example Playout Entrypoint Source: https://ersatztv.org/docs/scheduling/scripted/python-docker This is an example of how to call the entrypoint script for a playout configuration. It assumes a script named `one.py` exists in the scripts directory. ```bash /app/scripted-schedules/entrypoint.py one ``` -------------------------------- ### Install Community Applications Plugin Source: https://ersatztv.org/docs/installation/advanced/unraid Paste this URL into the Plugins / Install Plugin section of UnRAID to install the Community Applications plugin. ```bash https://raw.githubusercontent.com/Squidly271/community.applications/master/plugins/community.applications.plg ``` -------------------------------- ### Start Docker Compose Source: https://ersatztv.org/docs/installation/docker Command to launch the service defined in the Docker Compose file. ```bash docker compose up -d /path/to/compose/file ``` -------------------------------- ### Run ErsatzTV Container Source: https://ersatztv.org/docs/installation/docker Start the container with volume mappings for configuration and media, and set the timezone. ```bash docker run -d \ --name ersatztv \ -e TZ=America/Chicago \ -p 8409:8409 \ -v /path/to/config:/config \ -v /path/to/local/media:/path/to/local/media:ro \ --restart unless-stopped \ ghcr.io/ersatztv/ersatztv ``` -------------------------------- ### Example Folder Layout for Other Videos Source: https://ersatztv.org/docs/media/local/othervideos Demonstrates how folder hierarchy is used to automatically generate tags for media items. ```text └── Commercials ├── 1990 │   └── Cars │   └── 1990 Car Commercial 1.mkv └── 1992 └── Cars └── 1992 Car Commercial 1.mkv ``` -------------------------------- ### Define EPG Group for Program Guide Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'epg_group: true' to start a new program entry and 'epg_group: false' to end it. 'advance: true' creates a new EPG entry. 'filler_kind' content does not appear in the EPG. ```yaml playout: - epg_group: true # Start new program entry advance: true # Create new EPG entry (default) - count: 1 content: "BUMPERS" filler_kind: "preroll" # Won't appear in EPG - count: 1 content: "MAIN_SHOW" # Generates EPG metadata - count: 1 content: "BUMPERS" filler_kind: "postroll" # Won't appear in EPG - epg_group: false # End program entry ``` -------------------------------- ### Run ErsatzTV Executable on Windows Source: https://ersatztv.org/docs/installation/windows Execute the ErsatzTV application on Windows. This is the primary step after installation or update. ```bash ErsatzTV-Windows.exe ``` -------------------------------- ### Common Search Query Patterns Source: https://ersatztv.org/docs/scheduling/sequential/content Examples of search query strings for filtering episodes, movies, and tags. ```yaml # Find all episodes of a specific show query: "type:episode AND show_title"The Simpsons"" # Find movies from a specific decade query: "type:move AND release_date:[20000101 TO 20091231]" # Find content with specific tags query: "type:other_video AND tag:bumpers" # Complex searches with multiple criteria query: "type:episode AND (show_title:"Friends" OR show_title:"Seinfeld")" ``` -------------------------------- ### Example Song Folder Structure Source: https://ersatztv.org/docs/media/local/songs Visual representation of a nested folder structure used for song metadata extraction. ```text └── Rock └── Awesome Band ├── Awesome Album │   └── 01 Track 1.flac └── Better Album └── 05 Track 5.flac ``` -------------------------------- ### Sequence Example: Single Execution Source: https://ersatztv.org/docs/scheduling/sequential/playout Execute a predefined Sequence block once. This is useful for structuring repeatable content segments. ```yaml playout: # Execute the sequence a single time - sequence: "MORNING_BLOCK" ``` -------------------------------- ### Music Videos Folder Structure Example Source: https://ersatztv.org/docs/media/local/musicvideos Illustrates the required artist subfolder structure for music videos in ErsatzTV. Ensure artist names are used for subfolders, with albums and tracks organized within. ```text └── Artist ├── Album │     ├── Track One.mp4 │     └── Track Two.mp4 ├── Another Track │     └── Another Track.mp4 └── Track Three.mp4 ``` -------------------------------- ### Pad Until Example Source: https://ersatztv.org/docs/scheduling/sequential/playout Use Pad Until to schedule content until a specific time, useful for filling gaps before a scheduled event. The 'trim' parameter ensures content fits exactly. ```yaml playout: - pad_until: "9:00 AM" tomorrow: false content: "MORNING_FILLER" trim: true fallback: "BACKUP_CONTENT" ``` -------------------------------- ### Sequence Example: Repeat Execution Source: https://ersatztv.org/docs/scheduling/sequential/playout Repeat a predefined Sequence block multiple times. The 'repeat' parameter specifies the number of executions. ```yaml playout: # Repeat a sequence multiple times - sequence: "SHOW_BLOCK" repeat: 4 # Executes SHOW_BLOCK 4 times in a row ``` -------------------------------- ### Movie Folder Structure Example Source: https://ersatztv.org/docs/media/local/movies Illustrates the required subfolder structure for movies in ErsatzTV. Each movie must reside in its own subfolder, which can contain the movie file and metadata. ```text ├── Movie (1999) | └── Movie (1999).mkv └── Movie └── Movie.mkv ``` -------------------------------- ### Remote Stream Folder Structure Example Source: https://ersatztv.org/docs/media/local/remotestreams Visual representation of a nested directory structure used for remote stream metadata tagging. ```text └── One └── Two ├── Three │   └── Stream One.yml └── Four └── Stream Two.yml ``` -------------------------------- ### Define Stream Selector Items Source: https://ersatztv.org/docs/advanced/custom-stream-selector Example of defining a list of items with audio and subtitle criteria in a YAML stream selector file. ```yaml items: # english audio (wildcard matches `en` and `eng`), and no subtitles - audio_language: ["en*"] disable_subtitles: true # any audio language, and no subtitles - audio_language: ["*"] disable_subtitles: true ``` -------------------------------- ### Motion Element Definition Source: https://ersatztv.org/docs/advanced/graphics-engine Defines a motion element for overlaying video. Configure video path, location, margins, scaling, start time, and end behavior. The start time can be dynamically set using Scriban. ```yaml video_path: /home/user/Videos/motion1.webm location: TopLeft horizontal_margin_percent: 5 vertical_margin_percent: 5 scale: true scale_width_percent: 25 start_seconds: {{ MediaItem_Duration.TotalSeconds - 5 }} end_behavior: loop z_index: 1 ``` -------------------------------- ### Configure Remote Live Content Source: https://ersatztv.org/docs/media/local/remotestreams/sample Defines a remote live stream using yt-dlp. Requires yt-dlp to be installed in the environment as it is not included in the default Docker image. ```yaml script: "yt-dlp whatever-live --hls-use-mpegts -o -" is_live: true duration: 02:00:00 ``` -------------------------------- ### Configure Marathon Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Define a marathon content source using either specific show GUIDs or search queries, with options for grouping and playback order. ```yaml content: - marathon: key: "COMEDY_MARATHON" # Option 1: Use specific show IDs guids: - source: "imdb" value: "tt0108778" # Friends - source: "imdb" value: "tt0098904" # Seinfeld # Option 2: Use search queries searches: - "type:episode AND show_title:\"Friends\"" - "type:episode AND show_title:\"Seinfeld\"" - "type:episode AND show_title:\"The Office\"" group_by: "show" # or "season" item_order: "shuffle" # or "chronological" play_all_items: false # Cycle through shows shuffle_groups: true # Randomize show order ``` -------------------------------- ### Movie Fallback Metadata Example Source: https://ersatztv.org/docs/media/local/movies Shows how movie title and year are parsed from the filename when no NFO file is present. This is the fallback mechanism for metadata extraction. ```text └── Movie (1999) └── Movie (1999).mkv ``` -------------------------------- ### Sample Stream Selector: Disable RiffTrax Source: https://ersatztv.org/docs/advanced/custom-stream-selector A complete example configuration for disabling RiffTrax and managing audio/subtitle priorities. ```yaml items: # english audio without "riff" in the title - audio_language: ["en*"] audio_title_blocklist: ["riff"] disable_subtitles: true # english audio with no subtitles - audio_language: ["en*"] disable_subtitles: true # any other language audio with english subtitles - audio_language: ["*"] subtitle_language: ["en*"] # any language audio with no subtitles - audio_language: ["*"] disable_subtitles: true ``` -------------------------------- ### Configure Remote VOD Content Source: https://ersatztv.org/docs/media/local/remotestreams/sample Defines a remote VOD stream using yt-dlp. Requires yt-dlp to be installed in the environment as it is not included in the default Docker image. ```yaml script: "yt-dlp whatever --hls-use-mpegts -o -" is_live: false ``` -------------------------------- ### All Instruction Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays every item from a content source before continuing to the next instruction. ```APIDOC ## All Instruction ### Description Plays every item from a content source before continuing. Useful for special events or movie marathons. ### Parameters - **content** (string) - Required - The key for the content that should play. - **custom_title** (string) - Optional - Overrides the title used in the EPG. - **filler_kind** (string) - Optional - Flags content as filler (none, preroll, postroll, midroll). Default: none. ### Request Example ```yaml playout: - all: content: "SPECIAL_EVENT" ``` ``` -------------------------------- ### Create Configuration Directory Source: https://ersatztv.org/docs/installation/docker Prepare a local directory to persist ErsatzTV configuration data. ```bash mkdir /path/to/config ``` -------------------------------- ### Pad To Next Instruction Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays content until a specific minutes interval. ```APIDOC ## Pad To Next Instruction ### Description Plays content until a specific minutes interval (e.g., top of the hour or half-hour). ### Parameters - **pad_to_next** (integer) - Required - The minute interval to pad until. - **content** (string) - Required - The key for the content that should play. - **trim** (boolean) - Optional - If true, trims content to fit. - **discard_attempts** (integer) - Optional - Number of items to skip if they don't fit. - **fallback** (string) - Optional - Key for content used to fill remaining time. - **filler_kind** (string) - Optional - Flags content as filler. ### Request Example ```yaml playout: - pad_to_next: 30 content: "FILLER" trim: true discard_attempts: 2 fallback: "BACKUP_FILLER" filler_kind: "postroll" ``` ``` -------------------------------- ### Docker Compose Configuration Source: https://ersatztv.org/docs/installation/docker Sample configuration for deploying ErsatzTV with Docker Compose, including optional NVIDIA GPU passthrough settings. ```yaml services: ersatztv: image: ghcr.io/ersatztv/ersatztv container_name: ersatztv environment: - TZ=America/Chicago # Edit for your timezone, list can be found https://en.wikipedia.org/wiki/List_of_tz_database_time_zones # UNCOMMENT THESE LINES TO ENABLE NVIDIA GPU PASSTHROUGH #- NVIDIA_VISIBLE_DEVICES:all #- NVIDIA_DRIVER_CAPABILITIES:all #deploy: # resources: # reservations: # devices: # - driver: nvidia # count: 1 # capabilities: [gpu] ports: # This maps port from host:container - "8409:8409" volumes: # Required: Configuration data (must be writable) - /path/to/config:/config # Required: media directories - Where your media files are stored. Use :ro at the end of the path to limit container to Read-Only - /path/to/local/media:/path/to/local/media:ro # tmpfs is optional but recommended: Limits writing to SSD/disk by using RAM for transcode files. Comment out to disable tmpfs: - /transcode restart: unless-stopped ``` -------------------------------- ### Configure Playout Entrypoint Source: https://ersatztv.org/docs/scheduling/scripted/python-docker Execute your custom playout script using this entrypoint command within the Docker container. Replace `[script name]` with the name of your Python script (without the .py extension) located in `/app/scripted-schedules/scripts`. ```bash /app/scripted-schedules/entrypoint.py [script name] ``` -------------------------------- ### Repeat Playout Sequence Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'repeat: true' to restart the playout from the first instruction. This is useful for looping content. ```yaml playout: - count: 1 content: "SHOWS" - repeat: true # Go back to beginning of playout ``` -------------------------------- ### Count Instruction Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays a specific number of items from a content source. ```APIDOC ## Count Instruction ### Description Plays a specific number of items from a content source. ### Parameters - **count** (integer) - Required - Number of items to play. - **content** (string) - Required - The key for the content that should play. - **custom_title** (string) - Optional - Overrides the title used in the EPG. - **filler_kind** (string) - Optional - Flags content as filler (none, preroll, postroll, midroll). Default: none. ### Request Example ```yaml playout: - count: 3 content: "MORNING_CARTOONS" custom_title: "Saturday Morning Block" ``` ``` -------------------------------- ### Add Temporary File System Mount Source: https://ersatztv.org/docs/installation/docker Optional flag to reduce SSD wear by using RAM for transcoding files. ```bash --mount type=tmpfs,destination=/transcode ``` -------------------------------- ### Prefer RiffTrax Audio Configuration Source: https://ersatztv.org/docs/advanced/custom-stream-selector Configure ERSatzTV to prioritize English audio with 'riff' in the title and disable subtitles. This setup is useful for specific content where riff tracks are preferred. ```yaml items: # english audio with "riff" in the title - audio_language: ["en*"] audio_title_allowlist: ["riff"] disable_subtitles: true # english audio with no subtitles - audio_language: ["en*"] disable_subtitles: true # any other language audio with english subtitles - audio_language: ["*"] subtitle_language: ["en*"] # any language audio with no subtitles - audio_language: ["*"] disable_subtitles: true ``` -------------------------------- ### Schedule all content from a source Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays every item from a specified content source. Useful for movie marathons or special events. ```yaml playout: - all: content: "SPECIAL_EVENT" ``` -------------------------------- ### Configure Local Camera Stream Source: https://ersatztv.org/docs/media/local/remotestreams/sample Defines a local RTSP camera stream. Ensure the URL includes valid credentials and the correct stream path. ```yaml url: "rtsp://user:pass@192.168.1.100/h264_Preview_01_sub" is_live: true duration: 01:00:00 ``` -------------------------------- ### Define a Sequence with Bumpers Source: https://ersatztv.org/docs/scheduling/sequential/sequence This sequence defines a pattern for playing content with preroll and postroll bumpers. Use this to ensure consistent branding or ad placement around main content. ```yaml sequence: - key: "SHOW_WITH_BUMPERS" items: - count: 1 content: "BUMPERS" filler_kind: "preroll" - count: 1 content: "MAIN_SHOW" - count: 1 content: "BUMPERS" filler_kind: "postroll" ``` -------------------------------- ### Schedule content to pad to next interval Source: https://ersatztv.org/docs/scheduling/sequential/playout Fills time until a specific minute interval, such as the next half-hour or hour mark. ```yaml playout: - pad_to_next: 30 # minutes content: "FILLER" trim: true discard_attempts: 2 fallback: "BACKUP_FILLER" filler_kind: "postroll" ``` -------------------------------- ### Define a Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference an existing manual collection by name. ```yaml content: - collection: "Saturday Morning Cartoons" key: "CARTOONS" order: "shuffle" ``` -------------------------------- ### Schedule content by duration Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays content for a specific duration, with options to trim items or use fallback content to fill remaining time. ```yaml playout: - duration: "30 minutes" content: "SHORT_SHOWS" trim: true discard_attempts: 3 fallback: "FILLER_CONTENT" ``` -------------------------------- ### Marathon Configuration Schema Source: https://ersatztv.org/docs/scheduling/sequential/content Defines the structure and parameters for creating a Marathon content source. ```APIDOC ## Marathon Configuration ### Description Marathon content sources create dynamic playlists that intelligently mix content from multiple shows or searches. ### Parameters - **key** (string) - Required - Unique name that can be used to reference this content throughout the sequential schedule definition. - **guids** (array) - Optional - List of external content identifiers (source and value pairs). - **searches** (array) - Optional - List of search expressions. - **group_by** (string) - Required - Tells the sequential scheduler how to group the combined content. Valid values: show, season, artist, album. - **item_order** (string) - Required - Playback order within each group. Valid values: chronological, shuffle. - **play_all_items** (boolean) - Optional - When true, will play every item from a group before moving to the next group. When false, will play one item from a group before moving to the next group. - **shuffle_groups** (boolean) - Optional - When true, will randomize the order of groups. When false, will cycle through groups in a fixed order. ### Request Example content: - marathon: key: "COMEDY_MARATHON" guids: - source: "imdb" value: "tt0108778" - source: "imdb" value: "tt0098904" searches: - "type:episode AND show_title:\"Friends\"" group_by: "show" item_order: "shuffle" play_all_items: false shuffle_groups: true ``` -------------------------------- ### Pull Docker Image Source: https://ersatztv.org/docs/installation/docker Download the latest ErsatzTV container image from the GitHub Container Registry. ```bash docker pull ghcr.io/ersatztv/ersatztv ``` -------------------------------- ### Smart Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference existing Smart Collections to reuse already organized content. ```APIDOC ## Smart Collection Content Source ### Description Reference existing Smart Collections to reuse already organized content. ### Parameters #### Request Body - **smart_collection** (string) - Required - The name of the existing Smart Collection. - **key** (string) - Required - Unique name for referencing this content source. - **order** (string) - Required - Playback order; supported values are `chronological` and `shuffle`. ### Request Example ```yaml content: - smart_collection: "Recent Movies" key: "NEW_MOVIES" order: "chronological" ``` ``` -------------------------------- ### Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference existing Manual Collections to reuse already organized content. ```APIDOC ## Collection Content Source ### Description Reference existing Manual Collections to reuse already organized content. ### Parameters #### Request Body - **collection** (string) - Required - The name of the existing Manual Collection. - **key** (string) - Required - Unique name for referencing this content source. - **order** (string) - Required - Playback order; supported values are `chronological` and `shuffle`. ### Request Example ```yaml content: - collection: "Saturday Morning Cartoons" key: "CARTOONS" order: "shuffle" ``` ``` -------------------------------- ### Duration Instruction Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays content for a specific amount of time, with options to trim or use fallback content. ```APIDOC ## Duration Instruction ### Description Plays content for a specific duration, optionally trimming items or using fallback content to fill time. ### Parameters - **duration** (string) - Required - The amount of time to play. - **content** (string) - Required - The key for the content that should play. - **trim** (boolean) - Optional - If true, trims content to fit duration. Default: false. - **discard_attempts** (integer) - Optional - Number of items to skip if they don't fit. - **stop_before_end** (boolean) - Optional - If false, allows content to run over duration. Default: true. - **offline_tail** (boolean) - Optional - If true, leaves remaining time unscheduled. Default: false. - **fallback** (string) - Optional - Key for content used to fill remaining time. - **custom_title** (string) - Optional - Overrides the title used in the EPG. - **filler_kind** (string) - Optional - Flags content as filler (none, preroll, postroll, midroll). Default: none. ### Request Example ```yaml playout: - duration: "30 minutes" content: "SHORT_SHOWS" trim: true discard_attempts: 3 fallback: "FILLER_CONTENT" ``` ``` -------------------------------- ### Define a Smart Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference an existing smart collection by name. ```yaml content: - smart_collection: "Recent Movies" key: "NEW_MOVIES" order: "chronological" ``` -------------------------------- ### Playlist Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference existing Playlists to reuse already organized content. ```APIDOC ## Playlist Content Source ### Description Reference existing Playlists to reuse already organized content. ### Parameters #### Request Body - **playlist** (string) - Required - The name of the existing Playlist. - **playlist_group** (string) - Required - The name of the existing Playlist Group that contains the named Playlist. - **key** (string) - Required - Unique name for referencing this content source. ### Request Example ```yaml content: - playlist: "My Favorites" playlist_group: "Personal Lists" key: "FAVORITES" ``` ``` -------------------------------- ### Schedule a specific count of items Source: https://ersatztv.org/docs/scheduling/sequential/playout Plays a defined number of items from a content source. ```yaml playout: - count: 3 content: "MORNING_CARTOONS" custom_title: "Saturday Morning Block" ``` -------------------------------- ### Turn On Graphics Element Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'graphics_on' to activate a graphics element. The element remains visible until explicitly turned off. ```yaml playout: - graphics_on: "image/watermark.yml" - count: 1 content: "MAIN_SHOW" ``` -------------------------------- ### Show Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Target specific shows using external identifier metadata for precise content selection. ```APIDOC ## Show Content Source ### Description Target specific shows using external identifier metadata for precise content selection. ### Parameters #### Request Body - **key** (string) - Required - Unique name for referencing this content source. - **guids** (array) - Required - List of show identifiers, each with a `source` and `value`. - **source** (string) - Required - The source of the identifier (e.g., "tvdb", "imdb"). - **value** (string) - Required - The identifier value. - **order** (string) - Required - Playback order; supported values are `chronological` and `shuffle`. ### Request Example ```yaml content: - show: key: "FRIENDS_EPISODES" guids: - source: "tvdb" value: "79168" - source: "imdb" value: "tt0108778" order: "chronological" ``` ### Show Identifiers Show identifiers can be any GUID present in your metadata. Verify GUID metadata using Search in the format `source:value` (e.g., `tvdb:79168`). ``` -------------------------------- ### Define a Search Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Use the search content source to dynamically select media based on query criteria. ```yaml content: - search: key: "SATURDAY_CARTOONS" query: "type:episode AND show_title:"Looney Tunes"" order: shuffle ``` -------------------------------- ### Define a Show Block Sequence Source: https://ersatztv.org/docs/scheduling/sequential/sequence This sequence pattern structures a block of shows, including intros and outros. It's useful for organizing programming blocks with consistent introductions and conclusions. ```yaml sequence: # Show block with intro/outro - key: "MORNING_SHOW_BLOCK" items: - count: 1 content: "SHOW_INTROS" - count: 3 content: "MORNING_SHOWS" - count: 1 content: "SHOW_OUTROS" ``` -------------------------------- ### Configure Audio Title Block List Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter out audio streams if the title contains any string from the blocklist. ```yaml audio_title_blocklist: ["riff"] ``` -------------------------------- ### Multi Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference existing Multi Collections to reuse already organized content. ```APIDOC ## Multi Collection Content Source ### Description Reference existing Multi Collections to reuse already organized content. ### Parameters #### Request Body - **multi_collection** (string) - Required - The name of the existing Multi Collection. - **key** (string) - Required - Unique name for referencing this content source. - **order** (string) - Required - Playback order; supported values are `chronological` and `shuffle`. ### Request Example ```yaml content: - multi_collection: "All Comedy Shows" key: "COMEDY" order: "shuffle" ``` ``` -------------------------------- ### Configure Audio Title Allow List Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter audio streams to only include those where the title contains a string from the allowlist. ```yaml audio_title_allowlist: ["riff"] ``` -------------------------------- ### Dual Audio Anime Configuration Source: https://ersatztv.org/docs/advanced/custom-stream-selector Set up ERSatzTV for dual audio anime, prioritizing English audio with subtitles disabled, falling back to Japanese audio with English subtitles, or any other language with English subtitles. ```yaml items: # 1. Prefer English audio, disable subtitles - audio_language: ["en*"] disable_subtitles: true # 2. Fallback to Japanese audio, enable English subtitles - audio_language: ["ja*"] subtitle_language: ["en*"] # 3. If audio is anything else, enable English subtitles - audio_language: ["*"] subtitle_language: ["en*"] # 4. Catch all: any audio when English subtitles are unavailable - audio_language: ["*"] disable_subtitles: true ``` -------------------------------- ### Display Music Video Artist Image Source: https://ersatztv.org/docs/advanced/graphics-engine/sample Configure an image element to display 'artist.png' from the current music video's folder for a set duration. Scales the image to fit within specified dimensions. ```yaml opacity_expression: "LinearFadePoints(content_seconds, 0, 1, 16, 17)" location: "BottomLeft" horizontal_margin_percent: 5 vertical_margin_percent: 10 z_index: 1 scale: true scale_width_percent: 8 image: {{ MediaItem_Path | get_directory_name }}/artist.png ``` -------------------------------- ### Configure Audio Language Filter Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter audio streams by language using a list of strings and wildcards. ```yaml audio_language: ["en", "eng"] ``` -------------------------------- ### Define a Multi Collection Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference an existing multi-collection by name. ```yaml content: - multi_collection: "All Comedy Shows" key: "COMEDY" order: "shuffle" ``` -------------------------------- ### Define a Playlist Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Reference an existing playlist within a specific playlist group. ```yaml content: - playlist: "My Favorites" playlist_group: "Personal Lists" key: "FAVORITES" ``` -------------------------------- ### Wait Until Specific Time Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'wait_until' to pause playout until a specified time. 'tomorrow: false' indicates the time is for the current day. 'rewind_on_reset: true' ensures the wait is re-evaluated on reset. ```yaml reset: - wait_until: "6:00 AM" tomorrow: false rewind_on_reset: true ``` ```yaml playout: - wait_until: "18:30" tomorrow: false - count: 1 content: "NEWS" ``` -------------------------------- ### Disable Subtitles Source: https://ersatztv.org/docs/advanced/custom-stream-selector Set to true to prevent any subtitle from being selected. ```yaml disable_subtitles: true ``` -------------------------------- ### Define a Show Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Target specific shows using external metadata identifiers like TVDB or IMDB. ```yaml content: - show: key: "FRIENDS_EPISODES" guids: - source: "tvdb" value: "79168" - source: "imdb" value: "tt0108778" order: "chronological" ``` -------------------------------- ### Configure Subtitle Language Filter Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter subtitle streams by language using a list of strings and wildcards. ```yaml subtitle_language: ["en", "eng"] ``` -------------------------------- ### Search Content Source Source: https://ersatztv.org/docs/scheduling/sequential/content Dynamically find content using ErsatzTV's search engine based on specified criteria. ```APIDOC ## Search Content Source ### Description Dynamically find content using ErsatzTV's search engine based on specified criteria (query). ### Parameters #### Request Body - **key** (string) - Required - Unique name for referencing this content source. - **query** (string) - Required - Search expression to find content. - **order** (string) - Required - Playback order; supported values are `chronological` and `shuffle`. ### Request Example ```yaml content: - search: key: "SATURDAY_CARTOONS" query: "type:episode AND show_title:\"Looney Tunes\"" order: shuffle ``` ### Common Search Patterns - Find all episodes of a specific show: `query: "type:episode AND show_title\"The Simpsons\""` - Find movies from a specific decade: `query: "type:movie AND release_date:[20000101 TO 20091231]"` - Find content with specific tags: `query: "type:other_video AND tag:bumpers"` - Complex searches with multiple criteria: `query: "type:episode AND (show_title:\"Friends\" OR show_title:\"Seinfeld\")"` **Note**: Test search queries in the search interface before using them in a sequential schedule. ``` -------------------------------- ### Image Element Definition Source: https://ersatztv.org/docs/advanced/graphics-engine Defines an image element for overlaying graphics. Specify opacity, location, margins, scaling, and the image path. Ensure the image file exists at the specified path. ```yaml opacity_percent: 100 location: "BottomLeft" horizontal_margin_percent: 5 vertical_margin_percent: 5 z_index: 1 scale: true scale_width_percent: 15 image: "/home/user/Pictures/watermark.gif" ``` -------------------------------- ### Configure Subtitle Title Block List Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter out subtitle streams if the title contains any string from the blocklist. ```yaml subtitle_title_blocklist: ["riff"] ``` -------------------------------- ### Display Music Video Artist and Title Text Source: https://ersatztv.org/docs/advanced/graphics-engine/sample Configure a text element to display the music video artist and title for a set duration. Uses the OPTIKabel-Heavy font and scales text to fit. ```yaml opacity_expression: "LinearFadePoints(content_seconds, 0, 1, 16, 17)" location: "BottomLeft" horizontal_margin_percent: 15 vertical_margin_percent: 10 z_index: 1 styles: - name: "base" font_family: "OPTIKabel-Heavy" font_size: 32 text_color: "#FFFFFF" font_italic: false font_weight: 700 base_style: "base" epg_entries: 0 width_percent: 80 text_fit: scale text: | {{ MediaItem_Artist }} "{{ MediaItem_Title }}" ``` -------------------------------- ### Skip to Specific Item Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'skip_to_item' to jump to a particular season and episode within a content source during a reset. ```yaml reset: - skip_to_item: content: "SEASONAL_SHOW" season: 2 episode: 10 ``` -------------------------------- ### Skip Items in Content Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'skip_items' to bypass a specified number of items within a content source during a reset. ```yaml reset: # skip first 5 items - skip_items: 5 content: "TV_SHOWS" ``` -------------------------------- ### Override Watermarks Source: https://ersatztv.org/docs/scheduling/sequential/playout Use 'watermark: true' with a 'name' to activate a specific watermark, or 'watermark: false' to deactivate it. Setting 'watermark: false' without a name resets all watermarks to default. ```yaml playout: # turn on COOL_WATERMARK - watermark: true name: "COOL_WATERMARK" # turn on ANOTHER_WATERMARK - watermark: true name: "ANOTHER_WATERMARK" - count: 1 content: "COOL_CONTENT" # turn off ANOTHER_WATERMARK - watermark: false name: "ANOTHER_WATERMARK" # turn off all watermarks (reset to default) - watermark: false ``` -------------------------------- ### Stop ErsatzTV Process on Linux Source: https://ersatztv.org/docs/installation/linux Use this command to cleanly terminate the running ErsatzTV process before performing an update. ```bash kill -SIGINT `pgrep ErsatzTV` ``` -------------------------------- ### Configure Subtitle Title Allow List Source: https://ersatztv.org/docs/advanced/custom-stream-selector Filter subtitle streams to only include those where the title contains a string from the allowlist. ```yaml subtitle_title_allowlist: ["riff"] ``` -------------------------------- ### Scripted Schedule Python Boilerplate Source: https://ersatztv.org/docs/scheduling/scripted/python-docker This is the required structure for a Python scripted schedule. It must define `define_content`, `reset_playout`, and `build_playout` methods. Ensure all necessary imports are included. ```python from datetime import datetime, timedelta from uuid import UUID from etv_client import ScriptedScheduleApi from etv_client.models import * def define_content(api_instance: ScriptedScheduleApi, context: PlayoutContext, build_id: UUID) -> None: pass def reset_playout(api_instance: ScriptedScheduleApi, context: PlayoutContext, build_id: UUID) -> PlayoutContext: return context def build_playout(api_instance: ScriptedScheduleApi, context: PlayoutContext, build_id: UUID) -> None: while not context.is_done: # TODO: make api calls here to build the playout pass ``` -------------------------------- ### Define a Commercial Break Sequence Source: https://ersatztv.org/docs/scheduling/sequential/sequence This sequence pattern is designed for commercial breaks, specifying a duration and content. It includes a trim option, likely for managing ad lengths. ```yaml sequence: # Commercial break pattern - key: "COMMERCIAL_BREAK" items: - duration: "2 minutes" content: "COMMERCIALS" trim: true ```