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:
@@ -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 |
|
||||
|
||||
@@ -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** l’HLS 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`; l’AAC 48 kHz mono è già prodotto dall’app / 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 |
|
||||
|
||||
@@ -170,7 +170,7 @@ Sull’app nativa l’overlay è composito in GPU **prima** dell’encode 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,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
|
||||
|
||||
|
||||
@@ -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.3–0.7 vCPU** medi per relay (picchi più alti su analyze/reconnect).
|
||||
Ipotesi: 720p, remux copy A/V — **~0.15–0.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 l’encoder telefono è già YouTube-compatibile (meno CPU)
|
||||
- ~~Audio copy se l’encoder telefono è già YouTube-compatibile (meno CPU)~~ → fatto (app AAC 48k mono + relay `-c:a copy`)
|
||||
- Dedicated più grosso come baseline (spesso più economico dell’overflow cronico ogni weekend)
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user