Skip to content

Transcoding

DatanoiseTV edited this page Jun 18, 2026 · 1 revision

Transcoding

TinyIce re-encodes a source mount into MP3 or Opus entirely in Go — no FFmpeg, no GCC. A transcoder subscribes to an input mount, decodes it to PCM, and publishes a re-encoded output mount that listeners consume like any other stream.

Manage transcoders in Admin → Transcoders or via the JSON API. Configuration lives under transcoders in Configuration.

Why

  • Offer a low-bitrate Opus rendition of a high-bitrate source for mobile listeners.
  • Convert an Ogg/FLAC source to MP3 for players that only speak MP3.
  • Normalise sample rate / channel count across mounts.

Basic transcoder

"transcoders": [
    {
        "name": "live-opus-64",
        "input_mount": "/live",
        "output_mount": "/live-opus",
        "format": "opus",
        "bitrate": 64,
        "enabled": true
    }
]
Field Notes
name Identifier.
input_mount Source mount to read.
output_mount Mount to publish the result on.
format mp3 or opus.
bitrate Output bitrate (kbps).
enabled Per-transcoder toggle.

Input formats are the same pure-Go set as the AutoDJ: MP3, Ogg Opus, Ogg Vorbis, FLAC, FLAC-in-Ogg, WAV. Opus output is always resampled to 48 kHz.

Output visibility

visibility controls whether the output appears in public listings, independent of whether it's streamable:

Value Meaning
"" (default) Follow the input mount's visibility.
"public" Always listed.
"unlisted" Hidden from listings, still streamable by URL.

Opus tuning

Opus outputs expose the encoder knobs (zero/empty = sensible default, so old configs keep working):

Field Values Default
sample_rate Hz 48000 (Opus is locked to 48 kHz)
channels 1 or 2 2
opus_application audio · voip · lowdelay audio
opus_vbr true / false VBR on
opus_complexity 0–10 encoder default
opus_frame_size_ms 2.5 / 5 / 10 / 20 / 40 / 60 20

These surface in the admin add/edit-transcoder form.

Auto-transcode

auto_transcode_mp3_bitrates spawns ephemeral MP3 transcoders for any non-MP3 source the moment it connects — handy when you publish Ogg/Opus but want MP3 fallbacks without declaring each one:

"auto_transcode_mp3_bitrates": [128, 64]

Output mounts are named <input>-mp3-<bitrate> and are not persisted to config — they live for the lifetime of the source.

Robustness notes

Transcoders are built to survive the messy reality of long-running upstreams:

  • Chained Ogg/Opus sources (RFC 3533 stream rotation between tracks) are decoded continuously by a pure-Go Ogg page reader that does not pin the bitstream serial; each BOS resets per-stream state and re-inits the decoder.
  • Source flaps (8–36 s gaps are routine for some sources) don't reap the output: the health monitor skips auto-removal for transcoded mounts, so the output stays at HTTP 200 across the gap. On resume, FlushAtHead snaps listeners to fresh encoder output instead of replaying stale buffered audio.
  • Per-cycle contexts ensure a source disconnect/reconnect doesn't leak goroutines in the retry loop.

These were hard-won fixes; the changelog documents the failure modes in detail (2.6.0 / 2.6.1).


Next: Streaming Sources · Playback and Output · AutoDJ

Clone this wiki locally