{
    "schema": "eupdate-package-specification-v1",
    "author": "PB <pavel.bartos.pb@gmail.com>",
    "project_id": "dbad8351151b6fd5",
    "software_id": "ecast-pipe-server",
    "software": "eCast pipe",
    "module": null,
    "release_id": "f8d76d73440a554be625d9a3c5a7b845",
    "version": "1.0.2",
    "release_date": "2026-10-07",
    "published_at": "2026-10-07T04:51:45+00:00",
    "bytes": 2106970,
    "sha256": "f16f0ac0e4a0d08fa291819ff91dcd96a5228e7a816aeaa65b23b50658fad5cf",
    "file_count": 310,
    "languages": {
        "JavaScript": {
            "bytes": 1358229,
            "files": 21
        },
        "Python": {
            "bytes": 372022,
            "files": 38
        },
        "PHP": {
            "bytes": 298234,
            "files": 12
        },
        "CSS": {
            "bytes": 152289,
            "files": 5
        },
        "Shell": {
            "bytes": 80824,
            "files": 5
        },
        "HTML": {
            "bytes": 13620,
            "files": 1
        }
    },
    "installation_url": "https://update.estudium.eu/package.php?software_id=ecast-pipe-server&version=1.0.2",
    "update_url": "https://update.estudium.eu/package.php?software_id=ecast-pipe-server",
    "install_json": {
        "software": "eCast pipe",
        "software_id": "ecast-pipe-server",
        "version": "1.0.2",
        "release_date": "2026-10-07",
        "author": {
            "name": "PB",
            "email": "info@estudium.eu",
            "website": "https://www.estudium.eu"
        },
        "project": {
            "website": "https://www.estudium.eu"
        },
        "homepage": "https://www.estudium.eu",
        "description": {
            "cs": "Webové přihlášení a levé menu podle eWebu 0.8.43, animované trojúhelníky, relace a ochrana přístupu k API/clusteru.",
            "en": "Web sign-in and sidebar ported from eWeb 0.8.43, animated triangles, sessions and API/cluster access protection."
        },
        "package": {
            "type": "release",
            "target": "software"
        },
        "compatibility": {
            "os_types": [
                "linux"
            ],
            "distributions": [
                {
                    "id": "ubuntu",
                    "name": "Ubuntu",
                    "versions": [
                        "24.04",
                        "26.04"
                    ]
                }
            ],
            "distribution_ids": [
                "ubuntu"
            ],
            "os_versions": [
                "24.04",
                "26.04"
            ],
            "any_linux_distribution": false,
            "architectures": [
                "amd64"
            ],
            "native_windows_supported": false,
            "native_macos_supported": false
        },
        "installation": {
            "commands": {
                "linux": {
                    "supported": true,
                    "mode": "automatic",
                    "command": "bash ./setup.sh"
                },
                "windows": {
                    "supported": false,
                    "mode": "unsupported",
                    "command": null
                },
                "macos": {
                    "supported": false,
                    "mode": "unsupported",
                    "command": null
                },
                "other": {
                    "command": null,
                    "supported": false,
                    "mode": "unsupported"
                },
                "source": {
                    "command": null,
                    "supported": false,
                    "mode": "unsupported"
                }
            },
            "requires_root": true,
            "requires_internet": true,
            "interactive": true,
            "fresh_install_command": "sudo bash ./setup.sh --install",
            "update_command": "sudo bash ./setup.sh --update",
            "verify_command": "bash ./setup.sh --check",
            "web_root": "."
        },
        "documentation": {
            "readme": "readme.md",
            "installation": "docs/INSTALL_EUPDATE.md",
            "changelog": "CHANGELOG.md",
            "diagnostics": "docs/DIAGNOSTICS.md",
            "password_reset": "docs/RESET_PASSWORD.md",
            "audit": "docs/VALIDATION_1.0.2.md",
            "release_notes": "docs/RELEASE_1.0.2.md",
            "security": "docs/SECURITY.md",
            "checkin": "docs/CHECKIN_0.9.1.md",
            "validation": "docs/VALIDATION_1.0.2.md",
            "eweb_monitoring": "docs/EWEB_LOG_SENDER.md",
            "cluster": "docs/CLUSTER_CONFIG.md",
            "audio": "docs/DAB_READY.md"
        },
        "archive_metadata": {
            "working_directory": "ecast-pipe-server",
            "publisher": "dcf6d41fbcdf0e16",
            "updated_at": "2026-10-07T04:51:45+00:00",
            "application_author": "PB <pavel.bartos.pb@gmail.com>"
        },
        "checkin": {
            "enabled_by_default": true,
            "endpoint": "https://update.estudium.eu/check/",
            "schema": "ecast-checkin-v1",
            "software_id": "ecast-pipe-server",
            "authentication_header": "X-eCast-API-Key",
            "interval_seconds": 604800,
            "events": [
                "install",
                "update",
                "weekly",
                "manual",
                "license"
            ],
            "systemd_timer": "ecast-checkin.timer",
            "calendar": "Mon *-*-* 03:00:00",
            "command": "sudo /usr/local/sbin/ecast-checkin --force"
        },
        "requirements": [],
        "modules": {
            "bundled": false,
            "catalog": "https://update.estudium.eu/updates.php?software_id=ecast-pipe-server",
            "minimum_core_version": "0.9.1",
            "license_check_timer": "ecast-license-check.timer",
            "license_check_interval_seconds": 900,
            "automatic_uninstall_on_revocation": true
        },
        "license": "MIT",
        "license_custom": ""
    },
    "readme": "# eCast 1.0.2 — 2026-10-07\n\nPřihlašovací stránka a levé menu převzaté z eWebu 0.8.43, včetně animovaných\ntrojúhelníků se zlatým impulzem. Stejná uživatelská jména a hesla; přihlášení\npřes formulář, skutečné odhlášení a ochrana relace. Skupiny menu zachovávají\nfunkce eCastu a aktivní moduly. Moduly se instalují samostatně.\n\n[Vydání a aktualizace](docs/RELEASE_1.0.2.md) · [Ověření](docs/VALIDATION_1.0.2.md)\n\n# eCast 1.0.1 — 2026-10-03\n\nUbuntu/Netplan: instalátor nastavuje odesílání skutečného hostname Linuxu\npřes existující DHCPv4/DHCPv6 klienty (networkd i NetworkManager). Nastavení\nnejprve ověří a uloží odděleně; aktivujte je přes SSH pomocí `sudo netplan try`\nnebo při plánovaném restartu. Síť se při této konfiguraci sama nerestartuje.\nModuly se nemění.\n\n[Vydání a aktivace](docs/RELEASE_1.0.1.md) · [Ověření](docs/VALIDATION_1.0.1.md)\n\n# eCast 1.0.0 — 2026-10-03\n\nCluster nabízí **Smazat všechna spojení** včetně zneplatnění starých klíčů.\n**Play** se v seznamu nahrávek neláme uprostřed slova. JSON se skladbami\nzapisuje každý song na vlastní řádek a zachovává tento formát i po přepisu\nřeči. Opraveny jsou nepřesné délky AAC/MP3 a dočasná ztráta zápisových práv\npři aktualizaci. Externí stream 1.3.0 a Stream Analyzer 1.6.0 se nemění.\n\n[Vydání a postup](docs/RELEASE_1.0.0.md) · [Ověření](docs/VALIDATION_1.0.0.md)\n\n# eCast 0.9.19 — 2026-10-03\n\nExterní audio relay má v modulu **Externí stream 1.3.0** oba odkazy: HTTP\ni HTTPS. Přímo pod názvem externího streamu se zobrazuje **Právě hraje**\ns automatickou obnovou. Stejný údaj je také v **Overview u každé pipe**,\npodle jejího skutečně poslouchaného výstupu, včetně aktivního fallbacku.\n\nNejprve aktualizujte jádro, potom samostatný modul Externí stream 1.3.0.\nStream Analyzer 1.6.0 zůstává kompatibilní.\n[Vydání a postup](docs/RELEASE_0.9.19.md) · [Ověření](docs/VALIDATION_0.9.19.md)\n\n# eCast 0.9.18 — 2026-10-03\n\nOprava přibližně 12sekundového předbíhání názvů skladeb za DAB procesorem:\nmetadata se předávají až na odpovídající pozici výstupního audia.\n**Stáhnout + JSON (ZIP)** přibalí k nahrávce seznam skladeb a dostupný\nJSON analyzátoru včetně přepisu řeči. Platí také pro výběr a celý den.\n\nStream Analyzer 1.6.0 zůstává kompatibilní a není nutné ho měnit.\n[Vydání a postup](docs/RELEASE_0.9.18.md) · [Ověření](docs/VALIDATION_0.9.18.md)\n\n# eCast 0.9.17 — 2026-10-03\n\nSpráva modelů v samostatném Stream Analyzeru 1.6.0 a oprava předbíhání\nnázvů skladeb při nahrávání vlastní pipe. Časy ICY se přiřazují podle\nzvukových rámců, nikoli podle opožděného výstupního progressu FFmpegu.\n\nNejdříve aktualizujte jádro, potom modul 1.6.0. Chybějící INA runtime\nnainstalujete v modulu přes **Správa modelů → INA → Nainstalovat / opravit**.\n[Vydání a postup](docs/RELEASE_0.9.17.md) · [Ověření](docs/VALIDATION_0.9.17.md)\n\n# eCast 0.9.16 — 2026-10-03\n\nOprava aktualizace končící kódem 132 při pádu TensorFlow: izolovaný test\nnativního modelu, kontrola CPU, skutečný stav přepisu v GUI a pokračování\ninstalace jádra. Opraven také výběr virtuálního prostředí Pythonu.\n\nStream Analyzer 1.5.0 zůstává kompatibilní.\n[Vydání a diagnostika](docs/RELEASE_0.9.16.md) · [Ověření](docs/VALIDATION_0.9.16.md)\n\n# eCast 0.9.15 — 2026-10-02\n\nPodpora samostatného modulu Stream Analyzer 1.5.0: výběr složek nahrávek,\nautomatický přepis české a anglické řeči do JSON se skladbami z Icecastu,\nprůběžná fronta a zachování pozastavených analyzérů při migraci.\n\nInstalujte nejdříve toto jádro, potom modul 1.5.0.\n[Vydání](docs/RELEASE_0.9.15.md) · [Ověření](docs/VALIDATION_0.9.15.md)\n\n# eCast 0.9.14 — 2026-10-02\n\nOprava oprávnění Python runtime při aktualizaci z GUI. Nově instalované\nknihovny analyzátoru jsou dostupné účtu `ecast` před kontrolou modelu.\n\n[Vydání a obnova aktualizace](docs/RELEASE_0.9.14.md) · [Ověření](docs/VALIDATION_0.9.14.md)\n\n# eCast 0.9.13 — 2026-10-02\n\nNázvy nahrávek používají hostname Linuxu. A/V procesor předává názvy skladeb\npřes hranici FFmpeg filtrů. Analyzátor přepisuje modelem rozpoznanou řeč v češtině\na angličtině do stejného `.nowplaying.json` jako skladby, s časovými značkami.\n\n[Vydání, nastavení přepisu](docs/RELEASE_0.9.13.md) · [Ověření](docs/VALIDATION_0.9.13.md)\n\n# eCast 0.9.12 — 2026-10-02\n\nRelay i nahrávání externích streamů přebírají názvy skladeb přímo z ICY metadat.\nU přehrávače záznamu se zobrazuje předchozí, aktuální a následující skladba\ns možností přeskočit na její začátek.\n\n[Vydání a aktualizace](docs/RELEASE_0.9.12.md) · [Ověření](docs/VALIDATION_0.9.12.md)\n\n# eCast 0.9.11 — 2026-10-02\n\nOprava pádu mixéru při připojení CH4: společné časování všech HTTP vstupů\nv běžném i nouzovém režimu. Oprava převodu PCM do FFmpeg filtrů DAB procesoru.\n\n[Vydání a aktualizace](docs/RELEASE_0.9.11.md) · [Ověření](docs/VALIDATION_0.9.11.md)\n\n# eCast 0.9.10 — 2026-10-02\n\nNázvy recordings `hostname_YYYY-MM-DD_HHMM_intervalh.ext`, přebírání fallbacku od masteru\npro sdílené pipe a opravené ukládání/nastavení DAB Ready v A/V Processor 0.3.7.\nPodrobnosti: [vydání 0.9.10](docs/RELEASE_0.9.10.md), [audio](docs/DAB_READY.md), [ověření](docs/VALIDATION_0.9.10.md).\n\n# eCast 0.9.9\n\nVšesměrná synchronizace nastavení A/V procesorů a fallbacků včetně jejich souborů.\nPipe se sdílejí jen se zaškrtnutou volbou **Clustering**. Nahrávky dostávají\nčasovaný JSON právě hraných skladeb z Icecastu; fallback jej automaticky přehrává.\n\n[Instalace a změny](docs/RELEASE_0.9.9.md) ·\n[Pravidla clusteru a metadat](docs/CLUSTER_CONFIG.md) ·\n[Ověření a omezení](docs/VALIDATION_0.9.9.md)\n\nAktualizujte všechny uzly. Pro editor a test přenesených fallback nahrávek\nje dodáván samostatný aktualizovaný modul **FallBack 1.2.7**. Core a moduly\nse nadále instalují odděleně; platná licence modulu je nadále vyžadována.\n\n---\n\n# eCast 0.9.8\n\nŽivé stavy source/fallback v clusteru bez intervalového dotazování protistran.\nKaždý den ve 03:00 se změří síťová odezva původních zdrojů a určí pořadí\nserverů: 1 = master, další = slave. Pořadí samo nepřesouvá vysílání.\n\n[Instalace a změny](docs/RELEASE_0.9.8.md) ·\n[Cluster, měření a řešení potíží](docs/CLUSTER_EVENTS.md) ·\n[Ověření a limity](docs/VALIDATION_0.9.8.md) ·\n[Reset hesla](docs/RESET_PASSWORD.md)\n\nCore-only package. Existing paid module ZIPs from the 0.9.4 collection remain\ncompatible and install separately. Upgrade all cluster nodes to 0.9.8 for event\ntransport and daily source RTT ranking. The new event service keeps SSE clients\noutside PHP-FPM. Network RTT is not end-to-end audio latency.\n\n# eCast 0.9.6\n\nOprava pádu SNMP na výchozí adrese `udp:161`, který se mohl zobrazovat při\ncheck-inu jako chyba místní aplikace konfigurace. Obsahuje také opravu ZIPu\nz 0.9.5 a všechny předchozí úpravy GUI a monitoringu. Moduly se nemění.\n\n[Instalace a změny](docs/RELEASE_0.9.6.md) ·\n[Ověření a limity](docs/VALIDATION_0.9.6.md) ·\n[eWeb monitoring](docs/EWEB_LOG_SENDER.md)\n\nCore 0.9.6 fixes SNMP default listen parsing and the associated local\nconfiguration failure during the check-in license workflow.\n\n---\n\n# eCast 0.9.5\n\nOprava aktualizace končící `Unverified release file` při přechodu na 0.9.4.\nNový ZIP lze ověřit i původním aktualizátorem 0.9.3. Obsahuje všechny úpravy\nGUI a integraci eWeb z 0.9.4. Moduly jsou stejné jako v kolekci 0.9.4.\n\n[Postup aktualizace a vysvětlení opravy](docs/RELEASE_0.9.5.md) ·\n[Ověření](docs/VALIDATION_0.9.5.md) ·\n[eWeb log sender a SNMP](docs/EWEB_LOG_SENDER.md) ·\n[Reset hesla v Bashi](docs/RESET_PASSWORD.md)\n\nCore 0.9.5 fixes the invalid 0.9.4 release ZIP and keeps complete checksum\nverification. Update directly from 0.9.3; existing 0.9.4 module packages remain\ncompatible. See the English section in the release notes.\n\n---\n\n# eCast 0.9.4\n\nČerné nadpisy, nové ovládání a boxy přehledu pipe, přepracované šablony všech\ndevíti modulů a HTTPS log sender/SNMP pro eWeb Log Analyzer.\n\nAktualizujte nejprve jádro a pak moduly: [Vydání 0.9.4](docs/RELEASE_0.9.4.md).\nPřipojení monitoringu: [eWeb Log sender a SNMP](docs/EWEB_LOG_SENDER.md).\n[Ověření a omezení](docs/VALIDATION_0.9.4.md).\n\n---\n\n# eCast pipe 0.9.3\n\nPB · info@estudium.eu · https://www.estudium.eu\n\n## Verze 0.9.3 – stabilita, licence a údržba systému\n\nOprava zaseknutého Icecastu po reloadu, chyby DSP afade a startu MediaMTX.\nČitelnější GUI, grafy využití úložiště přes GrafJS, automatická kontrola\nlicencí modulů a inventář balíčků v check-inu. V Nastavení lze zapnout\nplánované APT aktualizace. Clusterové klíče mají nový seskupený formát.\n\n**[Instalace a změny 0.9.3](docs/RELEASE_0.9.3.md)** ·\n**[Rozbor diagnostiky](docs/AUDIT_0.9.3.md)** ·\n**[Ověření](docs/VALIDATION_0.9.3.md)** ·\n**[Reset hesla z Bashe](docs/RESET_PASSWORD.md)**\n\nCore 0.9.3 fixes Icecast reload hangs, DSP fade types and MediaMTX startup;\nit adds license enforcement, system package reporting, storage charts and\nopt-in daily APT updates. Existing pairing/check-in credentials are preserved\nwhile cluster keys migrate to the grouped eCast format. See the English\nsection in the release notes. Optional modules remain separate paid packages.\n\n## Verze 0.9.2 – opravy podle provozní diagnostiky\n\nOpravené ukončování streamovacích služeb, dočasné soubory monitoru,\nindex nahrávek na pozadí, omezení paměti pomocných úloh a PHP výstupů.\nDoplněna diagnostika OOM a kompatibilita čtení klientů Icecast 2.5.\n\n**[Instalace 0.9.2](docs/RELEASE_0.9.2.md)** ·\n**[Rozbor logu a ověření oprav](docs/AUDIT_0.9.2.md)**\n\nCore 0.9.2 fixes shutdown loops, missing temporary files, blocking recording\nindexing and unbounded helper output. Optional module packages are unchanged;\nexisting modules and settings are preserved. See the release notes below.\n\n## Verze 0.9.1\n\nJádro bez modulů + **devět samostatných placených modulů** pro eUpdate.\nNový firewall/IPS, rozbalovací menu, hromadné aktualizace modulů, ruční\ncheck-in a reporting nahrávek/disku/klientů. Opraven DAB zvukový profil,\nclusterová synchronizace a ověřování hesla API. Existující moduly se zachovají.\n\n**[Instalace, změny a limity 0.9.1](docs/RELEASE_0.9.1.md)** ·\n[Firewall a IPS](docs/SECURITY.md) · [Check-in](docs/CHECKIN_0.9.1.md)\n\nCore 0.9.1 ships without optional modules. Upload each paid module ZIP\nseparately to eUpdate. Update core first, then AV Processor 0.3.5 / IPS 1.0.0.\n\n## Diagnostika a stabilita GUI\n\nDiagnostický balíček se vytváří na pozadí, takže jeho sběr a komprimace\nnečekají uvnitř PHP požadavku. Opraveno neomezené kopírování a načítání logů,\nsouběžné status dotazy a příliš dlouhé automatické kontroly clusterových uzlů.\nDoplněna historie zatížení, PHP-FPM, restartů a kapacity pro hledání příčin\nobčasných výpadků. Historie je dostupná až od instalace sběrače (0.8.3+).\n\nGrafy používají přiložený **GrafJS 1.3.9**, který je součástí ZIPu. V Diag\nje nová historie CPU/RAM/disku a odezvy/chyb PHP za 24 hodin, 7 a 30 dnů.\n\nNávody:\n\n- [Diagnostika, limity sběru a historie provozu](docs/DIAGNOSTICS.md)\n- [Reset hesla do GUI přes Bash / SSH](docs/RESET_PASSWORD.md)\n- [Instalace a aktualizace z eUpdate](docs/INSTALL_EUPDATE.md)\n- [Audit a ověření 0.9.1](docs/AUDIT_0.9.1.md)\n- [Check-in po instalaci, aktualizaci a každý týden](docs/Warning.md)\n\n## Instalace / aktualizace\n\nNahrajte celý ZIP jako nové vydání **0.9.7** projektu `ecast-pipe-server`\nv eUpdate a použijte nově vygenerovaný instalační příkaz. Příkaz s pevným\nID staršího vydání dál stahuje starší balíček.\n\nPo ručním rozbalení:\n\n```bash\ncd ecast-pipe-server\nbash ./setup.sh --check\nsudo bash ./setup.sh\n```\n\nNa existujícím serveru se obnoví uložené instalační preference a zachová\nsoubor webových hesel. Týdenní check-in a opravy mixéru z 0.8.2 jsou zachované.\nPo aktualizaci obnovte stránku GUI, aby se načetly nové skripty a GrafJS.\n\n## Rychlá diagnostika bez GUI\n\n```bash\nsudo ecast-collect-debug /tmp\n```\n\nArchiv se pojmenuje podle hostname a času. Podrobné volby, limity a příkazy\npro kontrolu úlohy jsou v `docs/DIAGNOSTICS.md`.\n\n## Historie vydání\n\nNásledující záznamy popisují starší verze; aktuální chování určuje návod 0.9.2.\n\n## v0.8.2 eUpdate installation and readme paths\n\n- Restored the missing setup.sh entry point, package verification and required documentation.\n- Moved install.json next to the scripts; declared the exact lowercase readme.md name.\n- The installer deploys readme.md and a legacy README.md copy; the web API accepts both names.\n- Restored update preference/password preservation and header-only eUpdate check-in authentication.\n- Added explicit install/update/weekly reports, a persistent weekly calendar and bounded service retries.\n- Retained the mixer functionality introduced in 0.8.0 and 0.8.1.\n\nThe following sections preserve the previous release history.\n\n## v0.8.1 Live mixer control and per-input monitoring\n\n- Main package bumped to `0.8.1`.\n- Mixer gain badges now call the new live gain API and can update Liquidsoap gain without restarting the pipe when the live control socket is available.\n- Mixer inputs MAIN/CH1-CH4 now expose copy buttons, connection state, silence/playing state and measured dB levels in the pipe table.\n- ecast-monitor writes per-input mixer state to `/run/ecast/<pipe>.mixer-inputs.json`; ecast-service merges it into status-json.\n- Safety limiter remains active even when no audio profile is selected, so mixer-only pipes still get output protection.\n- Fallback audio silence checks for mixer pipes are evaluated against the final public mixed output, not a single raw input.\n\n## v0.8.0 Multi-input audio mixer for pipe distribution\n\n- Main package bumped to `0.8.0`.\n- Audio pipes can enable a new Liquidsoap mixer with one MAIN input and up to 4 default optional channel inputs. Without an audio processor the generated input mount is `/__mix_<pipe>` plus `/__mix_<pipe>_ch1` through `_ch4`; with an audio processor the generated input mount remains `/__procesor_<pipe>` plus `_ch1` through `_ch4`.\n- Optional mixer inputs are not required for the pipe to run. The monitor treats the live source as healthy when at least one mixer input is connected; fallback/silence routing is based on the mixed public output.\n- The panel now shows all mixer input mounts separately with connection status and per-input gain badges such as `-4 dB`. Clicking a gain badge saves the new gain value for that input.\n- The mixer includes a safety limiter by default to reduce clipping risk when several source encoders are active at the same time.\n\n## v0.7.34 Check-in receiver confirmation and /check slash retry\n\n- Main package bumped to `0.7.34`.\n- Initial and daily check-in now counts as successful only when the receiver confirms storage, for example with `stored`, `accepted`, `queued`, `received` or `received_at`. A plain informational `{ok:true, service:...}` response no longer hides a non-stored POST.\n- The check-in client retries the endpoint with a trailing slash when the configured address is `https://update.estudium.eu/check`. This fixes deployments where `/check` is a directory and the web server redirects POST `/check` to GET `/check/`, causing the receiver to display help but not store the payload.\n- `checkin-state.json` now records `last_attempts`, `last_endpoint_used`, `last_final_url`, response preview and the precise storage/HTTP error.\n- Added a deployable receiver example in `tools/update-check-receiver/index.php`.\n\n## v0.7.24 FallBack silence routing, Liquidsoap-only audio processor and two-way transition fades\n\n- Main package bumped to `0.7.24`.\n- Fixed the processed-audio silence case where `/__procesor_*` stays connected but silent: fallback mode now stops the stale live publisher and publishes the selected fallback recording directly to the public mount, so silence can no longer mask `/__fallback_*`.\n- The same fallback scheme applies with and without the audio processor: monitor checks the live input, stops/removes the outgoing public source, then the channel worker attaches the fallback recording with fade-in.\n- Returning from fallback to live requests a fallback fade-out before live resumes. The fade-out concat is regenerated at transition time, so wallclock fallback files fade from the current programme position.\n- Liquidsoap script generation no longer emits FFmpeg filter options with wrong Liquidsoap types for bass/equalizer width settings.\n- Icecast URL auth allow responses now return a plain KVA-compatible body as well as the auth header, avoiding fallback/listener auth failures on Icecast versions that parse the response body.\n- Audio-only Icecast processing is Liquidsoap-only. If Liquidsoap is unavailable or the generated script fails validation, eCast logs an error and retries Liquidsoap instead of silently using FFmpeg as an audio-processor fallback. Video pipes still use FFmpeg for video processing.\n\n## v0.7.22 FallBack processor silence routing and transition fade\n\n- Main package bumped to `0.7.22`.\n- Fixed FallBack playback when an audio processor input `/__procesor_*` remains connected but silent: the monitor disconnects the stale public output source so Icecast can fall through to `/__fallback_*` instead of serving processed silence.\n- The same monitor scheme is used for audio pipes with and without processor: live input is checked separately from the continuously prepared fallback publisher.\n- New live/fallback eCast publishers start with an approximately 2 s fade-in. Entering fallback asks the fallback publisher to restart, so the fallback file begins with a smooth ramp.\n- Processed-mode fallback no longer permanently moves clients to the internal fallback mount; listeners remain logically on the public mount so Icecast fallback-override can return them to live after recovery.\n\n## v0.7.21 FallBack archive save/search and check-in endpoint\n\n- Main package bumped to `0.7.21`.\n- FallBack presets can now be saved when the audio file is selected from the recordings archive dropdown even if PHP-FPM cannot `realpath()` the recording; the safe relative archive reference is preserved and resolved by the eCast runtime.\n- Archive dropdowns in the FallBack editor now have an interactive search field above them; typing filters the dropdown by pipe, profile, date or filename.\n- Weekly FallBack archive references are resolved against the configured recordings root when generating the fallback playlist.\n- Daily status check-in now posts to `https://update.estudium.eu/check`.\n- FallBack module bumped to `1.2.4`.\n\n## v0.7.20 HW Output ALSA fallback, faster FallBack editor and inactive scope without source\n\n- Main package bumped to `0.7.20`.\n- HW Output audio test now prefers ALSA playback PCM devices (`plughw:card,device`) and retries safe fallbacks for older `hw:0` configs before reporting the full per-target error.\n- Live HW audio output also normalizes legacy `hw:N` / `hw:N,D` targets to `plughw:N,0` / `plughw:N,D`.\n- FallBack module no longer indexes the recordings archive during the normal list/add path. The editor opens immediately and loads archive choices lazily; saving remains settings-only and does not restart/apply services.\n- Pipe audio scope is inactive and clears its history when the pipe has no connected source, so a disconnected pipe no longer keeps or synthesizes the previous waveform.\n- HW Output module bumped to `1.1.3`; FallBack module bumped to `1.2.3`.\n\n## v0.7.19 HW Output test actions and files cleanup\n\n- Main package bumped to `0.7.19`.\n- Left sidebar menu is widened by roughly 10%.\n- HW Output detected devices are listed one per row and each device offers a type-aware test action: AES67 test data, audio test tone, or SDI test picture with beep-beep audio.\n- Files view no longer shows the default `Analýza JSON` help/table block; analysis results are shown only after clicking an analysis action.\n- HW Output module bumped to `1.1.2`; Recording Files module bumped to `1.1.1`.\n\n## v0.7.18 UI compacting and daily eCast check-in\n\n- Main package bumped to `0.7.18`.\n- Logo in the left top card is 20% larger.\n- Recordings tables are more compact and their Edit/Delete buttons now use the same mini button size as Externi stream.\n- Panel \"Posledni akce\" is reduced again: smaller spacing/fonts and only the last 2 actions are shown.\n- Settings / Cluster no longer displays local/peer API URL rows in the visible UI. Hidden form fields are kept for compatibility.\n- Added `docs/Warning.md` describing the daily operational check-in.\n- Added `/usr/local/sbin/ecast-checkin` plus `ecast-checkin.service`/`ecast-checkin.timer` for a sanitized daily POST to `https://update.estudium.eu/check`.\n- Added separate receiver example `check-estudium-receiver.php` outside the eCast ZIP; it stores only the last 10 check-ins per eCast ID.\n- Recordings module bumped to `1.1.2`.\n\n## v0.7.17 Audio pipe Icecast/recordings hotfix\n\n- Fixed audio pipe publishing when `dab-radio-optimal` A/V processing is enabled: `dynaudnorm` AGC gain is now a valid integer with minimum `3`, so Liquidsoap/FFmpeg no longer fail before publishing the Icecast mount.\n- Existing `dab-radio-optimal` profiles from A/V Processor module `<0.3.3` are migrated from invalid `max_gain=2.5` to `max_gain=3`.\n- A/V Processor module bumped to `0.3.3`; main package bumped to `0.7.17`.\n- The panel status now distinguishes `waiting_output` so a pipe with input connected but missing public Icecast output is no longer shown as fully running.\n\n## v0.7.17 Update TUI, DAB processor reserve and compact panel\n\n- Main package version bumped to `0.7.17` and update.sh now shows both installed and package version in the TUI.\n- update.sh prefers the bundled progress UI from the unpacked package, so it does not show an older installed progress UI version during update.\n- install.sh now uses checksum rsync and deletes stale files inside bundled core module folders, so PHP/HTML/JS/CSS assets are reliably replaced during update.\n- Core frontend assets are cache-busted with `?v=0.7.17` to avoid old app.js/style.css in the web GUI after update.\n- A/V Processor `dab-radio-optimal` default now uses target -19 LUFS, true peak -1.2 dBTP, limiter limit 0.87, softer AGC and gentler compression. A/V Processor module version is `0.3.3`.\n- Pipe overview audioscope values are rendered strictly below the graph, alert/action panels are about half-height, and the sidebar logo is about 15% larger.\n\n## v0.7.17 Sjednocení verzí v TUI a HTML\n\n- Main package version is propagated consistently to VERSION, PHP bootstrap, bundled settings, HTML fallback header, installer TUI/progress UI and install/update metadata.\n- Fallback module config now reports matching version/module_version `1.2.2`.\n\n## v0.7.9 Stabilizace akcí, diagnostika, validace a instalační preference\n\n- Added central action manager for start/stop/restart/apply with per-action ID, step timings and command logs.\n- Added diagnostic bundle download, self-test helper and action-status visibility in Diag.\n- Added config validation before apply, derived audio health metrics and additional A/V processor presets.\n- Installer writes data/installation.json and update.sh can reuse original install preferences for quick updates.\n\n## v0.7.7 FallBack 7×24h, safer audio processor defaults and external stream defaults\n\n- FallBack editor is now organized into pipe-style cards and supports weekly 7×24h audio fallback files. When enabled, eCast selects the current weekday 1–7 and starts playback at the current time-of-day offset.\n- FallBack save validates that all seven weekday files exist and are long enough for a 24h/day fallback source.\n- DAB radio audio processor default preset is updated to **music/talk ready**: less aggressive gain, denoising disabled by default, softer compression and safer true peak target to avoid choppy or raspy speech.\n- Bundled external stream examples are now disabled by default, including their Icecast relay, so a new install does not start sample radio channels automatically.\n- Apply/start/stop/restart command log now records per-command `elapsed_ms`, making it easier to identify the command that causes a 2–3 minute apply/reset delay.\n- Module versions: FallBack `1.2.0`, A/V Processor `0.3.0`, Externí stream `1.2.1`.\n\n## v0.7.5 Diag command log, compact menu and RTMP port setting\n\n- Fixed Diag / Log command launch log loading by repairing the diag-json command log reader and making it follow the configured log directory with `/var/log/ecast` fallback.\n- Left menu is more compact and the visible UI brand under the logo is shortened to `eCast`.\n- Settings / System now includes configurable RTMP port. The compiled MediaMTX config writes `rtmpAddress` from this setting.\n\n## v0.7.4 Form cleanup, diagnostic launch log and compact pipe URLs\n\n- Přehledněji uspořádané formuláře Nastavení / Security, A/V Processor editace a Soubory. Dlouhé bloky jsou rozdělené do karet, s čitelnějšími popisky, lepším gridem a stabilnějším responzivním rozvržením.\n- Diag / Přehled má upravené karty pipe: vstup a výstup jsou v oddělených řádcích, dlouhé mounty/URL se lámou uvnitř karty a výstupní URL je menší, aby se texty nepřekrývaly.\n- Pipe overview má kompaktnější výpis URL ve sloupci Výstup.\n- Přidán přepisovaný `/var/log/ecast/command-launch.log`. Každý start/stop/restart pipe nebo apply config log přepíše a následně do něj zapisuje přesné systemctl/ffmpeg/liquidsoap příkazy pro pipe, recordery, externí stream relay/recording a backend reloady.\n- Diag / Log zobrazuje nový blok „Start/Stop/Restart/Apply command log“.\n- Verze modulů: Diag `1.0.3`, A/V Processor `0.2.9`, Soubory `1.0.2`.\n\n## v0.7.1 HW Output picker and classic pipe Stop behavior\n\n- Pipe editor now refreshes and uses the shared HW Output list after edits in the HW Output module, so newly created outputs appear in Add/Edit pipe without a full page reload.\n- Audio pipes can select audio card/AES outputs. Video pipes can select SDI outputs and audio-only outputs; audio-only outputs on a video pipe publish only the audio stream.\n- A HW Output can be assigned to only one pipe. Already-used outputs are shown as occupied in the picker and the backend rejects conflicting saves.\n- Pipe Start/Stop/Restart were returned to the pre-0.6.16 blocking behavior: `systemctl enable/disable --now` is run per unit and the API returns fresh live status. This is slower, but avoids the UI staying at “pipe se zastavuje”.\n- HW Output module version is now `1.1.1`.\n\n## v0.7.0 HW Output routing, installer packages and firewall hardening\n\n- Audio/video pipe editor can select existing enabled **HW Output** entries matching the pipe type. Audio pipes can use audio card and AES/AES67 outputs; video pipes can use SDI outputs.\n- The compiled config stores selected HW output IDs and resolved output rows per pipe so `ecast-channel` can publish the normal network stream and the selected physical output in one FFmpeg command.\n- The Output module is renamed in the UI to **HW Output** and its module version is now `1.1.0`.\n- The installer now installs runtime packages used by HW Output detection/output: ALSA/Pulse tools, AES67 timing/network helpers and SDI detection utilities.\n- Default nftables rules now include RTMP 1935 and RTSP 8554, drop invalid/suspicious TCP packets, rate-limit SSH separately and keep generous limits for Icecast/HTTP/HTTPS/RTMP/RTSP traffic.\n\n## v0.6.19 Pipe stop reliability fix\n\n- Pipe Start/Stop/Restart now waits for the pipe systemd units themselves instead of only enqueueing jobs. Backend Icecast/MediaMTX reloads still run in the background.\n- Stop disables and stops channel, recorder and monitor units in one call, waits briefly for them to become inactive, and force-kills stubborn unit processes if needed.\n- Stop also tries to disconnect stale Icecast sources for the public, processor and fallback mounts, so a stopped audio pipe is not immediately detected as running again from an old source connection.\n- Live status now respects desired state `stopped`: if a source is still visible during shutdown, the UI shows `stopping` instead of resurrecting the pipe as `running`.\n\n## v0.6.18 External stream protocols and Output module\n\n- Externí stream accepts and displays `http://`, `https://`, `rtmp://`, `rtmps://` and `rtsp://` URLs. HTTP(S) playlist resolving remains enabled; RTMP/RTSP are passed directly to FFmpeg.\n- External stream recorder and relay now add reconnect options only for HTTP(S) inputs and use TCP transport for RTSP inputs.\n- Added a new core **Output** module backed by `php-app/data/output.json`. It can define outputs for audio cards, SDI cards and AES/AES67 over LAN.\n- The Output module detects ALSA/Pulse/PipeWire audio sinks, DeckLink/SDI candidates and usable LAN interfaces, then offers them in dropdowns. AES/AES67 entries store LAN interface, destination IP and 1-10 ms latency; output kind is assigned automatically as audio/video from the selected type.\n\n## v0.6.17 Diagnostics layout cleanup\n\n- Diag / Přehled, Linux, Log and Balancing now use bounded responsive grids so cards, terminals, long URLs/PIDs and filter tables do not overlap.\n- Diag terminals are scrollable inside their cards and long code/log strings wrap safely where appropriate.\n- Balancing cards now keep labels, state pills, legends and SVG charts inside the card on narrow displays.\n\n## v0.6.16 Fast pipe start/stop\n\n- Pipe Start/Stop/Restart from the web UI now queues systemd jobs asynchronously instead of waiting for every unit and backend reload to finish.\n- The UI marks the pipe as starting/stopping immediately and refreshes status in the background.\n- Channel, recorder and monitor units now have a shorter stop timeout to avoid long waits when FFmpeg/Liquidsoap/network I/O hangs during shutdown.\n\n## v0.6.15 Compact cluster settings and About docs install fix\n\n- Nastavení / Cluster: blok **Stav HW** u spárovaných serverů je zmenšený přibližně na polovinu šířky/výšky původního zobrazení, aby karta nepůsobila rozpadle.\n- Nastavení / Cluster: blok **Práva** je převedený do čitelné tabulky se sloupci **Poskytne** a **Přijme** a řádky `stav`, `pipe`, `recordings`, `soubory` a `sync recordings`.\n- Instalátor nově kopíruje `./docs/*.md` do `/opt/ecast/docs/` vedle `/opt/ecast/README.md`, takže menu **O programu** po instalaci zobrazí i tlačítka pro dokumenty z `docs/`.\n\n## v0.6.14 Cluster layout, richer cluster pipe overview and docs browser\n\n- Nastavení / Cluster už nepoužívá širokou neuspořádanou tabulku. Spárované servery jsou v přehledných kartách: identita/API, HW stav, práva a akce.\n- Panel **Cluster pipe přehled** má stejné hlavní sloupce jako lokální **Pipe přehled**: ID, typ/klienti, název, input, output, VU/traffic, waveform náhled a funkce.\n- Cluster pairing posílá a ukládá callback/origin API URL původního serveru. Odchozí čekající párování se také refreshuje, takže panel umí zobrazit pipe stav i v situaci, kdy potvrzovací callback z protistrany selhal nebo byl blokovaný.\n- Menu **O programu** nově načte seznam `./docs/*.md` a zobrazuje je tlačítky vedle README.md.\n\n## v0.6.13 Cluster UI, auto refresh and no-restart pipe save\n\n- Cluster paired servers table was reorganized into compact server/info/status/permissions/action columns.\n- Cluster peers are refreshed over API every 10 seconds on the panel/cluster view so remote pipe status appears automatically.\n- Remote eCast monitoring now uses small CPU/RAM/DISK/LAN cards with mini graphs instead of plain text.\n- Saving a pipe now only writes/syncs configuration and does not restart services; first run must be started manually with the Start button.\n\n## v0.6.13 Cluster pairing diagnostics and API gateway auth\n\n- Pairing now probes the remote server before sending a request and shows a table with remote eCast ID, type, version, IP/URL, Cluster API state and uptime.\n- Remote API errors now include the URL, HTTP status, content type and a short response preview so HTML login pages, reverse-proxy redirects, missing `/api.php`, invalid API key and PHP errors are distinguishable.\n- `/api.php` can be reached by paired nodes without Nginx BasicAuth, but PHP protects web-admin actions itself and keeps sensitive cluster endpoints behind the Cluster API key.\n\n## v0.6.13 Cluster pairing form fix\n\n- Fixed Cluster pairing form so the browser submits the remote eCast ID and API key correctly.\n- Pairing still requires only remote eCast ID + remote API key; remote API URL is derived automatically as `https://<eCast ID>/api.php`.\n- Added client-side validation before sending the pairing request and server-side compatibility aliases for older field names.\n\n## v0.6.13 Random Cluster/API key on install\n\nFresh installations now generate a unique random local Cluster/API key during `install.sh`. The package no longer ships a reusable default key in `php-app/data/cluster.json`. Updates preserve an existing key so already paired cluster nodes are not disconnected.\n\n## v0.6.13 Panel uptime display\n\n- Uptime is now shown inline with CPU in the monitoring panel as `CPU (UP hh:mm)` for the local server and paired cluster peers.\n- The separate `UP` meter/card was removed to keep the monitoring display compact.\n\n## v0.6.13 Cluster pairing, state API and recordings sync\n\n### 0.6.13 Cluster pairing\n- Cluster tab now supports two-step pairing by eCast ID + API key.\n- A pairing request is visible on the remote node with the peer ID, URL and peer API key; the remote side must explicitly approve it.\n- Paired nodes can query each other's HW status, pipe state, fallback/in-stream state, external streams and recordings summary through authenticated Cluster API calls.\n- Paired nodes expose recordings through the Cluster API and can pull/synchronize missing or changed recordings from a selected peer.\n\n## v0.5.22 Stream Analyzer Stage 3 + Files viewer fix\n\n### 0.5.22 Stream Analyzer segmentation\n\n- Stage 1 FFmpeg fallback now splits long non-silence blocks into bounded windows, so the Files JSON analysis viewer shows clickable time jumps instead of one 15-minute block.\n- New limits: `segmentation_window_seconds` and `max_segment_seconds`.\n- When Whisper Stage 2 is enabled, bounded ambiguous music windows can be reclassified as speech if Whisper returns a real transcript.\n- Partial sidecar JSONs from 0.5.20 or older are reprocessed once per completed batch to replace coarse segments.\n\n\n- Stream Analyzer Stage 3 no longer uses only the beginning of a long music block. It now tries several bounded AcoustID probes inside each music segment (middle, early part, regular stride, and end) and stores every attempt in `segment.track.attempts`, so long radio blocks with jingles/reklamy/fades are much more likely to be identified.\n- New Stage 3 limits: `music_probe_count` (default 5) and `music_probe_stride_seconds` (default 180). The Stream Analyzer UI exposes these under **Identifikace hudby**.\n- The Files index now detects new/changed sidecar analysis JSON files immediately by tracking analysis JSON mtime, so the **Analýza JSON** button appears after analyzer writes the file.\n- `.json` analysis files are also listed as first-class analysis entries in Soubory / Files. Clicking **Zobrazit analýzu** opens the right panel with clickable time segments and audio playback for the linked recording.\n- Stream Analyzer still processes long recordings in resumable batches instead of trying to finish the whole file in one worker/web-triggered execution. Each analysis JSON contains `batching.total_batches`, `completed_batches`, `next_batch`, and per-batch details; the next run continues with batch 2, 3, ... automatically.\n- `ecast-service analyzer-run` and analyzer restart start systemd jobs asynchronously, so the web UI does not wait for a long analyzer run and hit PHP/HTTP execution time.\n\n## v0.5.18 Whisper CLI + model TUI fix\n\n\n- The installer TUI now includes a dedicated **Whisper CLI** step. When enabled it clones and builds `ggml-org/whisper.cpp`, installs the resulting binary to `/usr/local/bin/whisper-cli`, validates it with `--help`, and writes that binary path into Stream Analyzer config when possible.\n- Selecting a Whisper model in TUI automatically keeps the Whisper CLI install enabled, so Stage 2 is not left with `/opt/ecast/models/whisper/ggml-*.bin` but no `/usr/local/bin/whisper-cli`.\n- Online installs add the needed build packages when Whisper CLI/model is selected: `git`, `cmake`, `build-essential`, and `pkg-config`.\n- Fixed the installer TUI Whisper model step so selecting `small` downloads and validates `/opt/ecast/models/whisper/ggml-small.bin` from the exact Hugging Face resolve URL `https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin`.\n- The installer now validates Whisper model downloads by expected minimum size and rejects empty/HTML/error responses instead of silently continuing without a model.\n- If a model is selected in TUI and cannot be downloaded or saved, installation stops with a clear log message instead of pretending the optional step succeeded.\n- The TUI now shows the exact target path for each model size and carries the exact download URL into the installer engine.\n\n## v0.5.15 Stream Analyzer UI and Files analysis viewer\n\n- Built-in **Stream Analyzer** module is now versioned as module v1.2.5 on the 0.5.15 runtime stack. It supports multiple source-specific analyzers: each analyzer can be added only for a pipe/external stream with audio recording enabled, has its own `ecast-stream-analyzer@<id>` service/timer, can be started/stopped/restarted independently, and saving analyzer configuration no longer restarts jobs automatically.\n- The **Soubory / Files** module now opens analysis sidecar `.json` files in a right-side panel. Analysis segments are shown as clickable time ranges; clicking a segment seeks the audio player to that range and stops at the segment end.\n- The Stream Analyzer panel explicitly shows module version v1.2.5 and includes visible `+ Přidat analyzer` buttons in both the header and empty-state view.\n- Fixed module initialization in the Stream Analyzer panel so the module no longer crashes with `this.esc is not a function` when the loader calls its render function without object binding.\n- Stream Analyzer Stage 3 now clearly distinguishes the AcoustID **application API key** used as the lookup `client` from the personal/user key used for submissions. The config stores it as `providers.acoustid.client_key` while still accepting the older `api_key` field. It also uses compressed AcoustID POST requests, correctly form-encodes the `meta` flags, validates the key format before lookup, preserves the HTTP error body in JSON, and stops repeated AcoustID requests for the rest of the file after a fatal rejected request.\n- The Stream Analyzer edit form is reorganized into logical UX sections: source, schedule, analysis stages, segmentation, speech-to-text, music identification, and final configuration check.\n\n- Backup is now also shipped as a protected core module in `php-app/module/backup`, so it appears in the module-driven sidebar and uses the same module API mechanism as other panels.\n- The backup workflow remains compatible with the Settings / Backup tab and still excludes audio/video recordings and `files-rec.json`.\n- Module installation now hardens third-party ZIP imports: uploaded modules cannot mark themselves as core/protected, target directory creation is checked, `compatible=ecast` is accepted alongside the legacy `compatabile=ecast`, and packaged Python bytecode caches are excluded from new release ZIPs.\n\n## v0.5.8 fast recording preset save\n\n- Saving or deleting recording presets no longer runs a full configuration apply and no longer restarts/reloads stream services from the web request.\n- The web API only synchronizes `/etc/ecast/config.json` so a manual restart of the affected recorder/service can pick up the new preset when the operator is ready.\n- The Recordings UI refreshes locally after save/delete instead of doing a full dashboard reload.\n\n## v0.5.7 installer TUI hard fallback fix\n\n- The installer no longer exits with `Installation cancelled.` when the whiptail/newt TUI fails before installation starts.\n- A diagnostic line is written immediately to `/tmp/ecast-installer-tui.log`.\n- If the TUI cannot continue after repeated step failures, the installer automatically switches to a safe plain terminal prompt mode and then runs the normal installer engine without the progress TUI.\n\n# eCast pipe server MVP\n\n## v0.5.6 installer TUI robustness fix\n\n- The installer TUI compatibility and welcome information screens are non-aborting informational screens. Pressing OK continues even on terminals where whiptail/newt incorrectly returns a non-zero status after `--msgbox`.\n- Configuration steps no longer use `whiptail --extra-button`, which is unreliable across some Ubuntu/newt builds and could abort immediately after compatibility OK.\n- Validation message boxes no longer abort the installer if the terminal returns a non-zero status after OK.\n- The first web user still uses one login/password/repeat-password form when `dialog` is available. If `dialog` is missing or mixedform fails, the installer automatically falls back to standard whiptail input/password screens instead of cancelling.\n- The TUI writes a small diagnostic trace to `/tmp/ecast-installer-tui.log`.\n\n## v0.5.4 installer TUI compatibility OK screen\n\n- The TUI compatibility check is now an OK-only information screen instead of a Yes/No confirmation. This avoids aborting the interactive installer on terminals where the initial yes/no dialog returns an unexpected cancel code.\n\n## v0.5.3 installer fix for Ubuntu 26.04 and TUI navigation\n\n- `php-opcache` is no longer a hard APT dependency. On Ubuntu releases where that package has no install candidate, the installer now continues and treats OPcache as optional.\n- The installer still tries to install an available OPcache package variant, such as `phpX.Y-opcache`, after PHP is installed, but failure of this optional package no longer aborts installation.\n- The interactive installer now has a **Back / Zpet** button on the individual configuration steps.\n- The first web user form now contains **login**, **password**, and **repeat password** in one form.\n\n## v0.5.2 PHP-FPM performance and External stream cleanup\n\n- Instalační skript nově spouští `ecast-tune-php`, který nastaví eCast performance profil pro PHP-FPM a PHP CLI: OPcache, realpath cache, větší upload limity, kratší socket timeouty a omezení dlouhých PHP requestů.\n- `ecast-tune-php` upraví PHP-FPM pool na dynamičtější režim s více workery, zapne slowlog do `/var/log/ecast/php-fpm-slow.log` a dá se spustit i samostatně po instalaci.\n- Nginx konfigurace pro PHP dostala explicitní FastCGI timeouty a buffery, aby se UI nezasekávalo čekáním na pomalý PHP-FPM backend.\n- PHP API už neposílá JSON prettified ve výchozím režimu, čímž se zmenší odpovědi a zrychlí dashboard. Pro ladění lze vrátit odsazený JSON přes proměnnou `ECAST_JSON_PRETTY=1`.\n- `app_bootstrap()` už při každém API dotazu nepřepisuje JSON data beze změny. Sníží se tím diskové I/O a blokování souborových locků.\n- `status-json` zůstává cachovaný pro časté dotazy dashboardu, takže při pomalejším systemd/Icecast stavu UI nespotřebuje všechny PHP-FPM workery.\n- Výchozí seznam **Externí stream** je zmenšen jen na **Evropa 2** a **Krokodýl**; oba mají připravený aktivní lokální relay mount `/ext_evropa-2` a `/ext_krokodyl`.\n\n## v0.4.22 files module label and relay links\n\n- Modul pro prohlížení nahraných souborů se v menu i titulku stránky zobrazuje jednoduše jako **Soubory** / **Files**.\n- Modul **Externí stream** u zapnutého Icecast relay vypisuje celé klikatelné adresy lokálního relay streamu, například `http://HOST:8000/ext_evropa-2`, a také HTTPS relay variantu.\n\n## v0.4.21 recordings files module and External stream module\n\n- `Soubory` is a separate built-in module for browsing recorded files instead of a tab inside `Recordings`.\n- The file browser keeps the top submenu with one button per pipe or external stream, labelled for example `Testovací rádio (radio1)` or `Evropa 2 (evropa-2)`.\n- The `Recordings` module now contains only recording profile settings.\n- Reworked the previous external recording UI into **Externí stream**. Its configuration file is `php-app/data/ext_stream.json`.\n- Each external stream has a URL, a checkbox list of recording profiles, and an optional Icecast relay switch with local mount.\n- External stream recordings are stored under `<recording_root>/<external_stream_id>/<recording>/<YYYYMMDD>/<HHMMSS.ext>`.\n- The compiled config still exposes `stream_recordings` as a compatibility alias for existing worker commands.\n\n\n## v0.4.19 live signalling and silence fallback fix\n\n- `ecast-service status-json` now treats the monitor mode file as authoritative for routing, so the UI shows fallback as active even when Icecast status endpoints do not list the internal `/__fallback_*` source.\n- `status-json` exposes a normalized `input_endpoints` list for every audio pipe: public source mount, fallback mount when enabled, and processor mount when configured. The Pipe overview INPUT column uses this list for red/green/blinking-green indicators.\n- The active route pill keeps showing `running-source`, `running-fallback`, or `running-processor`, and the pending fallback/recovery countdown remains visible below it.\n- Native Rocket Broadcaster style pipes now run audio-silence detection against the public source mount. When silence is confirmed, eCast routes clients to `/__fallback_*` and disconnects the silent public source so the final public mount can fall through to fallback; recovery is detected when Rocket reconnects with non-silent audio.\n\n## v0.4.16 Rocket Broadcaster fallback routing/status fix\n\n- Plain audio pipes with external Icecast publishers now check the public source by Icecast admin statistics, including whether the received-byte counter is still advancing.\n- If Rocket Broadcaster disconnects or leaves the public mount connected without sending data, `ecast-monitor` changes the pipe state to `fallback`, verifies that `/__fallback_<mount>` is connected, moves listeners to the fallback mount, and disconnects the stale public source.\n- When the real source returns, `ecast-monitor` switches back to `live` and moves listeners from `/__fallback_<mount>` back to the public mount when needed.\n- `ecast-service status-json` now exposes `route_mode`, `fallback_active`, `output_active`, `served_source_mount` and the active source role/mount so the web UI can show whether the pipe is using the real stream, processor input, or fallback recording.\n- The VU/output activity indicator now stays active when fallback is serving even if there are no listeners yet.\n\n## v0.4.15 audio virtual input routing\n\n- Audio pipes now keep the public Icecast mount as the stable listener/output URL, for example `/test`.\n- If an audio A/V processor is selected and the pipe has no upstream Input URL, eCast creates a separate pre-processor source mount named `/__procesor_<mount>`, for example `/__procesor_test`.\n- If audio fallback is enabled, eCast creates `/__fallback_<mount>`, for example `/__fallback_test`, and continuously publishes the selected fallback recording there.\n- The public mount is configured with Icecast fallback routing to `/__fallback_*`, so a processed output, direct source, or fallback source can serve the same final `/test` stream depending on the monitor state and source availability.\n- The web UI INPUT column now shows the active source route, such as `procesor -> .../__procesor_test`, `fallback -> .../__fallback_test`, or `source -> .../test`.\n- This supersedes the v0.4.14 behavior where fallback publishing was started only after the source-loss countdown.\n\n## v0.4.14 native Icecast fallback countdown fix\n\n- Native Icecast fallback now respects the configured source-loss countdown.\n- eCast does **not** publish to `/__fallback_*` while the pipe is only waiting for source; this keeps the pipe in `waiting source` state and the UI shows `FallBack za N s`.\n- After the configured delay elapses, `ecast-monitor` switches the mode to `fallback` and restarts `ecast-channel`, which starts publishing the fallback file to `/__fallback_*`.\n- When the original source reconnects to the public source mount, `ecast-monitor` switches mode back to `live`, restarts the channel, and stops the fallback publisher.\n- The public source mount, for example `/radio1`, stays free for the external encoder at all times, so Rocket Broadcaster should no longer fail with `Another broadcaster` because of eCast fallback.\n\n## v0.4.13 native Icecast fallback\n\n- Audio fallback for plain Icecast pipes no longer publishes to the public source mount. The fallback mount is separate, for example `/__fallback_radio1`.\n- The public source mount, for example `/radio1`, stays free for the external encoder. This prevents Rocket Broadcaster from failing with “Another broadcaster”.\n- Icecast native `<fallback-mount>` and `<fallback-override>` handle listener switching, so the real Icecast source has priority and listeners move back automatically when it reconnects.\n\n## v0.3.27 changes\n\n- Pipe run state is now persisted in `/var/lib/ecast/pipe-state.json`; start/stop/restart saves the desired state, and boot/apply restores only pipes that were meant to be running.\n- `ecast-service status` and diagnostics show the saved desired state next to the real systemd runtime state.\n\n## v0.3.26 changes\n\n- Recordings: added 48 kbps and HE-AAC v2 / libfdk_aac codec option.\n- Pipe overview: listener/client count moved into the Type column and centered under the pipe type.\n- FallBack module: added test FCT button to preview playback from the current wall-clock position in the selected fallback audio file.\n- Waveform: no synthetic waveform is drawn when no live level is measured or the measured level is silent.\n- A/V Processor: fixed DAB Radio optimal preset for Liquidsoap and FFmpeg fallback by using integer dynaudnorm frame size and compressor attack/release in milliseconds.\n\n\n## v0.3.25 changes\n\n- Audio-only Icecast A/V diagnostics now show Liquidsoap engine, generated filter lines, generated `.liq` script and Liquidsoap log tail.\n- Added default A/V Processor presets: `dab-radio-optimal` for DAB radio audio and `video-broadcast-balanced` for video. Existing installations get these presets injected if missing.\n- Reworked audio FallBack into standalone presets: upload an audio file or select an audio file from recordings archive, choose whether playback follows wall-clock time or starts at the beginning, then apply the preset only by selecting it in a pipe.\n\n\n## v0.3.24 development changes\n\n- Audio-only Icecast A/V processing is now handled by Liquidsoap. Video pipes remain on the FFmpeg A/V path, including video overlays and video-pipe audio filters.\n- `ecast-channel` generates a per-pipe Liquidsoap script in the runtime directory and publishes the processed audio back to the final Icecast mount. If Liquidsoap is unavailable or the audio input is not HTTP(S), the service logs a warning and falls back to FFmpeg.\n- The A/V filter diagnostic now reports the selected processing engine and shows the generated Liquidsoap script for audio-only Icecast pipes.\n\n- A/V Processor logo and watermark overlays now support MP4 and AVI assets in addition to PNG/JPG/WEBP images. Animated overlay videos are looped by FFmpeg and their embedded audio is ignored.\n- Logo and watermark filtergraphs were rechecked to keep the source aspect ratio with `force_original_aspect_ratio=decrease`, SAR normalization and safe height capping.\n- Audio bitrate selectors now start at 64 kbps, and the API accepts `64k` for channel output and recording profiles.\n\n- A/V Processor video overlays now preserve logo/watermark aspect ratio by normalizing SAR, scaling proportionally and capping overlay height safely.\n- VU / traffic meters in the pipe overview now render as bottom-to-top vertical indicators instead of left-to-right horizontal bars.\n- A/V Processor direct-publisher mode now creates a separate raw input route when no upstream Input URL is set, so FFmpeg can read raw input and publish the processed output to the final Icecast/RTSP endpoint.\n- A/V Processor Phase Rotator form now uses FFmpeg `aphaseshift` normalized range `-1..1` directly, while older saved degree values are converted automatically.\n\n- Waveform history in Pipe overview shortened from about 5 minutes to about 1 minute for a denser, more readable curve.\n- Application version propagation fixed: PHP bootstrap, installer TUI, progress UI, static header fallback and bundled JSON defaults now report `0.4.14`.\n- Diag / Log includes an A/V Filter test window for active pipes with selected processing. It prints pipe configuration, generated filter arguments, systemd state, a synthetic FFmpeg syntax test, and channel log tail for troubleshooting.\n\n- Pipe overview column `Recordings` was renamed to `Functions`.\n- Function tags are shown in the overview: red `recordy/records`, blue `processor`, and grey `fallback`.\n- Pipe overview now shows the live output-audio waveform directly in its own column between VU and Functions; it is drawn for active audio and video pipes.\n- Video pipes use the same output-audio waveform mechanism, so the displayed curve represents the audio track of the video pipe.\n- Saving an audio pipe now persists the selected A/V Processor audio profile correctly.\n- Liquidsoap is installed automatically with the base package; the TUI no longer asks a separate question for it.\n- A/V Processor module version updated independently to `0.2.8`.\n- Saving or deleting A/V Processor profiles now only updates `av-processor.json`; it does not restart services. Profiles are compiled and used only when selected in a pipe and the pipe configuration is applied.\n- Video processing separates `Logo` and `Watermark` overlays, each with its own drag-and-drop upload, path, position, width, opacity and margins.\n- Subtitle files can be uploaded by drag-and-drop or referenced by URL.\n- Audio processing adds noise reduction, echo and bass balance controls with slider ranges.\n- The FFmpeg runtime helper now supports separate logo/watermark overlays and the new audio filters.\n\n## Earlier 0.3.x development baseline\n\n- Package naming is now sequential, e.g. `ecast-pipe-server-mvp-v0.7.24.zip`.\n- Web UI branding shows the immutable cluster server ID, derived from the server hostname.\n- Files uses `files-rec.json` as a persistent file index and re-indexes only missing or changed files.\n- Web indexing now uses the sudo helper `/usr/local/sbin/ecast-recording-index`, so thumbnail generation does not depend on PHP-FPM user write permissions.\n- Audio recordings store probed duration in the index; video recordings generate JPEG thumbnails next to each video file about 30 seconds from the start, with 2-second and 0-second fallbacks for shorter files.\n- Day ZIP download accepts both `YYYYMMDD` and `YYYY-MM-DD` recording directory formats.\n- Video live delivery is RTSP-only in the UI to match the current FFmpeg/MediaMTX runtime; MP4/MKV/MPEG-TS remain recording formats.\n- Diagnostics / Balancing now reads root-collected CPU/RAM process metrics from `ecast-service status-json` and sums channel, recorder and monitor process trees, so FFmpeg child processes are included.\n- Settings / Cluster prepares `cluster.json`, generates a 32-character local API key when missing, and keeps the local server ID bound to hostname.\n- Settings / Backup adds an EDU Rádio compatible backup list/create/download/delete workflow for web UI and JSON settings only. Audio/video recordings are excluded.\n- Settings / Modules accepts eCast ZIP modules with `config.json` containing `\"compatabile\": \"ecast\"`, installs them into `module/<name>/`, and supports enable/disable/delete controls.\n- Recording video thumbnails enlarge 4x on hover in the Files/Soubory browser.\n- Modules installer now has an EDU Rádio-style drag-and-drop ZIP dropzone.\n- FallBack, Recordings and Diag are loaded through built-in eCast modules in `php-app/module/<name>/` with a flat module layout (`config.json`, `index.html`, `module.js`, `module.php`). About/O programu is a fixed core page and is always the last sidebar item.\n- The installer TUI asks for HTTPS web port and Icecast HTTP port. Defaults are 443 and 8000; the Icecast HTTPS relay is always `icecast_port + 1` and the selected ports are rendered into Nginx, `/etc/ecast/config.json`, web settings and the nftables firewall template.\n- About / O programu opens README.md inside the web UI and is a core application menu item, not a module.\n- New UI texts for these areas are available in both `cz.ini` and `en.ini`.\n\n\nProgram: **eCast pipe**\nVersion: **0.7.24**\nAuthor: **PB**\nWeb: **estudium.eu**\nEmail: **info@estudium.eu**\n\n`eCast pipe` is an Ubuntu server package for receiving, distributing, recording and monitoring audio/video pipes.  It combines a Bash/whiptail installer, Nginx + PHP web administration, Icecast for audio, MediaMTX for RTSP video, FFmpeg-based recording, and systemd services for runtime control.\n\n## Main features\n\n- Ubuntu amd64 target with interactive whiptail installer and environment-variable unattended mode.\n- Nginx + PHP web UI with form/session login using `/etc/ecast/web.htpasswd`; API Basic credentials remain supported.\n- Audio distribution through Icecast mountpoints, for example `/radio1`.\n- Video live distribution through MediaMTX RTSP paths, for example `rtsp://server:8554/tv1`.\n- Optional source/publisher password per pipe.\n- Optional listener/viewer password per pipe.\n- Recording presets selected per pipe.\n- Audio recording formats: MP3, AAC/ADTS, Ogg/Opus and FLAC.\n- Video recording formats: MP4, MKV and MPEG-TS.\n- Recording browser in the web UI with a persistent `files-rec.json` index, audio durations, stale-file cleanup and video thumbnails.\n- Built-in **A/V Processor** module for reusable audio and video processing profiles selected per pipe.\n- Day ZIP download for recording directories named either `YYYYMMDD` or `YYYY-MM-DD`.\n- Backup recordings for same-time previous-day fallback.\n- Audio silence detection with FFmpeg `silencedetect`.\n- Video black-frame detection with FFmpeg `blackdetect` and FPS checking.\n- Diagnostics page with Overview, Linux, Log and Balancing tabs.\n- Balancing tab with live per-pipe CPU, RAM and estimated LAN graphing.\n- Cluster settings preparation in `cluster.json` for future multi-server management.\n- Backup tab for ZIP snapshots of the web UI, JSON settings and installed modules, excluding audio/video recordings.\n- Module/package installer compatible with EDU Rádio-style ZIP modules containing `config.json`; modules are versioned independently from the main eCast package.\n- fail2ban, nftables firewall template, chrony time sync and HTTPS helper scripts.\n\n## Install\n\n```bash\nsudo unzip ecast-pipe-server-mvp-v0.7.24.zip -d /opt/src\ncd /opt/src/ecast-pipe-server\nsudo ./install.sh\n```\n\nThe installer installs the required packages, copies the application to `/opt/ecast`, installs systemd units and helper commands, configures Nginx/PHP, creates the first web user, asks for HTTPS web and Icecast ports, renders the matching Nginx/firewall configuration, and applies the initial configuration.\n\nTypical package dependencies are listed in `packages.txt` and include:\n\n```text\nnginx-full php-fpm php-cli php-mbstring php-xml php-curl php-zip icecast2 ffmpeg liquidsoap fail2ban nftables sudo curl ca-certificates jq uuid-runtime apache2-utils openssl python3 python3-yaml unzip chrony tzdata whiptail\n```\n\nThe installer writes a detailed log to:\n\n```text\n/var/log/ecast/install-latest.log\n```\n\nIf installation fails, collect a debug bundle with:\n\n```bash\nsudo ecast-collect-debug\n```\n\nThe command prints the generated `.tar.gz` path. Secrets in copied configs are redacted by the collector.\n\n## Unattended install\n\n```bash\nECAST_INSTALL_LANG=cz \\\nECAST_SYSTEM_HOSTNAME=web01.estudium.eu \\\nECAST_PUBLIC_HOST=web01.estudium.eu \\\nECAST_TIMEZONE=Europe/Prague \\\nECAST_WEB_HTTPS_PORT=443 \\\nECAST_ICECAST_PORT=8000 \\\nECAST_ENABLE_CHRONY=1 \\\nECAST_WEB_USER=admin \\\nECAST_WEB_PASSWORD='change-this-password' \\\nECAST_SSH_PUBLIC_KEY='ssh-ed25519 AAAA... your-key-comment' \\\nECAST_APPLY_FIREWALL=0 \\\nsudo ./install.sh\n```\n\nTo force non-TUI mode even from an interactive shell:\n\n```bash\nsudo ECAST_NO_TUI=1 ./install.sh\n```\n\nFor old terminals that render whiptail borders incorrectly:\n\n```bash\nECAST_ASCII_LINES=1 sudo ./install.sh\n```\n\n## Important accounts and groups\n\n- Web login: Nginx HTTP Basic Auth, first user created during install.\n- Runtime user/group: `ecast:ecast`.\n- MediaMTX user: `mediamtx`.\n- Web server user: `www-data`, added to group `ecast` so the PHP app can maintain local JSON data and submit compiled config.\n- Default time zone: `Europe/Prague`, configurable in Settings.\n\nThe web UI does **not** use PAM.\n\n## Main paths\n\n```text\n/etc/ecast/config.json                         compiled runtime config\n/etc/ecast/web.htpasswd                       web login / API credential hashes\n/etc/icecast2/icecast.xml                     rendered Icecast config\n/etc/mediamtx/mediamtx.yml                    rendered MediaMTX config\n/opt/ecast/php-app                            PHP API and web UI\n/opt/ecast/php-app/data/settings.json         web settings\n/opt/ecast/php-app/data/channels.json         pipe definitions\n/opt/ecast/php-app/data/recordings.json       recording presets\n/opt/ecast/php-app/data/runtime.json          last action/error state\n/opt/ecast/php-app/data/files-rec.json        indexed recording files\n/opt/ecast/php-app/data/cluster.json          cluster preparation config\n/opt/ecast/php-app/data/backup.json           backup archive index\n/opt/ecast/php-app/data/backup                backup ZIP archives\n/opt/ecast/php-app/module                     installed eCast modules\n/var/lib/ecast/recordings                     recording root\n/var/log/ecast                                eCast logs\n/run/ecast                                    runtime state, mode and probe files\n```\n\nRecording segments are stored as:\n\n```text\n/var/lib/ecast/recordings/<pipe>/<recording>/<YYYYMMDD>/<HHMMSS>.<ext>\n```\n\n## Web UI sections\n\n- **Panel**: overview cards, pipe table, status, output URLs, VU/traffic indicators.\n- **Kanál / pipe**: create and edit audio/video pipes, credentials, output settings, selected recording presets and failure/fallback settings.\n- **A/V Processor**: reusable audio/video processing profiles for FFmpeg runtime processing and future Liquidsoap audio workflows.\n- **Recordings**: recording preset settings and **Files/Soubory** browser for indexed recorded segments.\n- **FallBack**: one-day backup recording presets used for fallback.\n- **Diag**: live status, Linux diagnostics, logs and balancing graphs.\n- **Nastavení**: system settings, security, users, cluster preparation, backup and module installation.\n- **O programu / About**: displays this README.md directly in the web UI.\n\nThe logo in the sidebar links to `www.estudium.eu`.\n\n## Configuration flow\n\nThe web UI stores editable data in local JSON files under `php-app/data/`. `bootstrap.php` compiles that data into `compiled-config.json`; full Apply runs `ecast-apply`, writes `/etc/ecast/config.json`, renders service configs and restarts/reloads services. Recording preset save/delete is intentionally lighter: it only syncs `/etc/ecast/config.json` and leaves recorder/service restarts to the operator.\n\nManual apply:\n\n```bash\nsudo /usr/local/bin/ecast-apply\n```\n\nThe web UI automatically applies configuration after saving pipes, recordings and system settings.\n\n## Pipe model\n\nEach pipe contains:\n\n- `id`, `kind`, `title`, `enabled`\n- `input_auth` for source/publisher credentials\n- `delivery` for mount/path, codec, bitrate and listener auth\n- `recording_ids` selecting recording presets\n- `backup` fallback settings\n- `processing` selecting one audio profile and, for video pipes, one video profile\n- `failure_detection` thresholds and switch/recovery timing\n\nAudio live output uses Icecast.  Video live output is RTSP through MediaMTX.  Other video formats in the UI are recording formats, not live delivery formats.\n\n## Runtime services\n\nFor pipe `radio1`:\n\n```bash\nsystemctl status ecast-channel@radio1\nsystemctl status ecast-recorder@radio1\nsystemctl status ecast-monitor@radio1\njournalctl -u ecast-channel@radio1 -f\njournalctl -u ecast-recorder@radio1 -f\njournalctl -u ecast-monitor@radio1 -f\n```\n\nHelper commands:\n\n```bash\necast-service status-json\necast-service diag\necast-collect-debug\necast-web-user set <user> <password>\necast-setup-https\n```\n\n## Recordings and file index\n\nThe recording file browser no longer probes every file on every page load.  It keeps an index in:\n\n```text\n/opt/ecast/php-app/data/files-rec.json\n```\n\nOn each listing request the API:\n\n1. scans the recording root for allowed media files,\n2. removes missing files from the JSON index,\n3. indexes only new or changed files,\n4. probes audio files with `ffprobe` to store duration,\n5. generates one JPEG thumbnail for video files with FFmpeg,\n6. returns the cached metadata to the UI.\n\nAllowed media extensions are `mp3`, `aac`, `adts`, `ogg`, `opus`, `flac`, `mp4`, `m4a`, `mkv`, `ts` and `mpegts`.\n\nDay ZIP download supports both compact recorder date folders (`YYYYMMDD`) and older dashed folders (`YYYY-MM-DD`).\n\n## About / O programu\n\nThe **About / O programu** core page displays the installed `README.md` directly in the web UI. The installer copies `README.md` and `VERSION` to `/opt/ecast/`, and the web API exposes the README through `api.php?action=readme`.\n\n## Diagnostics and balancing\n\nThe Diag page contains:\n\n- Overview: pipe status, output URL and client/IP information.\n- Linux: service/system diagnostic command output.\n- Log: fail2ban, firewall and warning snippets.\n- Balancing: per-pipe live graph of CPU, RAM and estimated LAN throughput.\n\nBalancing metrics are sampled through `api.php?action=balancing`. CPU/RAM prefer root-collected process-tree metrics from `ecast-service status-json`, so FFmpeg child processes under channel/recorder/monitor services are included. LAN throughput is estimated from configured bitrate, source state and connected clients.\n\n## Cluster preparation\n\nSettings includes a **Cluster** tab.  It saves to:\n\n```text\n/opt/ecast/php-app/data/cluster.json\n```\n\nThe file contains local API settings for this server and a table of connected servers with ID, name, URL and API key.  This is preparation only; automatic synchronization and balancing across servers are not active yet.\n\n## Backup and module packages\n\nSettings includes a **Backup** tab derived from the EDU Rádio backup workflow. It stores metadata in:\n\n```text\n/opt/ecast/php-app/data/backup.json\n```\n\nBackup ZIP files are stored in:\n\n```text\n/opt/ecast/php-app/data/backup\n```\n\nA backup contains the PHP web UI/API, static HTML/CSS/JS, JSON configuration data and installed module files. It deliberately excludes audio/video recordings, the recording file index `files-rec.json`, and the backup archive directory itself, so backups do not recursively include previous backups.\n\nSettings also includes a **Modules / balíčky** tab. It accepts eCast ZIP modules that contain `config.json` with `\"compatabile\": \"ecast\"`. Module files are expected directly in one flat module directory, for example `config.json`, `index.html`, `module.js` and `module.php`; do not create internal `html/`, `js/` or `php/` folders for new eCast modules. Public HTML/JS/CSS assets are served through `api.php?action=module_asset`; module PHP handlers listed in `config.json` are called through `api.php?action=module_api`. Each module has its own `version`/`module_version` in `config.json`; module versions evolve separately from the main eCast package version. Installed modules are stored as:\n\n```text\n/opt/ecast/php-app/module/<module-name>\n```\n\nThe installer preserves this directory during upgrades, so locally installed modules are not deleted by the core eCast package update. Bundled core modules are installed/updated from the package without deleting third-party modules.\n\nBuilt-in core modules shipped by eCast:\n\n```text\nphp-app/module/fallback/config.json\nphp-app/module/fallback/index.html\nphp-app/module/fallback/module.js\nphp-app/module/fallback/module.php\nphp-app/module/recordings/config.json\nphp-app/module/recordings/index.html\nphp-app/module/recordings/module.js\nphp-app/module/recordings/module.php\nphp-app/module/recording-files/config.json\nphp-app/module/recording-files/index.html\nphp-app/module/recording-files/module.js\nphp-app/module/recording-files/module.php\nphp-app/module/ext-stream/config.json\nphp-app/module/ext-stream/index.html\nphp-app/module/ext-stream/module.js\nphp-app/module/ext-stream/module.php\nphp-app/module/diag/config.json\nphp-app/module/diag/index.html\nphp-app/module/diag/module.js\nphp-app/module/diag/module.php\nphp-app/module/backup/config.json\nphp-app/module/backup/index.html\nphp-app/module/backup/module.js\nphp-app/module/backup/module.php\nphp-app/module/av-processor/config.json\nphp-app/module/av-processor/index.html\nphp-app/module/av-processor/module.js\nphp-app/module/av-processor/module.php\n```\n\nThese core modules control the sidebar menu items **FallBack**, **Recordings**, **Soubory / Files**, **External stream / Externi stream**, **Diag**, **Backup** and **A/V Processor**. They can be enabled/disabled from Settings / Modules; protected core modules cannot be deleted from the UI. About / O programu is not a module and is always rendered as the final sidebar item. Third-party eCast modules can still be installed, enabled, disabled and removed.\n\n## Firewall\n\nThe firewall template is copied to:\n\n```text\n/etc/nftables.conf.ecast\n```\n\nTo apply it during install:\n\n```bash\nsudo ECAST_APPLY_FIREWALL=1 ./install.sh\n```\n\nReview it before applying on a remote server.  The default security settings allow TCP 22, 80, 443, 8000, 8001, 8554 and UDP 161. If custom ports are selected in the installer, `/etc/nftables.conf.ecast` is rendered with the selected HTTPS web port, selected Icecast HTTP port and relay port `icecast + 1`.\n\n## HTTPS\n\nThe installer can generate a self-signed certificate in `/etc/ecast/tls/`.  Browsers will show a warning until the certificate and key are replaced with a trusted certificate.\n\n## Recovery and debugging\n\nUseful files and commands:\n\n```bash\nsudo tail -n 200 /var/log/ecast/install-latest.log\nsudo ecast-collect-debug\nsudo systemctl status nginx php*-fpm icecast2 mediamtx\nsudo journalctl -u nginx -u icecast2 -u mediamtx --since today\n```\n\nSee also:\n\n- `docs/CHANNEL_SCHEMA.md`\n- `docs/INSTALLER_TUI.md`\n- `docs/MANUAL_TEST.md`\n- `docs/RECORDINGS.md`\n- `docs/RECOVERY_FROM_V2.md`\n- `docs/WEB_APP_V15.md`\n\n## Production hardening notes\n\n- Replace the self-signed HTTPS certificate before exposing the web admin publicly.\n- Restrict SSH and admin access to trusted IPs or VPN.\n- Keep API keys and source/listener passwords secret.\n- Consider moving secrets from JSON into root-only secret files for production.\n- Consider a queue/control daemon instead of direct sudo from PHP for larger deployments.\n\n## v0.4.14 A/V Processor additions\n\n- Added the built-in **A/V Processor** module in `php-app/module/av-processor`.\n- The A/V Processor module has its own independent module version: `0.2.8`; module versions evolve separately from the main eCast package version.\n- Profiles are stored in `php-app/data/av-processor.json`; uploaded logo/subtitle assets are stored in `php-app/data/av-assets`.\n- Audio profiles support phase rotation, AGC, noise reduction, echo, bass balance, compressor block, EQ and brickwall limiter settings.\n- Video profiles support luma/chroma correction, separate logo and watermark overlays with position, size, opacity and margins, subtitles and output metadata.\n- Each pipe can select one saved audio profile. Video pipes can additionally select one saved video profile.\n- Runtime FFmpeg arguments are generated by `/usr/local/bin/ecast-av-filter` and injected into `ecast-channel@<pipe>`.\n- Liquidsoap is installed automatically as preparation for richer audio processing workflows; the current runtime processing is applied through FFmpeg filters for compatibility with the existing pipe service.\n\nExample runtime inspection:\n\n```bash\necast-av-filter --config /etc/ecast/config.json --channel radio1 --part all\n```\n\n\n### Zmeny 0.4.14\n\n- Pipe overview waveform is now pipe-specific; each active pipe uses its own output audio level/seed so multiple rows no longer draw the same curve.\n- Function tags now show concrete names: recording preset names, selected A/V processor profile names and selected fallback preset/file.\n- ecast-monitor also samples output audio level into `/run/ecast/<pipe>.audio-level.json` when possible; the UI prefers output level fields for the waveform/VU display.\n- `ecast-channel` logs generated A/V filter arguments and avoids stream-copy codecs when a processing filter is active, so selected A/V processor profiles are actually applied by FFmpeg.\n\n### CLI test A/V processor\n\nAfter selecting an A/V audio profile in a pipe and applying the configuration, verify it on the server:\n\n```bash\nPIPE=100\nsudo jq --arg id \"$PIPE\" '.channels[] | select(.id==$id) | .processing' /etc/ecast/config.json\nsudo /usr/local/bin/ecast-av-filter --config /etc/ecast/config.json --channel \"$PIPE\" --part all\nsudo systemctl restart \"ecast-channel@$PIPE\"\nsudo tail -n 80 \"/var/log/ecast/$PIPE-channel.log\"\n```\n\nExpected: the JSON contains `audio_profile_id`, `ecast-av-filter` prints FFmpeg arguments such as `-filter_complex ... [aout]`, and the channel log contains `av_filter_args=` plus `ffmpeg_cmd=` when a real Input URL is configured.\n\n\n### 0.4.14 filter diagnostics\n\n- `Diag / Log -> Filter test` now includes a runtime assessment. If `Input URL` is empty it explicitly reports that the processor cannot be heard or seen in direct publisher mode.\n- The same test runs a short synthetic FFmpeg syntax check. This verifies that the generated audio/video filter graph is accepted by FFmpeg even before a real upstream input is connected.\n- A/V processing still requires a real upstream `Input URL`. A direct publisher that sends directly to the final Icecast mount or RTSP path cannot be processed in-place; route the source into a separate upstream URL, then let eCast publish the processed output.\n\n### A/V input/processor runtime behavior\n\n- Pipe editor restores the upstream Input URL field for relay and A/V processing workflows.\n- If Input URL is empty, eCast treats the pipe as direct publisher mode and `ecast-channel` does not run FFmpeg in live mode. This prevents repeated `Error opening input file .` messages.\n- Fallback can still publish generated fallback content when the monitor switches the pipe to fallback mode.\n- `ecast-av-filter --part audio` and `--part video` are accepted as CLI aliases for `--part filter`.\n\n### A/V processor runtime and waveform fixes\n\n- A/V Processor filter arguments are now emitted as explicit `-filter_complex` graphs with mapped outputs. Audio-only pipes map `[aout]`; video pipes map `[vout]` and `[aout]` when audio processing is selected. This makes echo, bass, limiter and video luma/chroma/overlay processing visible in the final FFmpeg command instead of relying on a plain `-af` chain.\n- `ecast-channel` logs the full escaped FFmpeg command as `ffmpeg_cmd=...` in `/var/log/ecast/<PIPE>-channel.log` so processing can be verified directly from CLI.\n- Audio container/codec mismatches are corrected for older configs, especially `format=mp3` with `audio_codec=aac`; MP3 output is forced to `libmp3lame`.\n- The Pipe overview waveform is now a denser one-minute history using an independent ring buffer for each pipe.\n\n## 0.5.22 Stream Analyzer folders and DAB preset\n\n- Stream Analyzer se nově přidává nad složkou pod recordings, ne nad pipe/externím streamem.\n- Stage 1 segmentace je pevně 1 s, aby Files panel zobrazoval klikatelné časové úseky po sekundách.\n- Stage 3 seskupuje sousední hudební sekundy do delšího vzorku pro AcoustID, aby 1s UI segmenty nerozbily identifikaci skladeb.\n- A/V Processor DAB preset má upravené odšumění, vypnutou ozvěnu a stabilnější výstupní hlasitost pro rádio.\n- Doporučený cluster postup je v docs/CLUSTER_RECOMMENDED.md.\n\n## 0.6.13 Backup restore and cluster pairing UI\n\n- Backup now stores the eCast server ID in the ZIP manifest and in the backup list.\n- Backup rows show content tags such as pipe count, recording presets, A/V processor presets, modules, fallbacks, external streams and Stream Analyzer definitions.\n- Backup includes a Restore action. Restore creates a safety backup first, then restores only safe `php-app` web UI, module and JSON settings paths. Audio/video recordings and the recordings index are not restored.\n- Cluster settings use a compact UI. Local eCast ID, API URL and local API key are read-only text values with copy buttons.\n- Cluster pairing is still two-sided: server A sends the remote eCast ID, API URL and API key; server B receives a visible request with A's ID/key and must approve it.\n- Paired servers now store type, version, IP and per-peer provide/receive capabilities for status, pipe, recordings and files.\n- Panel displays a separate remote Pipe overview only for paired peers of type `eCast`, plus a compact CPU/RAM/Disk/LAN display for every paired eCast peer with a loaded status snapshot.\n\n\n## 0.6.13 Cluster UI security and monitoring\n\n- Cluster pairing now needs only the remote eCast ID and remote API key; the API URL is derived as `https://<eCast ID>/api.php`.\n- `api.php?cmd=info` returns only a minimal non-sensitive discovery payload without a key. Hardware, pipes, recordings, files and reboot are exposed only after a valid Cluster API key.\n- Cluster settings use copy buttons before values, stronger contrast and peer type autodetection from authenticated peer info.\n- The Panel shows uptime for the local server and paired eCast peers, plus a protected remote reboot action for eCast peers.\n- Default Fail2ban SSH ban duration is now 1 day.\n\n\n### v0.7.17\n- Přehled Pipe: sloupec Typ je nahoře vycentrovaný stejně jako ostatní buňky tabulky.\n- Přehled Pipe: sloupec Funkce používá malé jednořádkové tagy skládané pod sebe, aby neroztahoval řádky.\n- Recordings: nové výchozí presety pro video 24 h H.265/nejvyšší komprese, video 1 h H.264/normální komprese a video test copy 10 min.\n- Recordings: nové výchozí audio presety Ogg/Opus 48 kbps na 24 h, HE-AAC v2 64 kbps na 1 h a MP3 test po 1 min.\n- Aktualizace existující instalace doplní chybějící nové recording presety bez přepsání uživatelských profilů.",
    "download_url": "https://update.estudium.eu/download.php?project=dbad8351151b6fd5&release=f8d76d73440a554be625d9a3c5a7b845",
    "package_target": "software",
    "requirements": [],
    "license": {
        "id": "MIT",
        "name": "MIT",
        "custom_text": ""
    },
    "deployment": {
        "archive_root": "ecast-pipe-server",
        "web_root": "."
    },
    "project_type": "application",
    "hosting": null
}