Alleggerisce il relay YouTube e rilascia Android 2.0.8.

ffmpeg fa solo remux copy A/V; le app fissano AAC 48 kHz mono; sync deploy non cancella più garage.prod.toml.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-05 19:25:40 +02:00
co-authored by Cursor
parent 9bc89fceba
commit 7b3256c8a0
14 changed files with 96 additions and 35 deletions
+4 -3
View File
@@ -202,7 +202,7 @@ MediaMTX :1935 — path live/match_{uuid}
├──► HLS :8888 ──► edge /hls/ ──► spettatori web
└──► (solo platform=youtube)
Streams::YoutubeRelay in Sidekiq
ffmpeg: -c:v copy, -c:a aac ──► YouTube RTMPS
ffmpeg: -c:v copy, -c:a copy ──► YouTube RTMPS
```
| Componente | Ruolo |
@@ -210,7 +210,7 @@ MediaMTX :1935 — path live/match_{uuid}
| Path dinamici via API :9997 | `Mediamtx::Client` (`create_path`, recording patch, …) |
| `alwaysAvailable` + slate | Copertina `/slates/offline.mp4` senza interrompere HLS |
| Overlay tabellone | **App nativa** (non più ricodifica server) |
| `Streams::YoutubeRelay` | Legge RTMP (o HLS) da MediaMTX; copy video + AAC → YouTube |
| `Streams::YoutubeRelay` | Legge RTMP (o HLS) da MediaMTX; remux copy A/V → YouTube |
| `Mediamtx::PublisherSync` | Publisher online/offline, go_live, recording on/off |
Dettaglio pause, player e ruolo ffmpeg: [`LIVE_STREAMING.md`](LIVE_STREAMING.md).
@@ -281,7 +281,7 @@ App Android ◄──── REST API (/api/v1/...) ────► Rails
Sidekiq ◄── Redis ◄──────┘
├── HealthMonitorJob, UploadJob (merge/thumbnail ffmpeg)
├── YoutubeRelay (ffmpeg copy+AAC, solo dirette YouTube)
├── YoutubeRelay (ffmpeg remux copy A/V, solo dirette YouTube)
└── PublishToYoutubeJob, purge replay, ecc.
```
@@ -419,3 +419,4 @@ cd infra && cp .env.example .env && docker compose up -d --build
| 2026-06 | `RAILS_MAX_THREADS=5`; relay YouTube da MediaMTX (non via Puma) |
| 2026-06 | Cleanup path MediaMTX orfani (`Mediamtx::CleanupOrphanPaths`); delete path sempre a fine diretta |
| 2026-07 | Rimosso overlay server (`OverlayRelay`); tabellone bruciato in app; HLS su path camera (non `*_air`); `YoutubeRelay` = copy video + AAC |
| 2026-08 | `YoutubeRelay` = remux copy video+audio (niente ricodifica AAC); profilo app/slate AAC 48k mono |
+3 -3
View File
@@ -8,7 +8,7 @@ MediaMTX espone **un unico flusso di uscita** per path (`live/match_{uuid}`):
1. **Telefono in onda** → publisher RTMP (camera + **overlay grafico bruciato in app**).
2. **Pausa / rete assente**`alwaysAvailable` con file slate (`/slates/offline.mp4`) **senza interrompere** lHLS verso il sito.
3. **YouTube** (solo se `platform=youtube`) → `Streams::YoutubeRelay` in **Sidekiq**: un processo `ffmpeg` legge RTMP/HLS da MediaMTX e inoltra a YouTube (`-c:v copy`, audio ricodificato in AAC).
3. **YouTube** (solo se `platform=youtube`) → `Streams::YoutubeRelay` in **Sidekiq**: un processo `ffmpeg` legge RTMP/HLS da MediaMTX e inoltra a YouTube (`-c:v copy`, `-c:a copy`; lAAC 48 kHz mono è già prodotto dallapp / slate).
Il telefono **non** invia la copertina di pausa: risparmia banda; lo switch slate ↔ camera è lato MediaMTX.
@@ -51,7 +51,7 @@ MediaMTX path live/match_{uuid}
├──► HLS (segmenti ~1s) ──► edge /hls/ → MediaMTX ──► player web (HLS.js)
└──► (solo platform=youtube)
Streams::YoutubeRelay
ffmpeg: -c:v copy, -c:a aac ──► RTMPS YouTube
ffmpeg: -c:v copy, -c:a copy ──► RTMPS YouTube
```
| Responsabilità | Dove |
@@ -93,7 +93,7 @@ La pagina live può mostrare badge HTML di stato (in onda / pausa / attesa); non
| Quando | Cosa | Peso CPU |
|--------|------|----------|
| Diretta `platform=youtube` | `YoutubeRelay`: demux + **copy video** + AAC audio → RTMPS | Medio-basso **per diretta**, scala con N processi |
| Diretta `platform=youtube` | `YoutubeRelay`: demux + **copy video/audio** → RTMPS (remux) | Basso **per diretta**, scala con N processi |
| Diretta solo `matchlivetv` | Nessun ffmpeg in live | Quasi zero |
| Fine diretta | `UploadFromSession`: concat segmenti (`-c copy`) | Picco breve |
| Post-process | `GenerateThumbnail`: un frame → JPEG | Trascurabile |
+1 -1
View File
@@ -170,7 +170,7 @@ Sullapp nativa loverlay è composito in GPU **prima** dellencode RTMP (
2. `OverlayRenderer``OverlayCanvasRenderer` disegna gli elementi su bitmap trasparente.
3. Il bitmap viene applicato come filtro sul flusso RTMP (OpenGL su Android, HaishinKit su iOS).
MediaMTX e `YoutubeRelay` ricevono quindi un flusso già “brandizzato”; il relay YouTube fa solo `-c:v copy` (+ AAC).
MediaMTX e `YoutubeRelay` ricevono quindi un flusso già “brandizzato”; il relay YouTube fa solo remux (`-c copy` video e audio).
Elementi grafici (`OverlayCanvasRenderer`):
+1 -1
View File
@@ -1,7 +1,7 @@
# YouTube Live — checklist operativa
**Aggiornato:** 2026-07-29
Pipeline attuale: telefono → MediaMTX → `Streams::YoutubeRelay` (ffmpeg copy+AAC in Sidekiq) → YouTube. Overlay tabellone in **app**, non più `OverlayRelay` server.
Pipeline attuale: telefono → MediaMTX → `Streams::YoutubeRelay` (ffmpeg remux copy A/V in Sidekiq) → YouTube. Overlay tabellone in **app**, non più `OverlayRelay` server.
## Verifica rapida su server
+1 -1
View File
@@ -7,7 +7,7 @@ Match Live TV supporta due modalità YouTube, legate al piano società:
| **Premium Light** | `matchlivetv_light` | Canale YouTube **Match Live TV** (gestito da te) |
| **Premium Full** | `team` | Canale YouTube **della società** (OAuth del club) |
Flusso tecnico: telefono (camera + overlay app) → RTMP MediaMTX → `Streams::YoutubeRelay` (ffmpeg `-c:v copy`, AAC) → YouTube Live.
Flusso tecnico: telefono (camera + overlay app) → RTMP MediaMTX → `Streams::YoutubeRelay` (ffmpeg `-c:v copy -c:a copy`) → YouTube Live.
---
@@ -29,7 +29,7 @@ Se il telefono andasse diretto a YouTube (o a un ingest cloud senza hold), la li
### Problema di capacità
Ogni diretta `platform=youtube` avvia un processo `ffmpeg` in Sidekiq (`Streams::YoutubeRelay`: video **copy**, audio **AAC**).
Ogni diretta `platform=youtube` avvia un processo `ffmpeg` in Sidekiq (`Streams::YoutubeRelay`: video+audio **copy** / remux).
Il carico scala con **N processi**, non con gli spettatori HLS.
Sul box attuale (~4 CPU / 8 GB, stack completo sullo stesso host):
@@ -299,7 +299,7 @@ Finché D1 non è chiusa, non stimare bandwitdh né SLA del picco.
## 7. Dimensionamento indicativo
Ipotesi: 720p, video copy, AAC mono**~0.30.7 vCPU** medi per relay (picchi più alti su analyze/reconnect).
Ipotesi: 720p, remux copy A/V**~0.150.4 vCPU** medi per relay (picchi su analyze/reconnect).
| Target live YT | Dedicated (relay) | Overflow tipico | Note |
|----------------|-------------------|-----------------|------|
@@ -349,7 +349,7 @@ Questi numeri vanno **calibati** con un load test (N sessioni fake + ffmpeg cont
### Fase 4 — Solo se necessario
- Secondo MediaMTX / sharding
- Audio copy se lencoder telefono è già YouTube-compatibile (meno CPU)
- ~~Audio copy se lencoder telefono è già YouTube-compatibile (meno CPU)~~ → fatto (app AAC 48k mono + relay `-c:a copy`)
- Dedicated più grosso come baseline (spesso più economico delloverflow cronico ogni weekend)
---