Senza questo il telefono (mono 48k) veniva rifiutato sui nodi Hetzner e lo warm spare rubava le sessioni a home. Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
2.5 KiB
YAML
78 lines
2.5 KiB
YAML
#cloud-config
|
|
# Nodo stream Hetzner: MediaMTX + ffmpeg.
|
|
# HCLOUD_USER_DATA_FILE=.../infra/stream-node/cloud-init.yaml
|
|
|
|
package_update: true
|
|
packages:
|
|
- docker.io
|
|
- ffmpeg
|
|
- curl
|
|
- apparmor
|
|
|
|
write_files:
|
|
- path: /opt/stream-node/mediamtx.yml
|
|
permissions: "0644"
|
|
content: |
|
|
logLevel: info
|
|
# Allinea a infra/mediamtx.yml: API raggiungibile anche da IP non-localhost
|
|
# (in prod restringere via WireGuard / firewall Hetzner).
|
|
authInternalUsers:
|
|
- user: any
|
|
pass:
|
|
ips: []
|
|
permissions:
|
|
- action: api
|
|
- action: metrics
|
|
- action: publish
|
|
- action: read
|
|
- action: playback
|
|
api: yes
|
|
apiAddress: :9997
|
|
rtmp: yes
|
|
rtmpAddress: :1935
|
|
hls: yes
|
|
hlsAddress: :8888
|
|
paths:
|
|
all_others:
|
|
- path: /opt/stream-node/bootstrap.sh
|
|
permissions: "0755"
|
|
content: |
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
mkdir -p /recordings /slates
|
|
systemctl enable --now docker
|
|
# aspetta il socket docker
|
|
for i in $(seq 1 60); do
|
|
if docker info >/dev/null 2>&1; then break; fi
|
|
sleep 2
|
|
done
|
|
docker pull bluenviron/mediamtx:latest
|
|
docker rm -f mediamtx 2>/dev/null || true
|
|
# Slate offline (alwaysAvailable) — richiesta da Mediamtx::Client#create_path.
|
|
# MediaMTX 1.20+: AAC del publisher RTMP deve matchare la slate.
|
|
# Allineato ad app Android (BroadcastConfig: 48 kHz mono) e infra/scripts/generate_slate.sh.
|
|
mkdir -p /slates
|
|
ffmpeg -y -f lavfi -i color=c=black:s=1280x720:d=2 -f lavfi -i anullsrc=r=48000:cl=mono \
|
|
-c:v libx264 -t 2 -pix_fmt yuv420p -c:a aac -ac 1 -ar 48000 -shortest /slates/offline.mp4
|
|
# Debian cloud image: docker.io senza apparmor_parser → serve unconfined o pkg apparmor
|
|
docker run -d --name mediamtx --restart unless-stopped --network host \
|
|
--security-opt apparmor=unconfined \
|
|
-v /opt/stream-node/mediamtx.yml:/mediamtx.yml:ro \
|
|
-v /recordings:/recordings \
|
|
-v /slates:/slates:ro \
|
|
bluenviron/mediamtx:latest /mediamtx.yml
|
|
# smoke locale
|
|
for i in $(seq 1 30); do
|
|
if curl -fsS http://127.0.0.1:9997/v3/paths/list >/dev/null; then
|
|
echo "mediamtx ready" | tee /opt/stream-node/ready
|
|
exit 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
echo "mediamtx NOT ready" | tee /opt/stream-node/ready
|
|
docker logs mediamtx || true
|
|
exit 1
|
|
|
|
runcmd:
|
|
- [bash, /opt/stream-node/bootstrap.sh]
|