m3u-viewer jvonscheidt
winget install --id=jvonscheidt.m3u-viewer -e Fast terminal viewer for large M3U playlists
winget install --id=jvonscheidt.m3u-viewer -e Fast terminal viewer for large M3U playlists
A fast terminal viewer for large M3U/M3U8 playlists, written in Rust. Browse, filter, and play IPTV channel lists that are far too big for a text editor — smoothly, even at 100 MB.
On Windows, install with WinGet:
winget install --id jvonscheidt.m3u-viewer --exact
Prebuilt archives for Windows, Linux, and macOS are attached to each GitHub release.
Requires a stable Rust toolchain (pinned via
rust-toolchain.toml) and, for playback, VLC.
$ cargo build --release
$ ./target/release/m3u-viewer
Or directly:
$ cargo run --release --
The UI opens immediately; large files keep loading in the background while you browse (progress shows in the status bar).
m3u-viewer [--epg ] [--vlc ] [--vlc-reuse-instance]
m3u-viewer --xtream --username --password [--epg ] [--user-agent ] [--vlc ] [--vlc-reuse-instance] [--save-config]
m3u-viewer [--vlc ] (with saved Xtream credentials)
m3u-viewer --version
.m3u or .m3u8, UTF-8).--xtream — instead of a file, load the playlist of an
Xtream Codes account. `` is the provider's base URL (e.g.
http://provider.example:8080; http:// is assumed if omitted).
Requires --username and --password. The playlist is downloaded via
the account's get.php endpoint and streams into the viewer while it
arrives. If the provider has disabled the M3U download (some panels
block get.php entirely), the live channel list is fetched through
the Xtream player API (player_api.php) instead, with categories as
groups. Note that the credentials are visible in your shell history
and process list.--epg — load an XMLTV
programme guide (plain or gzipped) and show what's airing now and
next. Usually unnecessary: playlists that name a guide in their
#EXTM3U url-tvg="…" header and Xtream accounts (via xmltv.php)
get EPG automatically; this flag overrides both. Can also be set as
epg_url in config.toml; the CLI value wins.--user-agent — send this User-Agent header when downloading
the playlist from the Xtream server. Some providers only answer to
known player user agents, e.g. --user-agent "VLC/3.0.20 LibVLC/3.0.20".
Can also be set as user_agent in config.toml; the CLI value wins.--save-config — write the Xtream credentials, the user agent, the
EPG source, and the VLC path (if given) to config.toml in the
config directory so you can omit them on future invocations. Run
once; then m3u-viewer with no arguments picks up the saved
credentials automatically. The file is created if it does not exist
yet.--vlc — use this VLC executable instead of auto-detection.
Without it, vlc is looked up on PATH, then in the standard install
locations (e.g. C:\Program Files\VideoLAN\VLC on Windows,
/Applications/VLC.app on macOS).--vlc-reuse-instance — play channels in a single running VLC window
(VLC's --one-instance) instead of opening a new window per channel.
Can also be set as vlc_reuse_instance = true in config.toml.--version, -V — print the application version and exit.When a guide is available — from --epg, the playlist's
url-tvg header, or the Xtream account itself — the channel list
gains a "now playing" column, and a line above the status bar shows
now/next with times for the selected channel:
▶ 20:15–21:45 Breaking Stories & More · next 21:45 Late Review
Channels are matched by tvg-id, falling back to the channel name.
The guide loads in the background (epg… in the status bar; epg ✗
plus a log entry if it fails) and never blocks browsing. Only a
12-hour window around "now" is kept, so even multi-day guides for
huge playlists stay cheap. e hides/shows the EPG display.
/ filters over channel name and group as you type. The pattern is a
case-insensitive regular expression
— bbc|cnn matches either channel, ^sky sports anchors at the
name's start. Text that doesn't (yet) compile as a regex — usually a
pattern you're still typing — falls back to a plain substring match
instead of showing "no matches", and the status bar says so. Set
regex_filter = false in config.toml to always match literally
(then ESPN+ finds only ESPN+).
Press ? inside the viewer for the full list. The essentials:
| Key | Action |
|---|---|
/ + text | filter channels as you type (regex) |
g | restrict to one group |
Enter | play the selected channel in VLC |
f | mark/unmark as favorite (★) |
F / R / Tab | favorites view / recents view / cycle views |
e | toggle the EPG display |
Esc | clear filter and group |
q | quit |
All persistent data lives in the per-user config directory — on Windows
%APPDATA%\m3u-viewer\config\, on Linux ~/.config/m3u-viewer/, on
macOS ~/Library/Application Support/m3u-viewer/.
| File | Contents |
|---|---|
config.toml | Xtream credentials, user agent, EPG source, and VLC path (written by --save-config); hand-edited toggles like regex_filter and vlc_reuse_instance |
favorites.json | Favorited channel URLs |
recents.json | Recently played channel URLs (newest first, capped at 50) |
cache/ | Last successfully downloaded Xtream playlist per account, shown instantly on the next launch while the live refresh runs |
m3u-viewer.log | Diagnostic log (startup, loading, playback); overwritten each run |
Favorites and recents are keyed by stream URL, so they survive playlist
re-downloads and re-ordering. Xtream credentials are stored in plaintext
in config.toml and in stream URLs inside the cache, favorites, and recents
files. These files are protected by the user account's filesystem access
controls (and created with mode 0600 on Unix), but they are not encrypted.
Deleting the directory resets everything.
m3u-viewer ; also accepts .m3u8 (UTF-8).--xtream --username --password <p> downloads the account playlist over HTTP
(get.php?type=m3u_plus) and streams it through the same parser;
progress is indeterminate when the server does not announce a
content length.--save-config persists Xtream credentials
and the VLC path to config.toml in the platform config directory;
subsequent invocations with no arguments use the saved values
automatically. CLI arguments always take precedence over config. The
file stores credentials in plaintext.#EXTINF metadata: channel name, tvg-id, tvg-logo (ignored),
group-title, and the stream URL on the following line./ opens a filter prompt; matching is over channel name and group,
updated on every keystroke (debounced ≤ 50 ms).regex_filter = false in config.toml forces literal substring matching.group-title; groups are listed alphabetically too.--epg (or
epg_url in config.toml), the playlist's #EXTM3U url-tvg /
x-tvg-url header, and — for Xtream accounts — the panel's
xmltv.php endpoint. Gzipped feeds are detected by content, not
file name.tvg-id first, then by display name
(case-insensitive). The list shows the current programme per
channel; a dedicated line shows now/next with times for the
selection.e toggles the EPG display without discarding the loaded guide.Enter launches the selected channel's URL in VLC as a detached
process; the viewer stays open.vlc on PATH, standard install locations per OS
(e.g. C:\Program Files\VideoLAN\VLC\vlc.exe on Windows), overridable
via config file or --vlc .f toggles favorite on the selected channel; favorites are marked
(e.g. ★) in the list.F) lists only favorites.%APPDATA%\m3u-viewer\favorites.json).R) lists them newest-first; persisted alongside
favorites.| Key | Action |
|---|---|
↑/↓, PgUp/PgDn, Home/End | Navigate list |
Enter | Play in VLC |
/ | Filter (type to narrow, Esc clears) |
g | Group selector |
f | Toggle favorite |
F | Favorites view |
R | Recent channels view |
Tab | Cycle views: all / favorites / recents |
e | Toggle EPG display |
? | Help overlay |
q | Quit |
| Metric | Target |
|---|---|
| Time to interactive UI | < 200 ms |
| Full background parse | < 3 s |
| Keystroke-to-filter-result | < 100 ms |
| Scrolling | no perceptible lag (60 fps redraw budget) |
| Memory | < 4× file size resident |
Vec with interned group names.directories crate); written atomically on change.std::process::Command spawn, detached, stdout/stderr
discarded.