Technical Manual
Complete technical reference for developers and system integrators working with the xiboplayer ecosystem.
SDK internals
| Topic | Description |
|---|---|
| Architecture | Package dependency graph, data flow, event bus, platform abstraction |
| Package Reference | All 14 @xiboplayer/* packages with exports and dependencies |
| Feature Comparison | Detailed comparison vs upstream Xibo players (Windows, XLR, arexibo) |
Communication protocols
XMDS (CMS ↔ Player)
The player communicates with the CMS via XMDS — available in both SOAP and REST transports:
Collection cycle (every 5-900 seconds):
RegisterDisplay()— register/re-register, receive settings and XMR addressRequiredFiles()— get file manifest with MD5 hashes (CRC32 skip optimization)Schedule()— get layout schedule XML- Download missing files — 4 parallel chunks, MD5 verification
MediaInventory()— report cached file inventoryNotifyStatus()— report device status (disk, timezone, layout)SubmitStats()— proof-of-play recordsSubmitLog()— queued log entries (batched, max 50)SubmitScreenShot()— captured screenshot (if configured)
REST vs SOAP:
- REST: JSON payloads (~30% smaller), ETag 304 caching, JWT auth
- SOAP: XML, compatible with all CMS versions (v3-v7)
- Auto-detected at startup via protocol probe
XMR (CMS → Player push)
Real-time WebSocket commands from CMS to player:
| Command | Action |
|---|---|
collectNow | Trigger immediate collection cycle |
screenshot | Capture and submit screenshot |
changeLayout | Switch to a specific layout |
overlayLayout | Show a layout as overlay |
revertToSchedule | Return to scheduled layout |
purgeAll | Clear cache and re-download |
dataUpdate | Refresh dataset/connector data |
commandAction | Execute a CMS-defined command |
triggerWebhook | Trigger interactive action |
criteriaUpdate | Update display criteria |
XMR uses RSA key exchange + ARC4 symmetric encryption. Auto-reconnect with exponential backoff (10 attempts).
Rendering pipeline
XLF (Xibo Layout Format)
Layouts are XML files defining regions, widgets, and transitions:
<layout width="1920" height="1080" background="bg.jpg">
<region id="1" width="1920" height="1080" top="0" left="0">
<media id="42" type="video" duration="30" uri="video.mp4">
<options><loop>1</loop></options>
</media>
<media id="43" type="image" duration="10" uri="image.jpg">
<options><scaleType>center</scaleType></options>
</media>
</region>
</layout>
Widget types
| Type | Element | Special handling |
|---|---|---|
| Video | <video> | HLS.js for non-Safari, pause-on-last-frame |
| Image | <img> | scaleType (center/stretch/fit), align/valign |
| Audio | <audio> | Gradient visualization overlay |
| Canvas | PDF.js (lazy-loaded), page-by-page rendering | |
| Text/Ticker | <iframe> | GetResource from CMS, NUMITEMS/DURATION parsing |
| Web page | <iframe> | Direct src, sandboxed |
| All CMS widgets | <iframe> | Generic GetResource rendering |
Performance optimizations
- Element reuse — widgets are pre-created and toggled via
visibility, not destroyed/recreated - 2-layout preload pool — next layout pre-built at 75% of current duration
- Blob URL lifecycle — tracked and revoked to prevent memory leaks
- Parallel media prefetch — all widget media URLs fetched via
Promise.all - Media-ready gating — layout timer starts only when all first widgets are loaded
Download system
Chunked parallel downloads
Large files are split into 4 parallel 50MB chunks:
File: 200MB video.mp4
Chunk 1: bytes 0-49999999 (parallel)
Chunk 2: bytes 50000000-99999999 (parallel)
Chunk 3: bytes 100000000-149999999 (parallel)
Chunk 4: bytes 150000000-199999999 (parallel)
→ Reassemble → MD5 verify → Store
- Header+trailer first — downloads first and last 1MB of MP4 for instant playback start
- Resume — incomplete downloads resume from last successful chunk
- Download windows — CMS-configured time restrictions honored
- Urgent queue — current layout media gets priority over background downloads
Storage layers
| Layer | Technology | Use case |
|---|---|---|
| ContentStore | Filesystem via proxy | Media files, layouts (Electron/Chromium) |
| Service Worker | Cache API | Media files (PWA) |
| IndexedDB | Structured data | Schedule, settings, stats, logs, file metadata |
Schedule system
Priority resolution
1. Interrupt layouts (share of voice, percentage-based)
2. Campaign layouts (highest priority wins)
3. Default layout (lowest priority fallback)
Within the same priority: layouts cycle in order with configurable duration.
Dayparting
- Daily, weekly, monthly recurrence
- Midnight-crossing support (e.g., 22:00 → 06:00)
- Geo-fencing with location fallback chain (browser → Google API → IP)
- Weather criteria evaluation
Layout blacklist
Layouts that fail rendering 3 consecutive times are blacklisted and reported to CMS via the BlackList XMDS method. Blacklist resets when RequiredFiles changes.
Multi-display sync
See Multi-Display Video Walls for the complete setup guide.
Protocol summary:
- Lead broadcasts
layout-changewith target timestamp - Followers preload → report
ready - Lead broadcasts
layout-showat coordinated timestamp - All displays show simultaneously (±4ms measured, <8ms guaranteed)
Testing
| Suite | Count | Framework |
|---|---|---|
| SDK unit tests | 1744 | Vitest + jsdom |
| Electron unit | 20 | Vitest |
| Electron e2e | 7 | Playwright |
| Chromium | 9 | bats |
| arexibo | 18 | Rust cargo test |
| Android | 9 | JUnit + Robolectric |
| webOS | 11 | Node.js test runner |
| Total | 1818 |
Integration tests run nightly against the dev CMS via Docker Compose or direct connection.
