Appearance
Relay another station
A relay makes Quikcast pull an existing stream from somewhere else (an Icecast or SHOUTcast stream, or an audio-only HLS playlist) and publish it on one of your mounts. People use relays to rebroadcast a partner station, build an edge server closer to listeners, or keep a backup feed warm.
Set up a relay
A relay needs two things: a mount to publish on, and a [[relays]] block saying where to pull from.
toml
[[mounts]]
path = "/remote.mp3"
secret_file = "secrets/remote-local" # still required, see note below
[[relays]]
mount = "/remote.mp3"
url = "https://origin.example/live"Listeners now play http://your-server:8000/remote.mp3.
The relay owns the mount
While a relay is configured for a mount, no encoder can connect to it, even if the relay is stopped. The mount still needs a password in its own block because the relay publishes through it.
Add backup upstreams
List more than one upstream with upstreams. If the first fails, Quikcast moves to the next straight away:
toml
[[relays]]
mount = "/remote.mp3"
upstreams = [
{ url = "https://primary.example/live" },
{ url = "https://backup.example/live" },
]How failover works:
- The first entry is the primary. A failure moves to the next entry immediately.
- After the last entry fails, Quikcast waits (1 second, doubling up to 60) and starts again from the primary.
- A working backup stays in use until it fails. There is no automatic return to the primary.
- Each switch is a new stream generation. Listeners reconnect to it and see the new source's audio format.
You can list up to 8 upstreams.
Upstreams that need a password
If the origin requires a login, give a username and a password file. Relay passwords can be shorter than local ones, since they must match whatever the origin gave you.
toml
[[relays]]
mount = "/remote.mp3"
username = "partner"
secret_file = "secrets/partner-password"
upstreams = [
{ url = "https://partner.example/live" },
{ url = "https://mirror.example/live", username = "other", secret_file = "secrets/mirror-password" },
]The top-level username and secret_file are the default for every upstream that does not set its own. Credentials are never sent to a different host than the one you configured, even across redirects.
Redirects
Many stream URLs redirect to a CDN. Allow Quikcast to follow them with max_redirects (0 to 8, default 0):
toml
[[relays]]
mount = "/boxradio.mp3"
url = "https://stream.example/abc123"
max_redirects = 3Control a relay while running
Relays are managed through the management API (you need [management] enabled):
| Action | Request |
|---|---|
| See all relays | GET /api/relays |
| See one relay | GET /api/relays/radio.mp3 |
| Reconnect (starts at the primary) | POST /api/relays/radio.mp3 |
| Stop and stop retrying | DELETE /api/relays/radio.mp3 |
Set enabled = false on a relay to have it start stopped.
Relay an HLS stream
Many stations publish only HLS (a .m3u8 playlist with small audio segments). Point a relay at the playlist and Quikcast republishes it on your mount as an ordinary continuous stream, so your listeners and players do not need to know it started as HLS.
toml
[[mounts]]
path = "/hls-station.aac"
secret_file = "secrets/hls-station-local"
[[relays]]
mount = "/hls-station.aac"
url = "https://stream.example/live/index.m3u8"
max_redirects = 3 # HLS segments are often redirected to a CDNThere is nothing to switch on: a relay recognises a playlist by its content type or a .m3u8 address.
How it works:
- Pick a variant. If the address is a master playlist with several bitrates, Quikcast follows an audio-only variant, the highest bitrate by default. Set
hls_variant = "lowest"to save bandwidth. Variants with video are never chosen. - Join near the live edge. It fetches the newest two segments first, then keeps polling the playlist (about every half segment length) for new ones.
- Unwrap the audio. Each segment is stripped down to plain AAC or MP3 audio and published to the mount. Nothing is decoded or re-encoded.
| Segment type | Supported |
|---|---|
Packed AAC or MP3 (.aac, .mp3) | Yes |
MPEG-TS with AAC or MP3 (.ts) | Yes |
Fragmented MP4 with AAC-LC (.m4s with an init section) | Yes |
Encrypted segments (EXT-X-KEY), byte ranges, FLAC or ALAC in MP4, video-only variants | No |
Expect some delay
HLS is built from segments, so a relayed HLS stream plays roughly 10 to 30 seconds behind the source, depending on how long each segment is. That is a property of HLS, not of Quikcast.
Good to know:
- It must be a live stream. A playlist that ends (
#EXT-X-ENDLIST) counts as the upstream finishing, so the relay backs off and retries, like any other upstream that disconnects. - Stalls and errors. An expired segment (404) is skipped. Three failed fetches in a row make the relay fail over to the next upstream. If no new audio arrives for the longer of
audio_timeout_msand three segment lengths, the relay treats the upstream as stalled. - Credentials stay home. A username and password are sent only to the host that served the playlist, never to a different host (a CDN) that serves its segments.
- Song titles are not carried over. HLS timed metadata is ignored, so the mount shows no track titles and no station name.
- One format per generation. If the upstream switches codec (AAC to MP3, say), the relay starts a new generation so listeners get the right content type.
- Size limits. Playlists up to 128 KiB (1,024 segments) and segments up to 1 MiB, which covers audio-only HLS comfortably.
Old SHOUTcast servers
Streams from older SHOUTcast v1 servers answer with a non-standard ICY 200 OK status line instead of HTTP/1.1 200 OK. Quikcast accepts that automatically, so you can relay them like any other URL. No setting is needed.
Things worth knowing
- HTTPS upstreams are always verified against the public certificate authorities. There is no switch to disable verification, add a private CA or use client certificates.
- Only HTTP and HTTPS upstreams that return a normal
200response (or the old SHOUTcastICY 200 OK) are supported. - Formats: MP3, AAC, Ogg Vorbis, Opus and Ogg FLAC streams, native FLAC (
audio/flac), and audio-only HLS (above). - A public upstream cannot point Quikcast at your private network. If a server on the public internet redirects a relay, or an HLS playlist references a segment, on to a private or local address (
127.0.0.1,10.x,192.168.x,169.254.x, cloud metadata addresses and similar), Quikcast refuses withdestination_not_allowedand tries the next upstream. An upstream you configured yourself on a private address is trusted, so a relay tohttp://192.168.1.20:8000/liveand anything it redirects to inside that network still work. - Never relay a stream to itself. Quikcast rejects obvious loops with its own address, but it cannot see loops that pass through a proxy. Keep your topology a tree.
- Timeouts and backoff are tunable per relay. See the configuration reference.