Arquitectura del SDK
Diagrama del Sistema
┌─────────────────────────────────────────────────────┐
│ Platform Layer (pwa/main.ts) │
│ PwaPlayer: wires all packages together │
│ Wake Lock, Screenshot, SW registration │
└──────────────────────┬──────────────────────────────┘
│
┌──────────────────────────────────────┼──────────────────────────────────┐
│ │ │
┌───┴────────────┐ ┌─────────┴─────────┐ ┌──┴──────────────┐ ┌───────────────┐
│ PlayerCore │ │ RendererLite │ │ Service Worker │ │ XmrWrapper │
│ Orchestration │ │ XLF rendering │ │ Chunk streaming │ │ WebSocket │
│ Collection │ │ Element reuse │ │ Range requests │ │ 13 commands │
│ Offline cache │ │ Transitions │ │ IC interception │ │ Reconnect │
│ Commands │ │ Touch/keyboard │ │ Cache-first │ │ │
└───────┬────────┘ └──────────────────┘ └───────────────────┘ └───────────────┘
│
├───────────────────────┬───────────────────────┬──────────────────┐
│ │ │ │
┌───────┴──────────┐ ┌────────┴────────┐ ┌──────────┴──────┐ ┌────────┴───────┐
│ XmdsClient │ │ ScheduleManager │ │ CacheManager │ │ StatsCollector │
│ + RestClient │ │ + Interrupts │ │ + CacheProxy │ │ + LogReporter │
│ SOAP + REST │ │ + Overlays │ │ + DlManager │ │ Proof-of-play │
│ ETag caching │ │ Dayparting │ │ Parallel chunks│ │ Fault reporting │
└──────────────────┘ └─────────────────┘ └─────────────────┘ └────────┬────────┘
│
┌────────┴────────┐
│ SyncManager │
│ Lider/seguidor │
│ BC + WebSocket │
│ Aillament grups│
│ Deleg. estad. │
└─────────────────┘
Patrons de Disseny Clau
1. Nucli Independent de Plataforma
PlayerCore conté tota la lògica de negoci sense assumpcions de plataforma. La capa de plataforma (PWA, Electron, Android) connecta els paquets i proporciona implementacions específiques de la plataforma (Wake Lock, captura de pantalla, registre del Service Worker).
2. Comunicació per EventEmitter
Tots els mòduls es comuniquen mitjançant events, no crides directes a mètodes:
PlayerCore emits: schedule-updated, collection-complete, purge-request
RendererLite emits: layoutStart, layoutEnd, widgetStart, widgetEnd
StatsCollector: listens to layout/widget events for proof-of-play
LogReporter: listens for errors from IC, renderer, collection
3. Transport Dual
El paquet XMDS proporciona dues implementacions de transport amb superfícies d'API idèntiques:
- XmdsClient (SOAP/XML) — protocol tradicional, totes les versions del CMS
- RestClient (REST/JSON) — càrregues 30% més petites, cau ETag 304
PlayerCore no sap quin transport està actiu.
4. Reutilització d'Elements
RendererLite pre-crea TOTS els elements DOM dels widgets en carregar el disseny, els emmagatzema en un Map, i alterna la visibilitat:
Layout load: Pre-create all elements → widgetElements.set(widgetId, element)
Widget switch: Hide current → Show next (visibility toggle, no DOM create/destroy)
Layout replay: Detect isSameLayout → Reuse elements → Restart videos
Layout change: Revoke blob URLs → Destroy elements → Create new set
5. Service Worker com a Servidor de Mitjans
En lloc d'un servidor HTTP local, la PWA utilitza el seu Service Worker per interceptar les peticions fetch i servir els mitjans des del cau:
- Streaming per blocs amb suport de peticions Range
- Intercepció IC (rutes de Control Interactiu)
- Reescriptura d'URLs de CSS de fonts
- Cau primer amb fallback a xarxa
- Funcionament offline
Flux de Dades
Cicle de Col·lecció
1. RegisterDisplay() → CMS settings, commands, XMR address
2. CRC32 comparison → Skip if unchanged
3. RequiredFiles() → File list with MD5 hashes
4. Download missing files → 4 parallel chunks, MD5 verify
5. Schedule() → Layout schedule XML
6. Parse schedule → Layouts, overlays, actions, commands
7. MediaInventory() → Report cached file inventory
8. NotifyStatus() → Report status (disk, timezone, layout)
9. SubmitStats() → Proof-of-play records
10. SubmitLog() → Queued log entries
11. SubmitScreenShot() → If captured
Mode Offline
Network down:
→ XMDS calls fail → Use IndexedDB-cached schedule/settings
→ Media requests → Service Worker serves from Cache API
→ Stats/logs → Queued in IndexedDB, submitted when network returns
→ Player continues rendering with last known schedule
Arquitectura d'Emmagatzematge
Cache API (Fitxers Binaris)
Cache: xibo-media
├── /media/{id} → Images, videos, audio
├── /widget/{widgetId} → Widget HTML (getWidgetHtml)
├── /font/{fontFile} → Font files
└── /static/{path} → Static player assets
IndexedDB (Dades Estructurades)
Database: xibo-player
├── files → File metadata (id, type, md5, size)
├── stats → Proof-of-play (pending submission)
├── logs → Log entries (pending submission)
├── schedule → Last known schedule (offline fallback)
├── settings → Last known CMS settings
└── requiredFiles → Last known required files
Pila Tecnològica
| Capa | Tecnologia | Justificació |
|---|---|---|
| Llenguatge | JavaScript (ES2020+) | Multiplataforma, sense transpilació |
| Client HTTP | fetch() + fetchWithRetry | Integrat, reintent configurable |
| Anàlisi XML | DOMParser | Integrat, conscient de namespaces |
| Emmagatzematge | Cache API + IndexedDB | APIs PWA integrades |
| Offline | Service Worker | Intercepta totes les peticions fetch |
| Hash MD5 | spark-md5 | 4KB, suport ArrayBuffer |
| PDF.js (càrrega diferida) | Estàndard de la indústria | |
| HLS | hls.js (càrrega diferida) | Polyfill per a navegadors que no són Safari |
| Animacions | Web Animations API | Integrat, accelerat per GPU |
| Compilació | Vite | Tree-shaking, minificació |
| Paquets | pnpm workspaces | Gestió de workspace |
Dependències en temps d'execució: spark-md5 (4KB), hls.js (diferit), PDF.js (diferit), xibo-communication-framework
