Files
stream-overlay/README.md
T

6.3 KiB
Raw Blame History

🎾 Tennis Roots

Overlay per streaming tennis (OBS) con controller remoto via WebSocket.

Architettura

┌─────────────────────┐      WebSocket      ┌──────────────────────┐
│  Controller (admin) │────────────────────→│                      │
│  /controller/       │←── STATE_UPDATE ───│  Express + WebSocket  │
└─────────────────────┘                    │  Server (hub)         │
                                           │  Port 3000            │
┌─────────────────────┐      WebSocket      │                      │
│  Scoreboard (OBS)   │←── STATE_UPDATE ───│                      │
│  Match Info  (OBS)  │←── STATE_UPDATE ───│                      │
│  Clock       (OBS)  │←── STATE_UPDATE ───│                      │
│  Server Ind. (OBS)  │←── STATE_UPDATE ───│                      │
└─────────────────────┘                    └──────────────────────┘

Quick Start

# Clona / entra nel progetto
cd tennis-roots

# Avvia tutto con uno script
chmod +x start.sh
./start.sh

Oppure manualmente:

cd server
npm install
npm start

Apri nel browser:

Widget Overlay (per OBS)

Ogni widget è un file HTML indipendente, dimensionabile e posizionabile liberamente in OBS come Browser Source.

Widget URL Dimensioni suggerite
Scoreboard /overlay/scoreboard.html 820×130 px
Match Info /overlay/match-info.html 600×50 px
Clock /overlay/clock.html 150×50 px
Server Indicator /overlay/server-indicator.html 250×50 px

Setup in OBS

  1. Aggiungi Browser Source
  2. Inserisci URL del widget (es. http://localhost:3000/overlay/scoreboard.html)
  3. Imposta larghezza/altezza come da tabella
  4. Importante: spunta "Controlla audio/visibilità del browser nella sorgente"
  5. Usa filtri di ritaglio/posizionamento per sistemare l'overlay

Controller

Il pannello di controllo admin è accessibile a /controller/.

Sezioni

  • Stato corrente: live view del match
  • Punteggio: pulsanti punto P1/P2, Deuce, Reset Game/Match
  • Servizio: cambio battuta manuale
  • Giocatori: modifica nomi e bandiere
  • Info Match: torneo e round

Scorciatoie da tastiera

Tasto Azione
1 Punto P1
2 Punto P2
D Deuce
R Reset Game
M Reset Match

API HTTP

# Stato corrente
curl http://localhost:3000/api/state

# Aggiornamento parziale
curl -X POST http://localhost:3000/api/state \
  -H 'Content-Type: application/json' \
  -d '{"player1":"N. Djokovic","tournament":"US Open"}'

# Comando
curl -X POST http://localhost:3000/api/command \
  -H 'Content-Type: application/json' \
  -d '{"command":"ADD_POINT","player":1}'

WebSocket

I widget si connettono automaticamente a ws://localhost:3000/ws. Il server propaga gli aggiornamenti a tutti i client connessi.

Formato messaggi

Da controller a server:

{ "type": "COMMAND", "command": "ADD_POINT", "player": 1 }
{ "type": "COMMAND", "command": "SET_DEUCE" }
{ "type": "COMMAND", "command": "RESET_GAME" }
{ "type": "COMMAND", "command": "RESET_MATCH" }
{ "type": "COMMAND", "command": "SET_SERVER", "player": 2 }
{ "type": "STATE_UPDATE", "state": { "player1": "...", ... } }

Da server a tutti:

{ "type": "STATE_UPDATE", "state": { ... } }

Sviluppo

cd server
npm run dev    # node --watch

Deploy su VPS (Docker + Traefik)

Il progetto include Dockerfile e docker-compose.yml pronti per il deploy su un'infrastruttura con Traefik come reverse proxy.

Prerequisiti

  • Docker e Docker Compose installati
  • Rete traefik-public già esistente (docker network create traefik-public)
  • Dominio configurato (es. tennis.ricordatiilatte.it)

Procedura

# Clona il progetto sulla VPS
git clone <url> tennis-roots
cd tennis-roots

# Avvia
docker compose up -d

# Log
docker compose logs -f

Accessi

Risorsa URL
Controller https://tennis.ricordatiilatte.it/controller/
Scoreboard https://tennis.ricordatiilatte.it/overlay/scoreboard.html
Match Info https://tennis.ricordatiilatte.it/overlay/match-info.html
Clock https://tennis.ricordatiilatte.it/overlay/clock.html
Server Ind. https://tennis.ricordatiilatte.it/overlay/server-indicator.html
API stato https://tennis.ricordatiilatte.it/api/state
WebSocket wss://tennis.ricordatiilatte.it/ws

Note

  • Il server è stateless (stato in memoria). Un restart azzera il match.
  • Il WebSocket funziona nativamente con Traefik (upgrade HTTP → WS automatico).
  • Se vuoi un dominio diverso, cambia il valore di Host(...) in docker-compose.yml.

Regole punteggio implementate

  • Punti game: 0, 15, 30, 40, Deuce, Vantaggio
  • Set: primo a 6 game con 2 di scarto
  • Tiebreak: a 6-6, primi a 7 punti con 2 di scarto
  • Servizio nel tiebreak: punto 1 → P1, punto 2 → P2, poi cambio ogni 2 punti
  • Match: al meglio dei 3 set

Struttura file

tennis-roots/
├── server/
│   ├── package.json
│   ├── index.js          # Server Express + WebSocket
│   └── node_modules/
├── overlay/
│   ├── common.js         # Client WebSocket condiviso
│   ├── scoreboard.html
│   ├── match-info.html
│   ├── clock.html
│   └── server-indicator.html
├── controller/
│   └── index.html        # Pannello di controllo
├── server/
│   ├── Dockerfile        # Immagine container
│   └── ...
├── docker-compose.yml    # Deploy con Traefik
└── README.md