Files
MatchLiveTv/docs/REPLAY_MODULE.md
Emiliano Frascaro 4ed15bc235 Rimuovi replay da app, fix live web e sync punteggi broadcast.
La pagina live mostra solo l'overlay nel video (niente tabellone HTML); l'app nativa non espone più l'archivio replay, il toggle regole punteggio parte spento e i controlli in diretta seguono il punteggio dalla regia.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 08:42:23 +02:00

5.7 KiB
Raw Blame History

Modulo Replay — Match Live TV

Panoramica

Al termine di ogni diretta Premium, MediaMTX registra i segmenti. Sidekiq unisce i segmenti, genera thumbnail, carica su Garage (S3-compatible) e attiva i servizi di notifica, statistiche e (opzionale) republicazione YouTube.

Piani e retention

Piano Registrazione Retention Download MP4 YouTube VOD
Free No No No
Premium Light 30 giorni No
Premium Full 90 giorni Sì (auto se diretta YouTube)

Funzionalità implementate

1. Registrazione automatica

Pipeline: Sessions::StopFinalizeSessionUploadJob → storage.

MediaMTX registra solo mentre il telefono pubblica (RTMP connesso). In pausa o con sola slate alwaysAvailable la registrazione è disattivata, così il replay non contiene minuti di schermo «Trasmissione in pausa».

2. Retention e purge

Recordings::PurgeExpiredJob / rails recordings:purge_expired

3. Archivio Replay

  • Web: /clubs/:id/replays (gestione società)
  • Pubblico: /replay con filtro società/squadra
  • App mobile: nessuna UI replay (gestione solo da sito web)

4. Riproduzione

  • Player MP4: /replay/:id + stream /replay/:id/stream
  • Contatore visualizzazioni su ogni play (view_count)

5. Visibilità

  • Pubblico (public): compare in /replay, indicizzabile, YouTube public
  • Privato (unlisted): non in catalogo pubblico, accessibile solo con link diretto, noindex, YouTube unlisted

Modificabile dallarchivio società (/clubs/:id/replays). Il cambio privacy sincronizza automaticamente il VOD YouTube se presente (Recordings::SyncYoutubePrivacyJob).

6. Eliminazione anticipata

Recordings::Delete — elimina video YouTube collegato, oggetti S3/Garage (MP4 + thumbnail) e soft-delete DB.

Stesso comportamento alla scadenza retention (PurgeExpiredJob alle 03:00).

7. Dashboard KPI

Replay disponibili, in scadenza (7 gg), spazio occupato, visualizzazioni totali.

8. Miglioramenti Premium

Feature Descrizione
Email replay pronto A owner e membri società quando status → ready
Email scadenza 7 giorni prima di expires_at (rails recordings:expiry_warnings)
Thumbnail Frame ffmpeg, URL /replay/:id/thumbnail
Download MP4 Premium, link presigned 15 min o /replay/:id/download
Statistiche views view_count su ogni replay
metadata JSONB source_platform, auto_publish_youtube, ai: {} per estensioni
YouTube VOD Premium Full: upload automatico se diretta era su YouTube; manuale da archivio

Storage

REPLAY_STORAGE_ENDPOINT=http://garage:3900
REPLAY_STORAGE_BUCKET=matchlivetv-replays
REPLAY_STORAGE_ACCESS_KEY_ID=...
REPLAY_STORAGE_SECRET_ACCESS_KEY=...
REPLAY_DOWNLOAD_URL_TTL_SECONDS=900

Senza endpoint S3: storage locale /recordings/replays/.

Dev locale con Garage

cd infra
docker compose up -d          # include garage
bash scripts/setup_garage_replays.sh   # layout, bucket, chiave → .env
docker compose up -d rails sidekiq

# Verifica pipeline (segmento finto → Garage)
docker compose exec -T rails bundle exec rails replay:e2e_garage

Produzione (/opt/matchlivetv)

cd infra
bash scripts/setup_garage_production.sh   # garage.prod.toml, bucket, chiavi → .env
# Rails/Sidekiq usano REPLAY_STORAGE_ENDPOINT=http://garage:3900 (rete Docker)

Credenziali in .env: non compilarle a mano in .env.example. Lo script scrive in infra/.env:

  • REPLAY_STORAGE_ACCESS_KEY_ID = Key ID Garage (es. GK...)
  • REPLAY_STORAGE_SECRET_ACCESS_KEY = Secret mostrato una sola volta alla creazione chiave

Cron (produzione)

Installazione sul server:

cd /opt/matchlivetv/infra
bash scripts/install_production_cron.sh

Job attivi (utente eminux):

Orario Task
03:00 recordings:purge_expired — elimina replay scaduti (DB + Garage)
08:00 recordings:expiry_warnings — email avviso scadenza (7 gg)

Log: /opt/matchlivetv/log/cron-replay.log

Capacità Garage

Allinstallazione, setup_garage_production.sh assegna ~(disco libero 20 GB) al nodo. Per ridimensionare dopo:

bash scripts/garage_set_capacity.sh 85G   # oppure senza argomento: calcolo automatico

Piattaforme live e replay

Origine diretta Copia Garage/S3 Player sito /replay/:id YouTube VOD
matchlivetv Sì (Premium) MP4 via proxy Rails Manuale (Premium Full)
youtube Sì (Premium) MP4 via proxy Rails Auto se Premium Full + diretta YouTube

Se il file S3 non è disponibile ma esiste youtube_video_id, la pagina replay mostra embed YouTube.

Retention e abbonamento

  • expires_at viene impostato alla fine diretta: 30 giorni (Premium Light), 90 giorni (Premium Full)
  • expires_at non cambia al cambio piano successivo
  • Nuove registrazioni richiedono abbonamento attivo (can_create_recordings?)
  • Archivio esistente resta accessibile fino a expires_at anche se labbonamento scade (can_access_recordings?)

API mobile

  • GET /teams/:id/recordings — lista con thumbnail, views, download_enabled
  • GET /recordings/:id/download — URL download temporaneo
  • POST /recordings/:id/publish_youtube — coda republicazione YouTube

Estensioni future (metadata.ai)

Campo metadata["ai"] predisposto per:

  • highlight automatici
  • trascrizioni
  • articoli generati
  • clip / Shorts

Esempio aggiornamento via API:

{ "recording": { "metadata": { "ai": { "transcript_status": "queued" } } } } }