-
Notifications
You must be signed in to change notification settings - Fork 17
Streaming Sources
How to get audio and video into TinyIce. Five paths: Icecast SOURCE/PUT, RTMP, SRT, WebRTC (browser), and pulling from an upstream Icecast relay. For getting streams back out, see Playback and Output.
Every external ingest path is authenticated with the per-mount source password
(falling back to default_source_password). Wrong-password attempts feed the
IP-level brute-force lockout — see Security.
The classic path. Works with BUTT, Mixxx, LadioCast, ffmpeg, RocketBroadcaster, and anything else that speaks Icecast 2. No ingest config needed — it runs on the main HTTP port.
Encoder settings:
| Field | Value |
|---|---|
| Server / host | your host |
| Port |
8000 (or your port) |
| Mount |
/live (any path) |
| User |
source (or empty) |
| Password | the mount's source password, or default_source_password
|
| Format | MP3, Ogg Opus, Ogg Vorbis, FLAC, FLAC-in-Ogg, WAV |
ffmpeg example:
ffmpeg -re -i input.mp3 -f mp3 -content_type audio/mpeg \
icecast://source:<password>@host:8000/liveThe TCP connection is hijacked into a raw, low-latency pipe; data is written straight into the mount's circular buffer. Late-joining listeners get an "instant start" burst from the buffer, plus (for Ogg) the captured BOS/Tags pages so the stream is immediately playable. A 60 s idle read deadline reaps silent/stuck encoders so they don't pin a connection forever.
TinyIce accepts H.264 + AAC (or H.264 + MP3) over RTMP and produces HLS
audio+video at /<mount>/playlist.m3u8.
1. Enable RTMP in tinyice.json (see Configuration):
"ingest": { "rtmp_enabled": true, "rtmp_port": "1935" }2. Create the mount in Admin → Streams → Add Mount. The mount's source password is your OBS Stream Key.
3. OBS → Settings → Stream (Service: Custom):
-
Server:
rtmp://<host>/<mount>— e.g.rtmp://radio.example.com/live -
Stream Key: the mount's source password
The classic single-URL form also works: Server
rtmp://<host>/, Stream Key<mount>?key=<password>.
4. OBS → Settings → Output: video encoder x264 (or hardware H.264), audio
encoder AAC or MP3, keyframe interval 1 s (matches the default HLS segment
size for lowest latency; 2 s is fine).
5. Start Streaming. The log shows RTMP: Publishing started mount=/<name>
and Parsed AVC config.
The HLS muxer emits one PES per frame with real 90 kHz PTS+DTS derived from the FLV composition-time field (correct on B-frame streams), AAC as ADTS, PCR on every PES, and keyframe-aligned segment boundaries. If OBS restarts its encoder mid-session, the keyframe index is reset and new viewers are fast-forwarded past the pre-reconfig bytes so a late tune-in doesn't crash the decoder.
Watch it via the browser player, HLS, or WebRTC.
Enable SRT in the ingest config:
"ingest": { "srt_enabled": true, "srt_port": "9000", "srt_latency": 120 }Publish an MPEG-TS stream (audio and video) from OBS, ffmpeg, or a DVB mux:
srt://host:9000?streamid=#!::r=live,m=publish,key=<password>
r= is the mount, key= is the source password. The TS demuxer resyncs
byte-by-byte if the sync byte drifts, so misaligned inputs don't silently lose
data.
Admin → Go Live broadcasts straight from a browser tab — no encoder software. It captures the mic/line input via WebAudio, offers a device picker, spectrum analyser, and level meters with headroom in dB.
-
WebRTC mode (default): Opus over a
pion/webrtcpeer connection, muxed to Ogg pages and written into the mount buffer. Lowest latency. -
HTTP fallback:
MediaRecorderchunks POSTed to/admin/golive/chunk(CSRF-protected, requires per-mount access).
The WebRTC source-ingest endpoint requires the source password. This was the subject of CVE-2026-45327 (fixed in 2.5.0) — keep your server current. See Security.
TinyIce can act as a relay/edge node, pulling a stream from an upstream Icecast
server and re-serving it as a local mount. Configure under relays
(Admin → Relays):
"relays": [
{ "url": "http://master:8000/stream", "mount": "/relay",
"password": "", "burst_size": 65536, "enabled": true }
]| Field | Notes |
|---|---|
url |
Upstream stream URL. |
mount |
Local mount to publish under. |
password |
If the upstream requires source auth. |
burst_size |
Instant-start buffer for local listeners. |
enabled |
Per-relay toggle (honoured across restarts). |
In-stream ICY metadata is parsed and re-emitted, so "now playing" follows the upstream. The relay body has a 60 s idle read deadline. Relay chaining works; shared cluster state does not (each node is independent).
SSRF guard: relay (and webhook) URLs are validated — loopback, private (RFC 1918), and link-local addresses are rejected. See Security.
A mount that receives no data for ~2 minutes is automatically removed by the
health monitor (its health is exposed per-stream in /api/streams).
Transcoded outputs are exempt — they're tied to a configured encoder that
re-attaches when the source resumes, so they survive transient source flaps.
Next: Playback and Output · Transcoding · AutoDJ
Repository · Releases · Issues · Security policy · Apache-2.0
Getting started
Streaming
Integrations
Operations
Internals
Help