eCast pipe
Server pro příjem, distribuci, záznam a monitoring audio/video streamů s webovou správou. Obsahuje Icecast, MediaMTX, FFmpeg, Stream Analyzer a instalační průvodce CZ/EN.
Documentation and check-in manual
Releases
Older versions (30)
- 1.0.7 · 2026-10-08 · ZIP · JSON
- 1.0.6 · 2026-10-08 · ZIP · JSON
- 1.0.5 · 2026-10-08 · ZIP · JSON
- 1.0.4 · 2026-10-07 · ZIP · JSON
- 1.0.3 · 2026-10-07 · ZIP · JSON
- 1.0.2 · 2026-10-07 · ZIP · JSON
- 1.0.1 · 2026-10-03 · ZIP · JSON
- 1.0.0 · 2026-10-03 · ZIP · JSON
- 0.9.19 · 2026-10-03 · ZIP · JSON
- 0.9.18 · 2026-10-03 · ZIP · JSON
- 0.9.17 · 2026-10-03 · ZIP · JSON
- 0.9.16 · 2026-10-03 · ZIP · JSON
- 0.9.15 · 2026-10-02 · ZIP · JSON
- 0.9.14 · 2026-10-02 · ZIP · JSON
- 0.9.12 · 2026-10-02 · ZIP · JSON
- 0.9.11 · 2026-10-02 · ZIP · JSON
- 0.9.10 · 2026-10-02 · ZIP · JSON
- 0.9.9 · 2026-10-01 · ZIP · JSON
- 0.9.8 · 2026-09-10 · ZIP · JSON
- 0.9.7 · 2026-09-09 · ZIP · JSON
- 0.9.6 · 2026-09-09 · ZIP · JSON
- 0.9.5 · 2026-09-09 · ZIP · JSON
- 0.9.3 · 2026-09-09 · ZIP · JSON
- 0.9.2 · 2026-09-09 · ZIP · JSON
- 0.9.1 · 2026-09-09 · ZIP · JSON
- 0.9.0 · 2026-09-09 · ZIP · JSON
- 0.8.3 · 2026-09-08 · ZIP · JSON
- 0.8.2 · 2026-09-08 · ZIP · JSON
- 0.7.35 · 2026-05-16 · ZIP · JSON
- 0.2.1 · 2026-04-28 · ZIP · JSON
README
# eCast pipe 0.2.1 server MVP for Ubuntu 26.04 amd64
Program: eCast pipe 0.2.1
Author: PB
Web: estudium.eu
Email: info@estudium.eu
This package is a first manual-install MVP for a Ferncast-like audio/video pipe server.
It is intentionally structured so it can later be converted into Ansible templates and handlers.
## Features in this package
- Ubuntu 26.04 amd64 target.
- Nginx + PHP web admin.
- Web admin uses Nginx HTTP Basic Auth with a first user created during install.
- PAM is not used for the web admin. The installer asks for the first web username and password and stores it in `/etc/audiopipe/web.htpasswd`.
- Audio distribution via Icecast mountpoints, for example `/radio1`, `/radio2`.
- Video distribution via MediaMTX RTSP paths, for example `rtsp://server:8554/tv1`.
- Per-channel optional input/source password.
- Per-channel optional listener/viewer password.
- One or more recording profiles per channel.
- Recording profile options: output/source input, format, codecs, bitrates, segment length, retention days.
- Backup recording profile for same-time previous-day fallback.
- Audio silence detection through FFmpeg `silencedetect`.
- Video black-frame detection through FFmpeg `blackdetect` plus simple FPS check.
- fail2ban config.
- nftables firewall example with ICMP limit and public ports.
## Install
```bash
sudo unzip audiopipe-server-mvp-v7.zip -d /opt/src
cd /opt/src/audiopipe-server
sudo ./install.sh
```
The installer uses this online APT install path:
```bash
sudo apt update
sudo apt install -y --no-install-recommends nginx-full php-fpm php-cli php-mbstring php-xml php-curl icecast2 ffmpeg fail2ban nftables sudo curl ca-certificates jq uuid-runtime apache2-utils openssl python3 python3-yaml unzip chrony tzdata whiptail
```
The installer writes a detailed log to:
```text
/var/log/esact/install-latest.log
```
If installation fails, collect a debug bundle with:
```bash
sudo audiopipe-collect-debug
```
The command prints the generated .tar.gz file path. Send that archive together with `/var/log/esact/install-latest.log`. Secrets in copied configs are redacted by the collector.
If you need an offline bundle, run this on a matching Ubuntu 26.04 amd64 machine first:
```bash
sudo ./bin/download-packages.sh
zip -r audiopipe-server-offline.zip audiopipe-server
```
Then copy the offline zip to the target server and run `sudo ./install.sh`.
## Important default accounts/groups
- Web login: Nginx HTTP Basic Auth, first user created during install
- Time zone: Europe/Prague; time synchronization: chrony, config `/etc/chrony/conf.d/audiopipe.conf`
- Runtime user/group: `audiopipe:audiopipe`
- MediaMTX user: `mediamtx`
- Web server user: `www-data`, added to group `audiopipe` so it can update `/etc/audiopipe/config.json`.
The web UI no longer uses PAM. Log in with the web username and password created during installation.
## Main paths
- Main config: `/etc/audiopipe/config.json`
- Web app: `/opt/audiopipe/php-app/public`
- Rendered Icecast config: `/etc/icecast2/icecast.xml`
- Rendered MediaMTX config: `/etc/mediamtx/mediamtx.yml`
- Recordings: `/var/lib/audiopipe/recordings/<channel>/<recording>/<YYYYMMDD>/<HHMMSS>.<ext>`
- Logs: `/var/log/esact`
- Runtime state: `/run/audiopipe`
## Channel model
Each channel has:
- `recordings[]`: one or more recording profiles.
- `backup`: defines which recording is used for fallback.
- `input_auth`: optional password for source/publish input.
- `delivery.listener_auth`: optional password for listeners/viewers.
- `failure_detection`: silence/no-picture thresholds and switch/recovery timing.
See `docs/CHANNEL_SCHEMA.md` for details.
## Apply config
From the web UI click `Apply configuration`, or run:
```bash
sudo /usr/local/bin/audiopipe-apply
```
This renders Icecast and MediaMTX configs and restarts/enables per-channel systemd services.
## Services
For channel `radio1`:
```bash
systemctl status audiopipe-channel@radio1
systemctl status audiopipe-recorder@radio1
systemctl status audiopipe-monitor@radio1
journalctl -u audiopipe-channel@radio1 -f
```
## Firewall
The firewall file is copied to:
```text
/etc/nftables.conf.audiopipe
```
To apply it during install:
```bash
sudo ECAST_APPLY_FIREWALL=1 ./install.sh
```
Review it before applying on a remote server. It allows TCP 22, 80, 443, 8000 and 8554.
## Debug after failed install
Send these files if something fails:
```bash
sudo cat /var/log/esact/install-latest.log > /tmp/audiopipe-install-latest.log
sudo audiopipe-collect-debug
```
The debug command prints a path like `/tmp/audiopipe-debug-YYYYMMDD-HHMMSS.tar.gz`.
## Notes for production hardening
- Replace the generated self-signed HTTPS certificate with a trusted certificate before exposing the web admin publicly.
- Restrict SSH to trusted IPs or VPN if possible.
- Move secrets from JSON into root-only secret files before final Ansible conversion.
- Consider a queue/control daemon instead of direct sudo from PHP for larger deployments.
## v4-v5 note: web authentication and time synchronization
- v5 replaces PAM with Nginx HTTP Basic Auth because PAM was unreliable in this deployment.
- The old `/etc/audiopipe/web-admin-groups` group gate is no longer used.
- Chrony is installed, time zone is set to Europe/Prague, and time synchronization is configured. Check status with:
```bash
timedatectl status
chronyc tracking
chronyc sources -v
```
## v3 note: sudoers recovery
If v2 failed on `/etc/sudoers.d/audiopipe-web` because of the wildcard in
`audiopipe-channel@*.service`, use `docs/RECOVERY_FROM_V2.md` or install v3.
v3 replaces that direct `systemctl` sudo rule with `/usr/local/sbin/audiopipe-restart-channel`.
## v5 note: HTTPS, Prague time zone, and web authentication
- The installer sets the server time zone to `Europe/Prague` and enables chrony.
- The web admin is HTTPS-only. Port 80 redirects to HTTPS, except the local Icecast auth callback `/audiopipe-auth/icecast.php` from `127.0.0.1`.
- The installer asks for the public HTTPS hostname and generates a self-signed certificate in `/etc/audiopipe/tls/`.
- Browsers will show a warning until `/etc/audiopipe/tls/audiopipe.crt` and `/etc/audiopipe/tls/audiopipe.key` are replaced with a trusted certificate.
- PAM is not used for the web admin anymore. The installer asks for the first web username and password and stores a bcrypt hash in `/etc/audiopipe/web.htpasswd`.
- For unattended install, set `ECAST_PUBLIC_HOST`, `ECAST_WEB_USER`, and `ECAST_WEB_PASSWORD`.
Example unattended install:
```bash
ECAST_PUBLIC_HOST=web01.estudium.eu \
ECAST_WEB_USER=admin \
ECAST_WEB_PASSWORD='change-this-password' \
sudo ./install.sh
```
## v7 note: whiptail installer improvements
v7 keeps the `dialog` installer and adds:
- first screen language selection: `cz` or `en`,
- UTF-8 whiptail rendering with `NCURSES_NO_UTF8_ACS` unset to avoid broken q/x/m box drawing on SSH/browser terminals,
- compatibility table before installation: OS, architecture, kernel, CPU cores, RAM, free disk space, detected hostname and IP addresses,
- hostname prompt; the installer applies it through `hostnamectl set-hostname`,
- login + password + password confirmation on one screen,
- optional insertion of an SSH public key into `/root/.ssh/authorized_keys`, prefilled with the provided `ssh-ed25519` key,
- program branding: `eCast pipe` version `0.2.1`, author `PB`, web `estudium.eu`, email `info@estudium.eu`.
For SSH/non-interactive usage, environment-variable mode still works:
```bash
ECAST_INSTALL_LANG=cz \
ECAST_SYSTEM_HOSTNAME=web01.estudium.eu \
ECAST_PUBLIC_HOST=web01.estudium.eu \
ECAST_TIMEZONE=Europe/Prague \
ECAST_ENABLE_CHRONY=1 \
ECAST_WEB_USER=admin \
ECAST_WEB_PASSWORD='change-this-password' \
ECAST_SSH_PUBLIC_KEY='ssh-ed25519 AAAA... your-key-comment' \
ECAST_APPLY_FIREWALL=0 \
sudo ./install.sh
```
To force the non-TUI installer even from an interactive shell:
```bash
sudo ECAST_NO_TUI=1 ./install.sh
```
## v8 installer notes
The TUI installer uses UTF-8 box drawing by default for cleaner window borders. If an old SSH client shows broken borders, start it with:
```bash
ECAST_ASCII_LINES=1 sudo ./install.sh
```
The time zone selector includes large city presets such as Prague, New York, Los Angeles, London, Paris, Dubai, Tokyo, Singapore and Sydney, plus a custom IANA time zone option.
Whiptail rendering now uses safe ASCII whiptail-drawn borders by default. The progress screen is a whiptail gauge, not a custom Unicode renderer.
## Web UI layout v15
The PHP web UI is now split into local JSON data, static HTML/CSS/JS, and PHP API files:
```text
php-app/
api.php
bootstrap.php
icecast.php
index.php
data/
user.json
settings.json
channels.json
recordings.json
runtime.json
html/
index.html
style.css
app.js
logo.png
```
Nginx serves only `php-app/html` as the public web root. PHP files stay one level above the public root and are exposed only through exact FastCGI locations. The UI contains these menu sections: Panel, Kanál / pipe, Recordings and Nastavení. Language switching is CZ/EN with automatic browser-language default.
## v0.2 notes
- Installer TUI uses `whiptail` instead of `dialog`.
- Nginx is not fixed to one domain. It uses `server_name _` and accepts direct IP access or any domain that points to the server.
- The web UI stores language strings in `/opt/audiopipe/php-app/html/cz.ini` and `/opt/audiopipe/php-app/html/en.ini`.
- The PHP API has stricter JSON responses to make frontend errors easier to diagnose.
- HTML, CSS, JS and PHP ownership/permissions are set explicitly during install.
## v0.2.1 notes
- Fixes web API routing: Nginx FastCGI routes for `/api.php`, `/index.php`, and `/audiopipe-auth/icecast.php` now use `fastcgi_params` instead of `snippets/fastcgi-php.conf`, avoiding the `try_files` 404 problem.
- Whiptail progress now shows the current installation output line, including APT and service activity.
- Compatibility check uses a compact double-line table to avoid wrapped columns.
- Web UI language files are separate: `php-app/html/cz.ini` and `php-app/html/en.ini`. Installer reference language files are included as `installer/cz.ini` and `installer/en.ini`.