VirtualChannels

Help & Setup

Your media, as live TV.

VirtualChannels turns folders of your own video files into always-on channels that Plex, Jellyfin, Emby, and Channels DVR treat as real television. This guide takes you from a fresh install to a working tuner — and covers what to check when something looks off.

01 What VirtualChannels is

VirtualChannels turns folders of your own video files into live TV channels. Each channel runs a continuous 24/7 schedule — episodes playing back to back on a real timeline, the way a cable channel does, rather than a library you browse.

It then pretends to be a network TV tuner (an HDHomeRun). Plex, Jellyfin, Emby, and Channels DVR see it as live television, with a full programme guide. Nothing needs to know your files exist.

Two things follow from that design and are worth understanding early:

  • The schedule is real. A programme that started ten minutes ago is ten minutes in when you tune to it. You do not start it from the beginning; that is what makes it feel like TV.
  • Nothing is copied or re-encoded up front. Your files stay where they are. The app reads them on demand.

02 On Air — what's happening right now

This is the screen to leave open. It answers "is it working?" in one look.

  1. Navigation — the app's five areas, grouped by what they do. Broadcast is what's going out, Library is what it's built from, People is who may watch, Output is the tuner itself. Counts and the pulsing dot update live.
  2. Status at a glance — tuners in use, combined output, how many streams are being transcoded, and how far ahead the schedule is published.
  3. What each channel is playing — one card per station showing its number, artwork, the current programme and how far through it is. When somebody is watching, the card shows who and how the stream is being delivered.
  4. Activity log — tunes, scans, source refreshes and server events as they happen. This is the first place to look when something seems wrong.
A note on the numbers. Where a figure hasn't been measured yet, the app shows rather than 0. Output reads until something is actually streaming. That's deliberate: a made-up zero is worse than an honest blank.

03 Sources — where your media comes from

  1. Add Source — the menu offers three kinds:
    • Media Folder — a directory of movies or TV episodes on this Mac or a network volume.
    • HDHomeRun Tuner — a real HDHomeRun on your network (see §7).
    • External Source — an M3U playlist from another server, with an optional XMLTV guide.
  2. Library totals — how many items are indexed, how many external channels are live, when the last scan finished, and whether folder watching is on.
  3. Media folders — each row shows the path, when it was last scanned, how many stations draw from it, and its item count. A folder being scanned shows live probe progress along the bottom edge.
  4. External sources and tuners — imported channel lists, with how many of their channels you've chosen to show.

Adding your first folder

  1. Click Add Source… → Media Folder…
  2. Choose a directory. Subfolders are included.
  3. Indexing starts immediately. Large libraries take a while — a 30,000-file NAS folder can run for several minutes — and the app stays usable throughout.
Filenames matter. VirtualChannels reads episode and movie information from filenames only. It doesn't use NFO files and doesn't look anything up online. Suits - S03E16 - No Way Out.mp4 gives it everything it needs.

When a folder shows a red warning

FOLDER ACCESS LOST — RE-ADD TO RESTORE means macOS revoked the app's permission to that location — usually because a network volume was unmounted, or the folder moved. Click Reconnect… and choose the folder again. Your stations and playlists survive; only the permission is renewed.

04 Stations — building a channel

A station is one channel in your lineup: a name, a channel number, and an ordered list of things to play.

  1. Your channels — every station, with its number and artwork. A red dot means a client is watching it right now.
  2. Station identity — name, number, and how it's programmed. The mono line underneath gives the item count, ordering mode, and how long one full cycle of the playlist runs.
  3. Playlist — what airs, in order. Search it, filter by season, and select several rows at once to remove or reorder them. The item currently broadcasting is marked AIRING NOW.
  4. Settings for this station — identity, programming and availability.

Creating one

  1. Click New Station.
  2. Give it a name and a channel number in the right-hand panel. Numbers can be plain (5) or subchannel-style (5.1).
  3. Click Add Media… and pick episodes or films.
  4. Choose an order — In Order for a series, Shuffle for variety.

Smart stations

Turn on Smart station and the playlist follows rules against your library instead of a hand-picked list. New matching files join the channel automatically after the next scan. Useful for "everything tagged Westerns" or "every episode of one series".

Two behaviours worth knowing

  • Editing a playlist restarts that station's timeline from now. The schedule is computed from an anchor point, and changing what's in the list invalidates it. Expect the guide to shift when you edit.
  • Items with no duration are skipped. They're marked SKIPPED with the reason. A programme of unknown length can't be placed on a timeline. Usually it means the file hasn't finished probing, or is damaged.

05 Guide — the whole lineup on one timeline

  1. Live preview — plays whatever channel is selected. PREVIEW means you're watching it here; ON AIR means a client is tuned to it too. Previewing does not use up a tuner.
  2. Programme detail — the selected programme, when it runs, how long, and which channel it's on.
  3. Timeline — every channel down the left, time across the top, the red line marking now. Arrow keys move the cursor: ↑↓ changes channel, ←→ moves through time.

Jump to now scrolls back to the present after you've been browsing ahead.

Shuffle (the crossed-arrows button) re-rolls every station's timeline from this moment. Shuffle stations get a new order; in-order stations jump to a random episode and continue forward. Refresh the guide in your client afterwards.

06 VC Tuner — connecting your media server

  1. Server status and address — whether the tuner is serving, how long it's been up, its address, current output and tuner usage.
  2. Tuner pool — one card per tuner. Each shows what's playing, which client, how the stream is being delivered, and its bitrate.
  3. Paste these into your media server — the three URLs your media server needs, each with a copy button.
  4. Settings — discovery, port, tuner count, guide window, appearance, and the external address.

