timothy edf8be4b5e
PR Gates / Docs update reminder (pull_request) Successful in 18s
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 18s
review-verdict/h10 Awaiting review verdict for edf8be4
PR Gates / decisions lifecycle (pull_request) Successful in 20s
Review verdict / Set review-verdict status (pull_request) Successful in 3s
PR Gates / Script tests (pytest) (pull_request) Failing after 38s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m13s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 9s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 24s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 16m40s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (pull_request) Successful in 17m20s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
fix(510): re-review round — make two review-added tests actually falsifiable
Re-review of the previous fix commit found that two tests added to close
round-1 findings could not fail. Both verified before fixing:

1. Missing_But_Named_Custom_Playout_Item_Watermark_Should_Not_Fall_Through
   gave the channel-level fallback the SAME missing custom path as the
   playout-item watermark, so a wrongly-widened guard would have fallen
   through to a fallback that also resolved to None -- the assertion held
   either way. The fallback is now an independently resolvable ChannelLogo
   whose cached file exists, so a fall-through returns it and fails the test.
   Added the matching positive control (blank -> falls through and DOES
   return that logo), so the pair shows the guard distinguishes blank from
   unresolvable instead of both landing on None.

2. Deco_With_One_Valid_And_One_Missing_Watermark... asserted a filtered list
   length while the routing claim the decision record cited it for lives in
   FFmpegLibraryProcessService.CanUseFFmpegNativeWatermark, which the test
   never called. It now calls the real predicate.

Also, three wrong claims of my own:

3. The Resource arm comment said "nothing in the app writes a Resource
   watermark to the database". False -- CreateWatermarkHandler and
   UpdateWatermarkHandler persist whatever ImageSource the request names, so
   a Resource watermark IS creatable through the API, always with
   Image = null. That is precisely why the new null guard is load-bearing,
   so the comment was arguing for its own removal.

4. "One resolver and no per-caller policy" contradicted the surviving
   playout-item blank-Custom fall-through documented a few lines later.
   Reworded in both the record and the XML docs: one resolver, and exactly
   one piece of per-caller policy which lives in the CALLER.

5. The record's "12 of 18 new tests fail pre-fix" was stale. Re-measured
   against the final fixture: 19 of 29. The other 10 pass both ways by
   design because they pin preserved behavior, which the record now says
   explicitly rather than leaving the gap to be read as weakness.

Removed the vacuous generated-URL test rather than keeping it with an honest
comment -- an empty list trivially contains no URL, so it implied coverage it
never had. Its assertion is folded into the sibling test that has a real
arrangement.

Gates: 2772 tests green across 5 projects, dotnet format exit 0, no BOMs,
decisions-validate OK, live-E2E re-run against this binary (0 changed pixels,
nameplate absent, warning emitted).

refs #510
2026-07-26 21:29:11 +02:00
2022-04-28 06:56:01 -05:00
2025-11-11 06:12:46 -06:00
2021-02-08 21:13:53 -06:00
2023-08-13 09:33:33 -05:00
2025-11-26 10:49:01 -06:00
2026-02-24 15:27:51 -06:00

ErsatzTV

ErsatzTV lets you transform your media library into a personalized, live TV experience - complete with EPG, channel scheduling, and seamless streaming to all your devices. Rediscover your content, your way.

contact features community

epg-example

How It Works

  1. Install ErsatzTV: Download and set up the server on your system.
  2. Add Your Media: Connect your media libraries and collections.
  3. Create Channels: Design and schedule your own live channels.
  4. Stream Anywhere: Watch on any device with IPTV and EPG support.

Key Features

  • Custom channels: Create and schedule your own live TV channels.
  • IPTV & EPG: Stream with IPTV and Electronic Program Guide support.
  • Hardware Transcoding: High-performance streaming with hardware acceleration (NVENC, QSV, VAAPI, AMF, VideoToolbox)
  • Media Server Integration: Connect Plex, Jellyfin, Emby and more.
  • Music & Subtitles: Mix music videos and enjoy subtitle support.
  • Open Source: Free, open, and community-driven project.

Documentation

Documentation is available at ersatztv.org.

License

This project is inspired by pseudotv-plex and the dizquetv fork and is released under the zlib license.

S
Description
Fork of ErsatzTV - custom IPTV channel server (upstream archived Feb 2026)
Readme Zlib
72 MiB
v26.11.0
Latest
2026-07-20 22:22:04 +02:00
Languages
C# 65%
TypeScript 15.8%
Python 9.6%
JavaScript 5.8%
Shell 2.5%
Other 1.2%