# Audio Ingest Rework ## Hinweis zum Stand (2026-04-07) Dieses Dokument beschreibt das Zielbild. Der aktuelle Ist-Stand in Phase 1 ist: - shared ingest runtime + unified source factory sind implementiert - `stdin`, `http-raw`, `icecast` Adapter sind implementiert - Icecast Decoder-Layer + ffmpeg fallback sind implementiert - native Decoder `mp3` / `oggvorbis` / `aac` sind noch Platzhalter - funktionaler Decode-Pfad heute: ffmpeg fallback ## Ziel `fm-rds-tx` soll mittelfristig mehrere Audio-Ingest-Pfade sauber unterstützen, ohne den bestehenden `ffmpeg`-Pfad kaputt zu machen. Die strategische Richtung ist daher **nicht** „ffmpeg sofort ersetzen“, sondern: - bestehenden `ffmpeg`-Pfad als universellen Fallback behalten - native Ingest-Familien daneben aufbauen - alle Pfade auf eine gemeinsame interne PCM-/Audio-Source-Abstraktion führen - neue native Pfade schrittweise produktionsreif machen ## Leitprinzipien 1. **Kein Big-Bang-Rewrite** – Bestehendes bleibt lauffähig. 2. **Native Pfade zuerst dort, wo sie klaren Mehrwert bringen**. 3. **Go-Libraries bevorzugen** – Decoder/Protocol-Handling einkaufen statt neu erfinden. 4. **Ein gemeinsames Ingest-Modell** – unabhängig von Quelle oder Protokoll. 5. **Control Plane / Runtime / Telemetrie von Decoder-Details trennen**. ## Zielbild: drei Ingest-Familien ### 1. FFmpeg Family Bestehender universeller Adapter. **Rolle:** - Fallback - Legacy-Kompatibilität - exotische oder seltene Formate - schneller pragmatischer Pfad für Quellen, die nativ noch nicht unterstützt werden **Wichtig:** - bleibt vorerst erhalten - wird nicht „rausoptimiert“, sondern architektonisch nachrangig - sollte in der Runtime als eigener Ingest-Typ sichtbar sein ### 2. AoIP Family Für professionelle / broadcast-nahe Audioquellen. **Ziel-Protokolle / Modi:** - RTP multicast - AES67-lite - SDP - SAP - später: NMOS IS-04 / IS-05 - später: SRT framed PCM **Basis:** - `aoiprxkit` **Rolle:** - deterministische LAN-Audiozuführung - Broadcast-/AoIP-Umgebungen - spätere professionelle Discovery/Activation ### 3. Streaming Family Für klassische Internet-/HTTP-/Radio-Streamingquellen. **Ziel-Protokolle / Modi:** - HTTP audio streams - Icecast / Shoutcast - ICY metadata - MP3 - AAC / HE-AAC (je nach verfügbarer Lib) - später ggf. Opus **Rolle:** - Webradio / Online-Streams - Metadatenübernahme - native Alternative zu `ffmpeg` für die häufigsten Streaming-Fälle **Wichtig:** Diese Familie sollte **nicht** in `aoiprxkit` gepresst werden. AoIP und Streaming sind konzeptionell verschieden genug, dass getrennte Package-Bereiche sinnvoll sind. ## Gemeinsame interne Abstraktion Alle Ingest-Familien sollen auf dieselbe interne PCM-Einspeisung münden. ### Ziel Unabhängig davon, ob Samples von: - `ffmpeg` - RTP/AES67 - Icecast/MP3 - SRT framed PCM kommen, soll der Rest der Sende-/RDS-/Runtime-Logik immer dieselbe Audioquelle sehen. ### Grobe Zielverantwortung Eine Quelle soll idealerweise liefern können: - PCM-Samples - Sample-Rate - Kanalzahl - Source-Label / Source-Type - Laufzeitstatus / Health - Basisstatistiken - optional Metadaten (z. B. ICY title) ### Wichtige Designregel **Decoder/Protocol-Layer** und **Sender-Runtime** nicht vermischen. Das Ingest-System soll: - Audio empfangen / decodieren / normieren - Health / Stats liefern - Audio in die bestehende Audio-Pipeline schieben Die Sender-Runtime soll: - Quellen starten/stoppen - aktive Quelle verwalten - Fehler/Fallback/Status darstellen - UI/Control-Plane bedienen ## Einordnung von `aoiprxkit` ## Was `aoiprxkit` heute schon gut abdeckt - RTP multicast RX - L24-Decoding - Jitter/Reorder - statische SDP-Auswertung - SAP-Listener - Stream-Finder per SDP `s=` Name - Basis-Stats - Live-Metering - NMOS-/SRT-Grundgerüst ## Was `aoiprxkit` heute noch nicht vollständig als Produkt ist - keine voll integrierte `fm-rds-tx`-Runtime-Anbindung - SRT-Pfad eher Scaffold als fertig produktionsreif - NMOS eher vorbereitend als vollständig integriert - noch kein gemeinsames Source-Management mit anderen Ingest-Familien ## Konsequenz `aoiprxkit` ist **integrationswürdig**, aber aktuell noch eher ein Modul/Baukasten als direktes Hauptsystem. ## Empfohlene Package-/Modul-Richtung in `fm-rds-tx` Dies ist ein Zielbild, kein harter Sofort-Umbau. ### Kandidaten - `internal/audioingest` - gemeinsame Interfaces / gemeinsame Typen / gemeinsame Runtime-Adapter - `internal/audioingest/ffmpeg` - bestehender ffmpeg-basierter Pfad - `internal/audioingest/aoip` - Adapter zwischen `aoiprxkit` und `fm-rds-tx` - `internal/audioingest/streaming` - HTTP/Icecast/Shoutcast/ICY + Decoder-Libs Optional später: - `internal/audioingest/shared` - Resampling, channel mapping, sample normalization, metadata structs ## Konfigurationszielbild Die Runtime sollte einen expliziten Ingest-Typ kennen. Beispielhaft: ```yaml input: kind: ffmpeg | aoip-rtp | aoip-sap | aoip-srt | stream-http ``` Später können pro Familie Unterstrukturen folgen. Beispielhaft: ```yaml input: kind: aoip-rtp aoip: multicastGroup: 239.69.0.1 port: 5004 payloadType: 97 sampleRateHz: 48000 channels: 2 ``` oder ```yaml input: kind: stream-http streaming: url: https://example.org/live.mp3 icyMeta: true ``` ## Runtime-Zielbild Die Runtime sollte Quellen einheitlich behandeln können: - initialisieren - starten - stoppen - Status abfragen - Health/Stats lesen - Audio in denselben bestehenden Ringbuffer / Audio-Input-Pfad drücken ## Telemetrie / UI Die Control Plane sollte mittelfristig ingest-bezogen sichtbar machen: - aktiver Ingest-Typ - Source-Label - Transport / Codec / Sample-Rate / Channels - Fehlerzustand - Puffer-/Jitter-/Underrun-relevante Daten - optional Metadata (z. B. StreamTitle) Wichtig ist hier eine Trennung zwischen: - **Audio ingest health** - **TX/runtime health** ## Empfohlene Umsetzungsreihenfolge ### Phase 1 – Architektur sauberziehen - gemeinsames Ingest-Zielbild festziehen - bestehende Audio-Input-Andockpunkte in `fm-rds-tx` dokumentieren - entscheiden, welche internen Interfaces nötig sind ### Phase 2 – AoIP MVP - `aoiprxkit` nicht blind verschieben, sondern zuerst als Adapter anbinden - erster nativer Ingest-Modus: statischer RTP/AES67-lite Pfad - PCM-Frames in bestehende Audio-Pipeline einspeisen - Runtime-/Health-/Status sichtbar machen ### Phase 3 – SDP / SAP Discovery - statische SDP-Unterstützung - optional SAP Listener + Session-Auswahl - Discovery klar von Audio-Transport trennen ### Phase 4 – Streaming MVP - neuer nativer HTTP/Icecast/Shoutcast-Pfad - bewährte Go-Libs für Decoder und ICY nutzen - erstes Ziel: häufige Webradio-Fälle ohne `ffmpeg` ### Phase 5 – Vereinheitlichung / Telemetrie - gemeinsame Ingest-Stats - gemeinsame Statusmodelle - UI/Control-Plane-Integration - Quellwechsel / Fehlermeldungen / Health States ### Phase 6 – Erweiterte Pfade - SRT sauber produktionsfähig machen - NMOS weiter integrieren - später ggf. Opus / weitere Streaming-Codecs ## Was explizit vermieden werden soll - `ffmpeg` sofort herausreissen - AoIP und Web-Streaming in denselben unscharfen Package-Topf werfen - Decoder / Demux / Protocol-Layer unnötig selbst neu bauen - Discovery-Logik eng mit der PCM-Pipeline verheiraten - UI bauen, bevor Runtime-Modelle sauber stehen ## Erste konkrete Bauschritte ab jetzt 1. bestehenden Audio-Input-Pfad in `fm-rds-tx` analysieren 2. kleinste gemeinsame Ingest-Abstraktion definieren 3. `aoiprxkit`-RTP als ersten nativen Adapter integrieren 4. danach Streaming-Familie planen und anbinden ## Kurzfazit `ffmpeg` bleibt vorerst als nützlicher Universalpfad erhalten. Die Zukunft liegt aber in zwei nativen Familien: - **AoIP** für professionelle/broadcast-nahe Zuführung - **Streaming** für HTTP/Icecast/Shoutcast/ICY + Standardcodecs Beide sollen sauber über eine gemeinsame interne Audio-Ingest-Schicht in `fm-rds-tx` zusammenlaufen.