Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ErsatzTV/legacy/llms.txt

Use this file to discover all available pages before exploring further.

ErsatzTV Legacy ships a suite of built-in diagnostic tools accessible from the Settings → Troubleshooting section of the web UI. Before filing a bug report or asking for help, work through the relevant tool for your issue — most problems can be identified quickly by combining the in-UI tools with the real-time log viewer.

Built-in Troubleshooting Tools

Navigate to Settings → Troubleshooting to access the following tools. They are organised into tabs — Tools for interactive diagnostics and General for a JSON snapshot of your system state.

Playback Troubleshooting

Located at /system/troubleshooting/playback. Streams a test transcode of any media item through a selected FFmpeg profile and stream selector, then downloads a ZIP archive of the FFmpeg report and session logs. Use this to isolate codec errors, hardware acceleration failures, and subtitle rendering problems without affecting live channel playback.

Block Playout Troubleshooting

Located at /system/troubleshooting/block-playout. Displays the schedule blocks and items that have been placed in a block-based playout, letting you verify that the correct content is being scheduled into the correct time slots.

Block Playout History

Located at /system/troubleshooting/block-playout/history. Shows a paginated, time-stamped table of playout history entries for block schedules. Each row includes the start time, finish time, history key, and detailed playout context. Use this to investigate why a specific item played — or did not play — at a given time.

Sequential Schedule Validation

Located at /system/troubleshooting/sequential-schedule. Validates a YAML sequential schedule file against either the full or import schema before applying it. Enter the path to the YAML file inside the container and select the schema type to get validation errors and warnings.

General System Information Tab

The General tab on the Troubleshooting page renders a JSON snapshot of your ErsatzTV installation. It includes:
  • Version — the running ErsatzTV build version
  • Environment — key environment variables (alphabetically sorted)
  • CPUs — the number of logical processors available to the container
  • VideoControllers — detected GPU adapters
  • Health — health check results for FFmpeg compatibility, schedule configuration, and other subsystems
  • FFmpegSettings — the configured FFmpeg binary path, default profile, and related settings
  • Channels — all configured channels with their numbers and names
  • FFmpegProfiles — all configured encoding profiles
Copy this JSON and attach it to any support request or GitHub issue. On macOS hosts, a VideoToolbox tab is shown instead of NVIDIA/VAAPI. On Linux hosts, NVIDIA, QSV, and VAAPI tabs show the raw capability output from the respective hardware detection queries.

Logs

Real-time application logs are available in the web UI at Settings → Logs (/system/logs). The log viewer is a paginated, searchable table showing timestamp, log level, and message. You can sort by timestamp or level, filter by free-text search, and configure how many rows are shown per page — the page size is saved between sessions. Log files are also written to disk in the logs/ subfolder of the config directory (e.g. /config/logs/ersatztv.log), rotating daily.
ErsatzTV uses independent log level controls per subsystem. The default minimum level is Information for all subsystems. Log categories include:
  • ScanningErsatzTV.Services.ScannerService, ErsatzTV.Services.SearchIndexService, ErsatzTV.Scanner
  • SchedulingErsatzTV.Core.Scheduling
  • StreamingErsatzTV.Application.Streaming, ErsatzTV.FFmpeg, ErsatzTV.Core.FFmpeg
  • HTTP — request/response logging via Serilog.AspNetCore.RequestLoggingMiddleware
You can override minimum levels per category in appsettings.json using the Serilog.MinimumLevel.Override section, or by adding an appsettings.Development.json file to the config folder if ASPNETCORE_ENVIRONMENT=Development.

Sample appsettings.json Log Configuration

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information",
        "Microsoft": "Warning",
        "System.Net.Http.HttpClient": "Warning",
        "MudBlazor": "Information"
      }
    },
    "Enrich": [
      "FromLogContext",
      "WithMachineName",
      "WithThreadId"
    ]
  }
}

Transcoding Speed Warnings

When ErsatzTV detects that FFmpeg is encoding slower than real-time, it logs a warning that can alert you to hardware transcoding misconfiguration or underpowered hardware before viewers notice problems. The log message includes the media item ID, channel number, and the measured transcoding speed (as a multiplier of real-time). For example:
[WRN] Transcoding speed 0.8x for media item 1234 on channel 2 may be insufficient for smooth playback
A speed below 1.0x means ErsatzTV cannot produce segments fast enough for continuous playback. If you see this warning:
  1. Check whether hardware acceleration is active (see the General tab in Troubleshooting).
  2. Verify the correct Docker Compose overlay is being used for your GPU type.
  3. Lower the output resolution or bitrate in the FFmpeg profile.
  4. On NVIDIA: confirm that 10-bit H.264 content is not being hardware-decoded (ErsatzTV forces software decode for it since NVIDIA hardware decode is unsupported by FFmpeg for that combination).

Troubleshooting API Endpoints

The troubleshooting controller exposes HTTP endpoints that the UI calls internally and that you can invoke directly for automation or scripting:
MethodPathDescription
GET / HEAD/api/troubleshoot/playback.m3u8Start a troubleshooting playback session for a specific media item, channel, and FFmpeg profile. Returns an HLS playlist redirect once segments are ready. Query parameters: mediaItem (int), channel (int), ffmpegProfile (int), streamingMode, watermark[], graphicsElement[], streamSelector, subtitleId, seekSeconds, start.
GET / HEAD/api/troubleshoot/playback/archiveDownload a ZIP archive of the most recent troubleshooting session’s FFmpeg logs and diagnostic output.
GET / HEAD/api/troubleshoot/playback/sample/{mediaItemId}Download a ZIP archive containing a sample transcode output for the given media item ID. Useful for sharing reproduction cases.