Channels DVR

Use a Custom Channels source — not the HDHomeRun option. Channels DVR's HDHomeRun mode reads lineups over port 80, which macOS reserves for the system, so the tuner can't be added that way. The Custom Channels method works on any port and is the supported path (since 1.1).
  1. In the Channels DVR web admin, open Settings → Sources → Add Source → Custom Channels.
  2. Set the source to URL and paste the Playlist (M3U) URL from VC Tuner.
  3. Point its guide at XMLTV and paste the Guide (XMLTV) URL.
  4. Save. Channels imports the lineup with your channel numbers and guide exactly as published — playlist channels keep the order they appear in.

Plex

  1. Settings → Live TV & DVR → Set up Plex DVR
  2. The tuner should appear. If not, choose Don't see your HDHomeRun? and enter the tuner address.
  3. When Plex asks for guide data, choose to use an XMLTV file and paste the Guide URL.
  4. Let Plex scan channels and finish setup.

Jellyfin and Emby

Add an M3U Tuner with the Playlist URL, then an XMLTV guide source with the Guide URL.

Jellyfin defaults M3U tuners to one simultaneous stream. If a second device can't tune, raise that limit in the tuner's settings — or add VirtualChannels as an HDHomeRun instead.

Settings that matter

SettingWhat it does
DiscoveryAnswers HDHomeRun broadcasts on UDP 65001. Leave on unless something else on your network conflicts.
HTTP portDefault 5004. Changing it restarts the tuner; clients reconnect on their next poll.
Tuner countHow many simultaneous streams to allow. Each concurrent viewer uses one.
Guide windowHow many days of schedule to publish. Longer means a bigger XMLTV file.
AppearanceSystem, Light or Dark. Pinning is useful — a dark room shouldn't flip to light at sunrise.
External addressThe public hostname for people outside your house (see §8).

07 Adding a real HDHomeRun

Because VirtualChannels emulates an HDHomeRun, it can also consume one. Your over-the-air or cable channels then appear in the same lineup as your own.

  1. Add Source… → HDHomeRun Tuner…
  2. The app scans your network. Pick the device it finds, or type its address.
  3. Optionally add an XMLTV guide URL.
  4. Click Add Tuner.

The device appears under HDHOMERUN TUNERS in Sources, showing its model, device ID, firmware, and dots for its physical tuners — filled when in use.

HDHomeRun devices carry no guide data. SiliconDust serves that from a separate subscription service. Without an XMLTV URL the channels still appear and still play, but with no programme information.

08 Watching from outside the house

By default the tuner is only reachable on your local network, which is the right default. To extend it safely, use Tailscale — it puts your devices on a private network without opening any ports to the internet.

  1. Install Tailscale on the Mac running VirtualChannels, and on whatever device will be watching.
  2. Sign both into the same Tailscale account.
  3. Find the Mac's Tailscale address (a 100.x.y.z address, or its MagicDNS name).
  4. In VC Tuner → External address, enter that name.
  5. Use the addresses shown on the Users screen on the remote device.

Tailscale is a better fit than port forwarding here because nothing is exposed publicly — traffic is encrypted between your own machines, and there is no certificate to obtain or renew.

⚠️ Do not port-forward this to the open internet as it stands.
See the authentication warning in §9.

09 Users — a profile per person

A tuner has no login screen — Plex and other media servers just want a URL. So the profile is the URL: each person gets their own address, plus a username and password their client asks for once.

  1. Household — everyone with a profile. A red dot means they're watching.
  2. Add User — create a profile; the password is generated for you.
  3. Profile — their role, what they may watch, and their private tuner URL, username and password, each with a copy button. Regenerate issues a new password and signs out every device using the old one.

Setting someone up

  1. Add User…, give them a name, choose a role.
  2. Copy their Tuner address and password.
  3. On their device, add the tuner using that address. It prompts for the username and password once.
⚠️ Authentication is not enforced yet

The profiles, credentials and URLs are all in place, but the server does not yet check them — /u/{username} is not routed and no password is verified. Anything that can reach the tuner can currently watch everything.

On a home network behind a router, that is fine. Over Tailscale it is also fine, because only your own devices are on that network. Do not expose the tuner to the public internet until this lands.

10 Troubleshooting

A channel shows the wrong programme, or something unexpected plays.

Check the Activity log on On Air. If the channel comes from an external source, that source may be substituting content — VirtualChannels verifies streams against the guide and will skip a provider that serves the wrong programme, but it can only do that when the guide carries programme identifiers.

The preview is black.

Most likely the file is in a format macOS cannot decode directly — HEVC tagged hev1, or AC-3 / E-AC-3 audio are common. The app transcodes these for preview using its bundled engine; if that fails the pane says why. Playback to real clients is unaffected, since that path handles these formats natively.

A second device can't tune in.

All tuners are busy. Raise Tuner count in VC Tuner, or check On Air to see what's using them.

Plex or your media server can't find the tuner.

Confirm the server shows Serving on VC Tuner, that Discovery is on, and that both machines are on the same network. Failing that, add the tuner manually with the address shown.

Guide is empty or stale in the client.

Refresh the guide in the client — most cache it for hours. Confirm you pasted the Guide (XMLTV) URL, not the tuner address.

Artwork missing.

Artwork is extracted during indexing, from embedded art, sidecar images, or a frame grab. Run Rescan All on Sources if a folder was indexed before its artwork existed.

macOS asks about Local Network access.

Allow it. Discovery replies need it; without it clients must add the tuner manually.

Still stuck? Email [email protected].