Skip to content

Streaming Sources

DatanoiseTV edited this page Jun 18, 2026 · 1 revision

Streaming Sources (Ingest)

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.


Icecast SOURCE / PUT

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/live

The 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.


Video from OBS (RTMP)

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.


SRT (MPEG-TS)

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.


WebRTC from the browser (Go Live)

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/webrtc peer connection, muxed to Ogg pages and written into the mount buffer. Lowest latency.
  • HTTP fallback: MediaRecorder chunks 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.


Pulling a relay

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.


Auto-removal of silent mounts

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

Clone this wiki locally