Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
stream-recorder
Generischer Stream-Recorder für RTMP, HLS, HTTP-Audio und weitere Formate — mit Web-UI und Docker
🏰 Website · 📰 Community · 🐘 Mastodon · 💬 Support
Funktionen
- Web-Interface — Jobs planen, Aufnahmen steuern und verlängern im Browser
- Docker-basiert — Ein Container, läuft auf ARM und x86/x64
- Mehrere Stream-Typen — RTMP, RTMPS, HLS (m3u8), MP3, AAC, OGG, FLAC und HTTP-Streams
- Aufnahmen verlängern — Laufende Aufnahmen spontan verlängern oder auf unbegrenzt setzen
- Zeitplanung — Automatische Aufnahmezeiten direkt im Web-UI konfigurieren
- Segment-Splitting — Lange Aufnahmen automatisch in Teile zerlegen
- Auto-Reconnect — Automatische Wiederverbindung bei Verbindungsabbrüchen
- Schnellaufnahme — URL eingeben, sofort aufnehmen
- NTFY-Benachrichtigungen — Push-Nachrichten bei Start, Stop, Fehler und Upload (pro Job schaltbar)
- Plik-Upload — Aufnahmen automatisch hochladen, optional danach löschen (pro Job schaltbar)
- Metadata-Monitor — Automatische Show-Erkennung via Stream-Metadaten (Plugin)
- REST-API — Alle Funktionen auch per API steuerbar
Schnellstart
# Repository klonen
git clone https://git.techniverse.net/scriptos/stream-recorder.git
cd stream-recorder
# Container starten
docker compose up -d
Das Web-UI ist unter http://localhost:8484 erreichbar. Die Konfiguration wird beim ersten Start automatisch in data/config.yml erstellt.
Beim ersten Start ist die Anmeldung aktiv: Benutzer admin, das zufällig erzeugte Passwort steht einmalig im Container-Log:
docker logs stream-recorder
Das Passwort kann danach unter Einstellungen geändert werden.
Container Image
Release-Images werden automatisch in der Gitea Container Registry veröffentlicht:
docker pull git.techniverse.net/scriptos/stream-recorder:latest
docker pull git.techniverse.net/scriptos/stream-recorder:v3.0.0
Dev-Images entstehen bei Pushes auf main oder dev:
docker pull git.techniverse.net/scriptos/stream-recorder:dev-latest
Docker Compose
services:
stream-recorder:
image: git.techniverse.net/scriptos/stream-recorder:latest
container_name: stream-recorder
restart: unless-stopped
ports:
- "127.0.0.1:8484:8484"
volumes:
- ./data:/app/data
environment:
TZ: Europe/Berlin
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETUID
- SETGID
Der Port ist standardmäßig nur auf 127.0.0.1 gebunden. Für Zugriff von außen einen Reverse-Proxy (mit TLS) davorschalten oder gezielt an eine IP binden, z.B. eine Tailscale-IP ("100.64.0.10:8484:8484").
Umgebungsvariablen
| Variable | Standard | Beschreibung |
|---|---|---|
TZ |
— | Zeitzone (z.B. Europe/Berlin) |
PUID / PGID |
1000 |
UID/GID, unter der die Anwendung im Container läuft |
RECORDING_ROOTS |
/app/data/recordings:/recordings |
Erlaubte Basisverzeichnisse für download_path (durch : getrennt) |
LOG_RETENTION_DAYS |
90 |
Log-Einträge älter als X Tage werden gelöscht |
ENABLE_API_DOCS |
— | 1 aktiviert die Swagger-UI unter /docs |
Daten
Alle persistenten Daten liegen in einem einzigen Volume (./data):
| Pfad | Beschreibung |
|---|---|
data/config.yml |
Konfiguration (wird beim ersten Start automatisch erstellt, Rechte 600) |
data/stream-recorder.db |
SQLite-Datenbank |
data/recordings/ |
Aufnahmen (pro Job ein Unterordner) |
Sicherheit
- Anmeldung — Basic Auth ist bei Neuinstallationen aktiv. Passwörter werden als PBKDF2-Hash gespeichert. Nach 10 fehlgeschlagenen Logins innerhalb von 5 Minuten wird die IP für den Rest des Zeitfensters gesperrt (HTTP 429).
- Secrets — Passwort, NTFY-Token und Plik-API-Key werden von der API nie zurückgegeben.
- Kein Root — Der Container startet als root, passt die Besitzrechte von
data/an und startet die Anwendung dann alsPUID/PGID(Standard1000). Der Anwendungscode ist für diesen User schreibgeschützt. - Eingaben — Stream-URLs nur per
http(s),rtmp(s)undrtsp(s); ffmpeg läuft mit Protokoll-Whitelist. Extra ffmpeg-Argumente unterliegen einer Allowlist (siehe Jobs).download_pathmuss innerhalb vonRECORDING_ROOTSliegen. - Web — Kein CORS; schreibende Cross-Site-Requests werden abgewiesen (403). Security-Header und CSP sind gesetzt. Die Swagger-UI (
/docs) ist standardmäßig deaktiviert. - Netzwerk — Den Port nicht ungeschützt ins Internet stellen; Reverse-Proxy mit TLS oder VPN verwenden.
Upgrade bestehender Installationen
- Besitzrechte — Beim Start werden
data/und die Verzeichnisse ausRECORDING_ROOTSautomatisch aufPUID:PGIDumgestellt (nur Dateien mit abweichendem Besitzer). Soll ein anderer Host-User Besitzer sein,PUID/PGIDsetzen. - Anmeldung — Die bisherige Auth-Einstellung bleibt erhalten. Ein Klartext-Passwort in
config.ymlwird beim Start automatisch in einen Hash umgewandelt. - Secrets rotieren — Ältere Versionen haben NTFY-Token und Plik-API-Key über
/api/configausgeliefert. War die Instanz für andere erreichbar, diese Secrets erneuern. - Port-Bindung — Die mitgelieferte
docker-compose.ymlbindet nur noch an127.0.0.1. Bei Bedarf anpassen (siehe oben). - download_path — Liegt ein eigener Aufnahmepfad außerhalb von
/app/data/recordingsund/recordings, muss er inRECORDING_ROOTSaufgenommen werden. - Extra ffmpeg-Argumente — Bestehende Jobs mit nicht erlaubten Argumenten müssen angepasst werden.
- Laufende Aufnahmen — Aufnahmen, die beim Neustart liefen, werden als Fehler „Abgebrochen durch Neustart" markiert.
Multi-Arch Build
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t stream-recorder:latest .
Dokumentation
| Thema | Beschreibung |
|---|---|
| Jobs | Jobs erstellen, Zeitplanung, Schnellaufnahme |
| Aufnahmen | Verlängern, Stoppen, Reconnect, Segment-Splitting |
| Plugins | NTFY, Plik-Upload, Metadata-Monitor |
| Konfiguration | config.yml, alle Parameter |
| API | REST-API Endpunkte |
© Patrick Asmus · Techniverse Network · Lizenz
