@xiboplayer/pwa
v0.7.16
Published
Lightweight PWA xiboplayer with RendererLite
Readme
xiboplayer PWA
Lightweight PWA Xibo digital signage player built on the @xiboplayer SDK. Part of the SDK monorepo at packages/pwa/.
CMS Communication
- REST API (primary) — lighter JSON transport with ETag caching (~30% smaller payloads)
- XMDS SOAP (fallback) — standard Xibo player protocol when REST is unavailable
Features
- Offline-first — Service Worker caching with parallel chunk downloads and progressive streaming
- XLF layout rendering — video (MP4/HLS), images (scale/align), audio overlay, PDF, text/ticker, web pages via RendererLite
- Campaign scheduling — priority-based campaigns, dayparting, interrupts, and overlays
- Playback control — skip to next/previous layout via keyboard or click a layout in the timeline overlay
- Conflict indicators — timeline overlay highlights overlapping schedule entries with accurate per-layout durations
- Multi-display sync — BroadcastChannel-based lead/follower synchronized playback for video walls, with cross-tab stats/logs delegation so followers submit proof-of-play through the sync lead
- Real-time CMS commands — collectNow, screenshot, changeLayout, overlayLayout via XMR WebSocket
- SDK event wiring — widget duration events, scheduled commands, event-based proof of play
- Proof of play — per-layout and per-widget duration tracking with stats reporting
- Log batching — aggregated log submission aligned with CMS spec
- Screenshots — html2canvas-based capture for non-Electron browsers, Electron uses
capturePage() - Screen Wake Lock — prevents display from sleeping during playback
- Configurable log levels —
DEBUG,INFO,WARNING,ERROR,NONE(via URL param or CMS settings; log levels only affect verbosity, not overlays)
Keyboard Shortcuts
All keyboard shortcuts and mouse hover are disabled by default for secure kiosk operation. Enable them via controls in the host player's config.json (Electron or Chromium). The config is injected into localStorage by @xiboplayer/proxy.
| Key | Group | Action |
|-----|-------|--------|
| D | debugOverlays | Toggle download progress overlay |
| T | debugOverlays | Toggle timeline overlay (click-to-skip supported) |
| S | setupKey | Toggle CMS setup screen |
| V | videoControls | Toggle native <video> controls |
| → / PageDown | playbackControl | Skip to next layout |
| ← / PageUp | playbackControl | Skip to previous layout |
| Space | playbackControl | Pause / resume playback |
| R | playbackControl | Revert to scheduled layout |
| Media keys | playbackControl | Next/prev/pause/play (MediaSession API) |
Auto-authorize via CMS API (optional)
By default, new displays must be manually authorized by a CMS administrator. To skip this step and have the player authorize itself automatically, provide OAuth2 API credentials — either via the setup page or via config.json provisioning in the Electron/Chromium shells.
How it works
After the player registers with the CMS (via XMDS RegisterDisplay), it uses the CMS REST API with an OAuth2 client_credentials flow to:
- Obtain an access token from
/api/authorize/access_token - Find the display by hardware key via
GET /api/display?hardwareKey=... - Authorize the display via
PUT /api/display/{id}/authorise
If auto-authorize fails (wrong credentials, missing scope, CMS unreachable), the player silently falls back to manual authorization — the CMS administrator sees the display as "Awaiting approval".
CMS setup
- In the CMS, go to Administration > Applications
- Click Add Application
- Set Grant Type to
client_credentials - Important: on the Scopes tab (2nd tab), enable the
displaysscope — this is required for the player to find and authorize itself - Save and copy the Client ID and Client Secret
Without the displays scope enabled, the API will return 403 Forbidden and auto-authorize will not work.
Interactive setup
In the setup page, expand "Auto-authorize via API (optional)" and enter the Client ID and Client Secret. These are saved to localStorage alongside the CMS configuration.
Provisioning via config.json
When using the Electron or Chromium shells, add the credentials to config.json:
{
"cmsUrl": "https://your-cms.example.com",
"cmsKey": "your-cms-key",
"displayName": "Lobby Display",
"apiClientId": "your-client-id",
"apiClientSecret": "your-client-secret"
}Debug Overlays
Three toggleable overlays provide real-time insight into player operation without leaving the playback screen. All are disabled by default — enable controls.keyboard.debugOverlays in the host player's config.json, then press the corresponding key to toggle. Overlays are independent of log level — DEBUG logging does not enable overlays.
Timeline Overlay (T)
Shows the upcoming schedule as a scrollable list (up to 8 entries visible):
- Current layout highlighted with a
▶marker and blue left border - Time range and duration for each entry (e.g.
19:25–19:31 #362 6m 15s) [def]tag on default/fallback layouts (no campaign scheduled)OFFLINEbadge when the player has lost CMS connectivity- Conflict indicators — a
+Nbadge appears next to a layout when N other layouts were scheduled for the same time slot but suppressed by a higher-priority campaign. Hover over it to see which layouts were hidden and their priorities (e.g.Also scheduled: #366 (p0), #362 (p0)) - Click-to-skip — click any future layout to jump to it immediately. The player enters override mode (the schedule won't auto-advance). Press
Rto return to normal schedule playback - Remaining duration — the currently playing layout shows time remaining rather than full duration, so the predicted end time is always accurate
Download Overlay (D)
Shows real-time media download progress:
- Active downloads with progress bars, speed, and chunk status
- Queue depth — how many files are waiting to download
- Idle status when all media is cached and up to date
- Auto-hides when all downloads complete (if auto-hide is enabled)
Useful during initial deployment or after a purgeAll command to monitor how quickly content is being cached.
Video Controls (V)
Toggles native browser <video> controls on all video elements currently in the DOM. Shows play/pause, seek bar, volume, and fullscreen buttons on each video widget — helpful for debugging video playback issues, checking codec info, or manually seeking within a video.
Service Worker Architecture
The Service Worker (sw-pwa.js) provides:
- Progressive streaming — large media served via chunk streaming with Range request support
- BlobCache — in-memory assembled chunks with LRU eviction for fast video seeking
- XLF-driven media resolution — parses layout XLF to download exactly the media each layout needs, including data widget IDs (media tags without fileId) and unclaimed media files
- Server-enriched widget data — RSS/dataset widget data paths are provided by the CMS in enriched RequiredFiles responses, downloaded alongside regular media rather than fetched client-side
- Layout-ordered downloads — media queued with barriers so the currently-playing layout downloads first
- Version-aware activation — same-version SW update skips activation to preserve in-flight video streams
- Adaptive chunk sizing — adjusts chunk size and concurrency based on device RAM (4GB/8GB+ tiers)
Installation
The PWA can be served from:
- CMS origin — deploy
dist/to a path under the CMS web server (e.g.https://your-cms.example.com/player/pwa/) to avoid CORS - Standalone with proxy — use
@xiboplayer/proxyto serve the PWA and proxy CMS requests (used by Electron and Chromium shells)
Development
Prerequisites
- Node.js 20+
- pnpm 10+
Setup
pnpm installBuild
pnpm run buildDev server
pnpm run devLink SDK for local development
pnpm link ../xiboplayer/packages/{utils,cache,renderer,schedule,xmds,xmr,core,stats,settings}Testing
Electron (recommended for development)
cd ../xiboplayer-electron && npx electron . --dev --no-kioskChromium kiosk
cd ../xiboplayer-chromium && ./xiboplayer/launch-kiosk.sh --no-kioskPlaywright E2E
Playwright tests in playwright-tests/ run against a live CMS with scheduled layouts — not for CI.
PWA_URL=https://your-cms.example.com/player/pwa/ npx playwright testLicense
Apache-2.0
