A native Windows IPTV player written in C++20 with Qt 6 and libVLC. It plays M3U playlists, Xtream Codes portals, Stalker/Ministra portals and Plex libraries, with a virtualised XMLTV programme guide, multi-view, and DVR recording.
No licence key, no account, no feature gates. Your IPTV credentials stay on your machine, DPAPI-encrypted.
OmenPlayer ships no channels, streams or content. It is a player, like VLC. You bring your own playlist or provider subscription.
Most IPTV front-ends are Electron apps or Android ports that redraw the world on every keystroke. OmenPlayer is compiled to machine code and treats a 20,000 channel playlist as the normal case rather than the pathological one:
- Starts from cache. The full playlist is stored as a binary snapshot. Startup reads it in roughly 0.4 s instead of an ~18 s network round-trip. Re-downloads happen only on manual refresh, TTL expiry (24 h, refreshed in the background) or changed credentials.
- Never parses on the UI thread. M3U and XMLTV parsing run on workers with generation guards, so stale callbacks cannot clobber fresh state.
- Draws only what you can see. The EPG grid virtualises rows and programme blocks, with cached text layouts and a bounded row cache.
Sources — M3U/M3U8 via URL or local file (including .gz), Xtream Codes
(live, VOD, series with seasons/episodes, account status, TS or HLS), Stalker/
Ministra portals (beta: live, VOD and series via MAC-based sign-in; stream
URLs are resolved per play through the portal's create_link), and Plex
(movie and series libraries). Multiple providers merge into one library without
ID collisions.
Guide — XMLTV EPG, auto-discovered via Xtream xmltv.php or url-tvg, or
a manual URL. Streaming parse, gzip, disk cache, now/next with progress, a full
day view, and a fullscreen overlay guide.
Playback — libVLC by default: HLS, MPEG-TS, MKV/HEVC/AC3. Auto-reconnect
with backoff on stream errors, theatre mode, fullscreen, zapping, favourites,
click-to-seek, audio delay (G/H, -5000..+5000 ms), subtitle styling, and
resume of the last watched channel. MPV is available as an opt-in beta backend.
Extras — Multi-view (up to four streams, exactly one audible), DVR
(immediate and scheduled), Windows auto frame-rate matching, OpenSubtitles
search, external ratings and Discover rows via MDBList, a local inverted
prefix index for instant search (Ctrl+F), catch-up/archive, watch progress,
next-episode handling, and EN/NL localisation.
Everything is free; there are no tiers.
Download the installer from the Releases page and run it. Windows 10 or 11, 64-bit. Then add a playlist via Settings → Add playlist.
Requirements
| Qt | 6.8 (mingw_64) — Widgets, Network, Xml, Concurrent |
| Toolchain | MinGW 13 (ships with Qt; provides gcc, gendef, dlltool) |
| Build | CMake 3.21+ and Ninja |
Put the Qt MinGW toolchain on PATH first — fetch-vlc.ps1 needs gendef
and dlltool from it:
$env:PATH = "C:\Qt\Tools\mingw1310_64\bin;C:\Qt\6.8.3\mingw_64\bin;$env:PATH"1. Fetch libVLC. The SDK is not vendored in this repository. The script downloads the official VLC 3.0.21 build from videolan.org, verifies a pinned SHA-256, and regenerates the MinGW import libraries:
powershell -ExecutionPolicy Bypass -File scripts/fetch-vlc.ps12. Configure and build.
cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=C:\Qt\6.8.3\mingw_64
cmake --build build --parallel
windeployqt build/client/OmenPlayer.exe # bring the Qt runtime along3. Run the tests.
cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=C:\Qt\6.8.3\mingw_64 -DOMEN_BUILD_TESTS=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failureThat registers 12 suites covering player/subtitles, pointer interaction, app integration and localisation, EPG windowing, playlist merge and catch-up, the settings wizard, storage and search, ratings matching, and multi-view/DVR/AFR.
Already have a VLC SDK? Point at it with -DLIBVLC_DIR=<path>.
Ratings/Discover (MDBList) and subtitle search (OpenSubtitles) run on an app key rather than a per-user account, so they are baked in at build time and never committed:
cmake -S . -B build -DOMEN_MDBLIST_API_KEY=<key> -DOMEN_OPENSUBTITLES_API_KEY=<key>Without a key those features simply hide themselves and the rest of the app
works normally. OMEN_MDBLIST_API_KEY / OMEN_OPENSUBTITLES_API_KEY in the
process environment override the baked value for local work. Free keys:
mdblist.com,
opensubtitles.com.
A key inside a desktop binary can be recovered with
strings. That is true of every client-side key and only a proxy server avoids it. Treat these as public and rotatable, not as secrets.
Modules live in client/src/:
| Module | Responsibility |
|---|---|
MainWindow / MainWindow_logic |
UI construction; navigation, sources, playback, EPG |
CustomWidgets, ListModels, UiHelpers |
reusable widgets, models, delegates |
PlayerController, VideoWidget |
libVLC wrapper and native video surface (mouse/touch/pen) |
PlayerAdapter, VlcPlayerAdapter, MpvPlayerAdapter |
shared player contract; VLC default, MPV beta with safe fallback |
MultiViewController |
up to four independent players, exactly one audible |
Recorder, AutoFrameRateController |
headless DVR; temporary Windows refresh-rate control |
XtreamClient, M3uParser, PlexClient, StalkerClient |
providers |
EpgService |
XMLTV parse (worker), disk cache, now/next via immutable snapshots |
EpgGridView, FullscreenGuideOverlay |
virtualised guide; keyboard and D-pad navigation |
PlaylistMergeEngine, CatchupUrlBuilder |
provider-scoped IDs, merging, safe archive URLs |
SearchIndex |
local inverted prefix index over channels, EPG, movies, series |
PlaylistCache |
binary per-source disk cache — the app starts from cache |
ImageCache |
logos/posters: LRU memory bound plus persistent disk cache |
RatingService, MdbListClient, ContentMatcher |
external ratings and title matching |
OpenSubtitlesClient |
subtitle search and download |
Http |
shared async HTTP (keep-alive, gzip, timeouts) |
Storage, SecureStore |
atomic config (QSaveFile) plus DPAPI encryption |
Log |
rotating file logging |
State. AppConfig is the persistent user state; Storage normalises
imported values and writes atomically, with passwords and tokens protected by
Windows DPAPI. Favourites, custom groups, hidden items, reminders and
recordings are separated per sourceId. PlaylistMergeEngine gives every
upstream ID an injective provider prefix so sources merge without conflicts.
Large network data stays out of the config as binary playlist and immutable
EPG snapshots.
Auto frame-rate reads the detected video frame rate after the libVLC vout
is up and uses the monitor the VideoWidget sits on. It picks a supported
cadence multiple (23.976→24, 25→50, 29.97→60) via ChangeDisplaySettingsEx,
never persists a mode to the registry, and restores the original display mode
on zap, stop, end, error or destruction.
VLC stays the default. The MPV adapter loads the public libmpv C ABI at
runtime only when the user opts in ("MPV Player (beta)" under Settings >
Player). To get a runtime, either run
powershell -ExecutionPolicy Bypass -File scripts/fetch-mpv.ps1which downloads a pinned, checksum-verified libmpv-2.dll (shinchiro
mpv-winbuild) into third_party/libmpv/bin/ — copy it next to
OmenPlayer.exe — or place your own compatible 64-bit mpv-2.dll (or
libmpv-2.dll) there yourself, or point at a trusted install with
OMEN_MPV_DLL=C:\path\to\mpv-2.dll. If an export is missing or playback
fails, the session falls back to the VLC controller.
The git repository ships no MPV binaries. The shinchiro builds are effectively
GPLv3 as combined works; see THIRD_PARTY_NOTICES.md before redistributing a
package that includes libmpv-2.dll.
- Log:
%AppData%/Omen/OmenPlayer/logs/omen.log(rotates at 1 MB). OMEN_VLC_LOG=<path>writes a libVLC log;OMEN_AUTOPLAY=1autostarts the first channel.- Caches and config live under
%AppData%/Omen/OmenPlayer/.
See CONTRIBUTING.md. Note that existing source comments are in Dutch; documentation is English. Both are fine in new code.
Security issues: please use private advisories rather than public issues. See SECURITY.md.
GPL-3.0-or-later. See LICENSE.
OmenPlayer links libVLC dynamically, and official binary releases bundle VLC's plugin set — which includes GPL-2.0-or-later modules. The combined distributed work is therefore GPL, the same position VideoLAN takes for VLC itself. Third-party components and their licences are listed in THIRD_PARTY_NOTICES.md.