Skip to content

How it works

Recorder

A single Go binary. Subscribes to followed channels, evaluates schedules, pulls HLS segments, and remuxes finished recordings to MP4.

Dashboard

React SPA served by the same Go binary. Login, schedules, live indicators, recording queue, playback.

Database

SQLite or Postgres. Holds schedules, videos, segment state, sessions, and scheduled-task state.

Storage

Local filesystem or S3-compatible. Holds the actual MP4s and thumbnails.

Connect relay

Optional Cloudflare Worker that gives you a public EventSub callback without router-port forwarding.

A schedule is a rule. When a followed channel goes live, ReplayVOD evaluates every schedule and records the stream if any of them match. Filters available: channel, category, tag, viewer threshold, quality. See Schedules & title tracking for the full reference.

ReplayVOD subscribes to Twitch EventSub and acts on stream.online deliveries the moment they arrive. EventSub requires a publicly reachable HTTPS callback — direct (EventSub) or via the Connect relay.

Stream titles and categories often change mid-broadcast. ReplayVOD captures that history while a recording is active. Three modes — see Schedules & title tracking for the full table.

Once a stream matches a schedule:

  1. Fetch a Twitch playback token (anonymous by default; authenticated if TWITCH_SERVICE_ACCOUNT_REFRESH_TOKEN is set).
  2. Pull the HLS master playlist; pick a variant per [download] policy.
  3. Download segments in parallel with retry and gap detection.
  4. Remux to MP4 with ffmpeg; probe with ffprobe.
  5. Generate a thumbnail and snapshot strip.
  6. Hand the finished file to the storage backend (local move or S3 upload).

Job and segment state lives in the database, so a crash mid-record resumes cleanly on the next start.

Twitch EventSub needs a public HTTPS endpoint. Many homelabs don’t have one. Connect is a small Cloudflare Worker that:

  • Gives you a public ingest URL Twitch posts to.
  • Forwards each signed POST to your recorder over an outbound WebSocket.
  • Holds no Twitch credentials and never inspects payloads — your recorder still verifies the HMAC locally.

You don’t need Connect if you can already expose /api/v1/webhook/callback over public HTTPS. See Connect relay for setup.