Skip to content

Pairing With tvdinner

Iain Smith edited this page Sep 3, 2026 · 3 revisions

Pairing with tvdinner

tvdinner is the companion desktop player. The split the pairing is built around:

tvtimes is where you plan. tvdinner is where you watch.

Everything below rides the export token you already have from Export Feeds — there's no second credential, no pairing dance, and no per-feature setup. Turn the feeds on once and each capability is a flag away.

At a glance

What you want tvtimes side tvdinner side Since
Play your whole line-up Open in tvdinner button tvtimes://host?token=… tvtimes 0.1.53 · tvdinner 1.36
Record what you watchlist /api/exports/watchlist.json --record-watchlist 0.1.53 · 1.37
See what you've watched POST /api/exports/watch-events --report-watch-state 0.1.54 · 1.38
Share your favourites /api/exports/favourites.json --sync-favourites 0.1.55 · 1.39
Jump back to the web guide /search?q=… T keybinding 0.1.55 · 1.39
See what's still connected Export feeds panel 0.1.56

All of it at once:

tvdinner 'tvtimess://tv.example.com?token=…' \
    --record-watchlist \
    --report-watch-state --device-name 'living room' \
    --sync-favourites

1. Your whole line-up, as one source

Settings → Export feeds → Generate feed links now shows a third row, Open in tvdinner, carrying a single URL that stands in for both feeds:

tvtimess://tv.example.com?token=…      (tvtimes:// if you serve over http)

Click it — once tvdinner has run tvdinner default-handler, the browser hands tvtimes: links straight over — or copy it and run tvdinner 'tvtimess://…'.

It's sugar, not a protocol: tvdinner expands it back into the same playlist.m3u + epg.xml pair, so its program guide, favourites, recording and scheduling behave exactly as they would for any M3U + XMLTV source. A sub-path deployment keeps its base path (tvtimess://example.com/tv?token=…).

One subtlety worth knowing: tvdinner derives the guide URL from the host you typed rather than from the playlist's own url-tvg= header. tvtimes builds that header from its configured public origin, which needn't be the address the player reaches it on — a LAN IP versus the proxied hostname.

2. Record what you watchlist

Press Remind me (or Watch this title) here — on your phone, on the bus — and the box at home records it.

tvdinner 'tvtimess://…' --record-watchlist

tvdinner polls /api/exports/watchlist.json every 15 minutes and turns each upcoming airing into a scheduled recording.

  • The watchlist is per user; the token is per account. The feed is the union across the household, de-duplicated per broadcast — two people flagging the same film yields one recording.
  • Un-watchlisting removes the pending recording on the next poll. Recordings you scheduled by hand in tvdinner are never touched, and no duplicate is added beside one that already covers the same airing.
  • Times arrive already clock-shift corrected, so they line up with the guide.
  • tvdinner has no background service — it must still be running when the recording's time comes.

3. See what you've watched

tvdinner 'tvtimess://…' --report-watch-state --device-name 'living room'

The guide grid then dims and ticks programmes you've already seen.

What a player sends is plain start/stop intervals — never "programme X was watched". tvtimes derives which programmes those cover by overlapping them against its own guide. That's the whole point of the design:

  • An EPG re-ingest deletes and recreates every programme row. An interval doesn't care; a stored programme reference would have dangled.
  • Correcting a channel's clock offset retroactively fixes what counts as watched, with nothing re-reported.

A programme counts as watched once half of it, or 30 minutes, is covered — whichever is less demanding, so flicking past doesn't count and half a three-hour film isn't demanded. Intervals over six hours are ignored as a player left running at a dead screen.

This is the one thing the export token can write. It stays narrow: it appends intervals for channels already on your account and nothing else. The worst a leaked token does here is pollute your own watched badges — it already exposes the whole line-up and streams through it. Leave --report-watch-state off and nothing is ever written.

4. Share your favourites

tvdinner 'tvtimess://…' --sync-favourites

Stars set in the web app appear in tvdinner's guide, read from /api/exports/favourites.json at startup.

Additive and one-way. Un-starring here won't un-star it there. tvdinner records favourites by name with no note of where each came from, so a two-way reconcile couldn't tell "removed upstream" from "added locally" — and quietly deleting a favourite someone set themselves is the worse failure. Un-star it in tvdinner with h.

5. Jump back to the web guide

T in tvdinner opens tvtimes for whatever's on the current channel — the reverse of the Play button. It lands on /search?q=<title> rather than the exact guide cell: the grid is virtualised, so targeting a cell would need scroll-to-row support, and finding the thing by name is what you actually want arriving from a player.

Playing just one channel

You don't need any of this to send a single channel across. Play on any programme panel emits a tvdinner: link carrying that one channel and its own guide, behind a 24-hour ticket rather than the export token — see Export Feeds.

Use tvtimes:// when you want the whole line-up; use Play when you just want to watch the thing you're looking at.

Seeing what's connected

Settings → Export feeds shows when the feeds were last fetched, and lists the players reporting watch state back — by their --device-name, or grouped as a single "Unlabelled player" for any running without one.

This is the only place a paired player is visible. An export token never creates an entry on the Sessions screen — that screen is browser sign-ins — and a watchlist or favourites poll is a plain read that leaves no trace. Before this, a box that had stopped reporting, or a token still live on a machine you'd retired, looked exactly like nothing at all.

Two caveats worth knowing:

  • "Last fetched" is recorded at most once a minute, so it's deliberately coarse — the panel only ever shows it as "3 minutes ago" anyway, and a player polling hard shouldn't turn every read into a write.
  • The device list is derived from the stored intervals rather than tracked separately, so a player that stops reporting drops off once its last interval ages out of the 90-day retention window. It's "who has been watching", not a registry of paired devices.

Building your own

Nothing here is tvdinner-specific. The feeds are ordinary HTTP behind the export token, and the routes are documented as OpenAPI: tvtimes Export API.

Security summary

Reach Lifetime
Export token whole line-up, streams, watchlist, favourites; writes watch state until rotated
Play ticket one channel + its guide 24 hours

Rotating the export token invalidates every feed and every saved tvtimes:// bookmark at once. Treat it as a password — see Export Feeds and Accounts and Security.

Clone this wiki locally