Skip to content

Commit 3192470

Browse files
author
Datanoise
committed
Docs: Add ARCHITECTURE.md
1 parent 54cb091 commit 3192470

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

ARCHITECTURE.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# TinyIce Architecture & Technical Documentation
2+
3+
> **For AI Agents & LLMs:** This document is your primary source of truth for understanding the system's design philosophy, concurrency models, and architectural boundaries. Read this before suggesting large-scale refactors.
4+
5+
## 1. Project Vision
6+
**TinyIce** is a modern, standalone audio streaming server compatible with the Icecast protocol.
7+
* **Goal:** Provide a "single binary" radio station solution (Server + AutoDJ + Transcoder + SSL).
8+
* **Philosophy:** Minimal external dependencies (Pure Go preferred), zero-allocation broadcasting paths, and high concurrency.
9+
* **Aesthetic:** Professional, dark-mode "Cyberpunk/Studio" interfaces using vanilla HTML/CSS/JS (no heavy frontend frameworks).
10+
11+
## 2. Core Subsystems
12+
13+
### A. The Relay Engine (`relay/`)
14+
The heart of TinyIce is the **Relay**. It manages the lifecycle of streams (`relay/stream.go`) and listeners.
15+
* **Circular Buffers:** Every stream uses a fixed-size `CircularBuffer` (`relay/relay.go`). This allows new listeners to receive an "instant burst" of audio to fill their client-side buffers immediately, minimizing startup latency.
16+
* **Concurrency:**
17+
* **Global Lock:** `Relay` uses a `sync.RWMutex` to manage the map of streams.
18+
* **Stream Lock:** Each `Stream` has its own `sync.RWMutex` to protect metadata and listener maps.
19+
* **Atomic Stats:** Bandwidth (`BytesIn`, `BytesOut`) is tracked via `sync/atomic` for performance.
20+
21+
### B. AutoDJ & Streamer (`relay/streamer.go`)
22+
The **Streamer** is an internal audio source that behaves like an external source client.
23+
* **Decoding:** Uses `hajimehoshi/go-mp3` for decoding.
24+
* **Encoding:** Uses a custom native implementation (`relay/transcode.go`) to re-encode audio into chunks suitable for streaming (MP3/Opus).
25+
* **Pacing:** Crucial. The streamer must manually pace itself (sleep) to match the playback duration of the audio frames, otherwise, it would flood the buffer.
26+
* **Metadata:** ID3 tags are extracted using `bogem/id3v2` (pure Go) in a non-blocking background goroutine (`fetchTitleAndCache`) to prevent UI stalls.
27+
28+
### C. Networking & Security (`server/socket_*.go`)
29+
* **Dual Stack:** Binds to both IPv4 and IPv6.
30+
* **Hot Swap (`SO_REUSEPORT`):** Allows a new process to bind to the *same* port while the old one is still running. The old process hands off duties and shuts down gracefully (`server/server.go` -> `HotSwap()`).
31+
* **TCP Banning:** We implement a `BannedListener` wrapper that drops connections from banned IPs at the `Accept()` level, before any TLS or HTTP overhead is incurred.
32+
33+
### D. Web Interface (`server/templates/`)
34+
* **Technology:** Server-Side Rendered (SSR) Go templates + Vanilla JS.
35+
* **Real-time:** Uses **Server-Sent Events (SSE)** (`/admin/events`) to push JSON state updates (listeners, current song, VU meters) to the frontend.
36+
* **Studio UI:** A specific focus on "app-like" behavior using AJAX forms (`submitForm`) to avoid full page reloads during broadcast operations.
37+
* **Go Live Studio:** Enables direct browser-to-server streaming using WebAudio API.
38+
* **WebRTC Mode:** Uses `pion/webrtc` for ultra-low latency Opus streaming.
39+
* **HTTP Fallback:** Uses `MediaRecorder` to stream chunks via POST requests.
40+
41+
## 3. Directory Structure
42+
43+
```text
44+
tinyice/
45+
├── main.go # Entry point. Flags, config loading, and Updater initialization.
46+
├── config/ # JSON configuration struct and defaults.
47+
├── relay/ # AUDIO CORE.
48+
│ ├── relay.go # CircularBuffer and Stream structs.
49+
│ ├── streamer.go # AutoDJ logic (playlist, queue, playback loop).
50+
│ ├── transcode.go # Native MP3/Opus encoding logic.
51+
│ ├── mpd.go # Minimal implementation of MPD protocol.
52+
│ ├── webrtc.go # WebRTC PeerConnection and Source management.
53+
│ └── client.go # Logic for pulling external relay streams.
54+
├── server/ # HTTP/TCP LAYER.
55+
│ ├── server.go # Routes, handlers, auth, middleware.
56+
│ ├── socket_*.go # OS-specific socket syscalls (SO_REUSEPORT).
57+
│ └── templates/ # HTML/CSS/JS assets.
58+
└── updater/ # Self-update mechanism (GitHub Releases).
59+
```
60+
61+
## 4. Key Data Flows
62+
63+
### A. AutoDJ Playback
64+
1. `StreamerManager` selects a file from `Playlist` or `Queue`.
65+
2. File is decoded to PCM.
66+
3. Transcoder (`EncodeMP3`/`EncodeOpus`) converts PCM to streaming chunks.
67+
4. Chunks are written to the `Stream.Buffer`.
68+
5. `Stream.Broadcast` signals all waiting Listener goroutines via channels.
69+
70+
### B. WebRTC Source (Go Live)
71+
1. Browser captures microphone via `getUserMedia`.
72+
2. Opus packets are sent via WebRTC `TrackRemote`.
73+
3. `WebRTCManager` receives RTP packets and uses `oggwriter` to mux them into Ogg pages.
74+
4. The resulting Ogg data is written directly to the `Stream.Buffer` for distribution.
75+
76+
### C. Listener Connection
77+
1. `handleListener` (`server/server.go`) accepts HTTP request.
78+
2. `Stream.Subscribe` registers the listener and returns a buffer offset (rewound by `burst_size`).
79+
3. The listener loop reads from the `CircularBuffer` starting at that offset.
80+
4. Loop waits on a signal channel for new data to arrive.
81+
82+
## 5. Future Roadmap & Missing Features
83+
84+
If you are an AI agent looking to contribute, focus on these areas:
85+
86+
### High Priority (functionality)
87+
1. **Scheduler:** The AutoDJ needs a time-based scheduler (e.g., "Play 'Jazz' playlist every Friday at 8 PM").
88+
2. **Jingles/Sweepers:** A mechanism to inject short audio files (station IDs) between tracks or every $N$ songs.
89+
3. **Live Mic Injection:** Integrate `pion/webrtc` more deeply to allow "Go Live" directly from the browser (WebRTC -> Opus -> Internal Buffer mix).
90+
4. **S3/MinIO Support:** Allow the AutoDJ to stream files directly from object storage instead of the local filesystem (cloud-native scaling).
91+
92+
### Medium Priority (UX/Polish)
93+
1. **Visualizer:** A server-side or client-side FFT visualizer in the Studio.
94+
2. **Request System:** A public-facing widget where listeners can request songs from the library (with rate limiting).
95+
3. **OIDC/OAuth:** Support for logging in via GitHub/Google/OIDC instead of just Basic Auth/Cookies.
96+
97+
### Architecture Improvements
98+
1. **HLS/DASH Support:** Currently only supports progressive HTTP (Icecast). Adding HLS would improve mobile compatibility.
99+
2. **Clustering:** Allow multiple TinyIce nodes to share state/streams (Relay-chaining is already supported, but shared state is not).

0 commit comments

Comments
 (0)