Common Issues

Work through this checklist in order:
  1. Channel enabled — open the channel editor and confirm the channel is not disabled.
  2. FFmpeg profile assigned — every channel requires an FFmpeg profile. Go to Channels → (channel) → Edit and confirm a profile is selected.
  3. Playout exists — a channel with no playout has nothing to stream. Navigate to the channel’s Playouts tab and confirm at least one playout is present and has been built.
  4. Playout has items — click into the playout and check that items are scheduled. An empty playout (no items in the timeline) will result in filler or a blank stream.
  5. Correct IPTV URL — confirm your client is using the M3U playlist URL from Settings → IPTV (/iptv/channels.m3u).
  6. Check logs — filter the log viewer for the channel number or IptvController to see streaming-level messages.
Hardware transcoding errors are almost always a container configuration issue:
  • NVIDIA: ensure you launched the container with the NVIDIA Compose overlay (docker-compose.nvidia.yml) and that the NVIDIA Container Toolkit is installed on the host. In the Troubleshooting UI, open the NVIDIA tab — if the capability output is empty or shows errors, the GPU is not visible to the container.
  • VAAPI: ensure the VAAPI Compose overlay (docker-compose.vaapi.yml) is active and that /dev/dri/renderD128 is the correct render node for your GPU. Check the VAAPI tab in the Troubleshooting UI. If you have a radeonsi or i965 driver and see green padding artefacts, set Pad Mode to Software in the FFmpeg profile.
  • QSV: on Linux, QSV uses the VAAPI device. Ensure the same device passthrough applies. Check the QSV tab.
  • All GPU types: use the Playback Troubleshooting tool to run a test transcode and download the FFmpeg report — it contains the exact command line and full FFmpeg stderr output.
The XMLTV guide (/iptv/xmltv.xml) is only populated for channels that have at least one playout with scheduled items:
  1. Confirm the channel’s Show In EPG setting is enabled in the channel editor.
  2. Confirm the playout is built — open the playout and check that items exist in the timeline for the relevant time window.
  3. XMLTV is regenerated on a schedule and after playout builds. If you just built a playout, wait a moment and then refresh the EPG URL in your client.
  4. If you run multiple ErsatzTV instances, set ETV_INSTANCE_ID to unique values on each instance so that channel identifiers in the XMLTV output don’t overlap.
Scanning failures are most commonly caused by path mismatches between the host filesystem and the Docker volume mounts:
  1. Volume mount missing — ensure the media directory is listed as a volume in your Compose file (e.g. - /media/movies:/media/movies:ro). The container path must exactly match the path configured in ErsatzTV’s library settings.
  2. Permissions — the container process must be able to read the mounted files. If your media is on a NAS share with restricted permissions, you may need to set PUID/PGID (not natively supported — use a wrapper or adjust the share permissions).
  3. Path case sensitivity — Linux container filesystems are case-sensitive. A library path of /media/Movies will not match files under /media/movies.
  4. Check scan logs — set the scanning log category to Debug temporarily and re-trigger a scan. Look for ScannerService and ErsatzTV.Scanner entries showing which paths are being enumerated and where failures occur.
When a channel plays black video or generic filler unexpectedly:
  1. Schedule gaps — open the playout’s timeline view and look for unscheduled gaps. Classic schedules with no filler configured will play black video during any gaps.
  2. Empty collection — if a schedule item references a collection or smart collection that is empty (e.g. all items were deleted or the search yields no results), that slot will be skipped or filled.
  3. Health checks — the General tab in Troubleshooting includes a Health section. Look for warnings about empty schedules or incompatible FFmpeg configurations.
  4. Slug seconds — if the channel has a Slug Seconds value configured, a short burst of black video and silence is deliberately inserted between every playout item. This is by design.
ErsatzTV Legacy enforces a single running instance using a named system mutex. If you see:
Another instance of ErsatztTV is already running.
This means either:
  • A previous ErsatzTV process is still running (check with docker ps or your process manager).
  • Two containers are sharing the same /config volume. Each ErsatzTV instance must have its own dedicated config volume.
To run two separate ErsatzTV instances legitimately (e.g. separate channel lineups for different rooms), use two Compose stacks with distinct named volumes, distinct port mappings, and distinct ETV_INSTANCE_ID values.
  • AC3 / surround audio desync — if you experience audio/video desync on content with AC3 audio when targeting stereo output and the input audio layout changes mid-stream, check the FFmpeg profile’s audio normalization settings.
  • Subtitle not appearing — ensure Extract Embedded Subtitles is enabled in FFmpeg settings if you want text subtitles burned in or converted. Subtitles are only extracted once; re-triggering a deep library scan is needed if the flag was off when items were first scanned.
  • Custom stream selectors and subtitles — if your channel uses a custom stream selector, embedded text subtitle extraction requires the extraction setting to be enabled in Settings.

Build docs developers (and LLMs) love