Digital Signage — Flujo SpinetiX
Qué es
Pipeline completo para publicar contenido multimedia en reproductores SpinetiX HMP (Hyper Media Player). Abarca desde composición de proyecto SVG dinámico hasta descarga autónoma por el dispositivo físico, sin requerir conexión permanente con el servidor.
Por qué existe
Los SpinetiX usan Scheduled Download: consultan periódicamente una URL HTTP para obtener índice WebDAV (spx-listing.xml) y descargan solo archivos cambiados. Esto exige endpoints públicos sin autenticación de sesión, identificados por token UUID (publish_token) por SignagePlayer. El módulo resuelve el contrato para que el reproductor opere autónomo incluso con NAT o cortafuegos.
Componentes
SpinetiXAdapter (signage/services/adapters/spinetix.py): adapter async con 2 protocolos:
- JSON-RPC sobre HTTP POST en
/rpc:getStatus,setPlaylist,setSchedule,getPlaybackLog,reboot. Payload{"jsonrpc": "2.0", "method": ..., "params": ..., "id": 1}, timeout 10s. - WebDAV PUT sobre
/content/<filename>: sube archivos binarios viaaiohttpcon HTTP Basic, timeout 120s.push_content()acepta 200/201/204. - Screenshot GET
/screenshotpara proof-of-play visual.
Auth opcional: si credentials["username"] existe, aiohttp.BasicAuth.
SVG Composer (signage/services/svg_composer.py): genera SVG completo compatible SpinetiX desde items de playlist.
- Namespace
xmlns:spx="http://www.spinetix.com/namespace/1.0/spx"+spx:repeatCountpara loop nativo HMP. - Cada slide → elemento SVG (
<image>,<video>,<text>,<rect>,<iframe>) con animaciones de visibility/opacity como fracciones del tiempo total (keyTimes). - Transiciones:
dissolve/fade(animate opacity),slide_left/right/up/downyzoom_in/out(animateTransform),none(visibility toggle). - Capas
always_visible(overlays, tickers, logos) se renderizan sobre slides sin animación. - Vídeos:
<video xlink:href="..." repeatCount="indefinite"/>, nunca sobreescribe duración con playback global.
Scheduled Download — endpoints públicos (signage/views_publish.py): bajo /signage/publish/<token>/ sin CSRF ni auth de sesión:
| Endpoint | Función |
|---|---|
spx-listing.xml (o PROPFIND raíz) | DAV:multistatus XML con project.svg, index.svg y media files, con size, content-type, ETag |
project.svg / index.svg | Genera SVG dinámico en tiempo real via compose_project_svg() |
<filename> | Sirve binario del MediaAsset via FileResponse |
Cada request a spx_listing actualiza last_heartbeat y status="online" del player (proof-of-life pasivo). Si hay current_schedule, se evalúa con scheduling.engine.evaluate_schedule() para determinar playlist activa antes de componer SVG.
Despliegue activo (signage/services/deployment.py): execute_deployment(deployment_id) punto de entrada del task Huey. Modo push:
- Carga
ContentDeployment, pone estadodeploying. - Resuelve IP del player desde
device_profileomonitoring_target. - Descifra credenciales sensibles (password, api_key, token) con
CredentialManager.safe_decrypt. - Instancia adapter correcto via
registry.get_adapter(slug, ip, creds, config). - Ejecuta en nuevo event loop:
push_content()por cada archivo +set_playlist()+set_schedule()si aplica. - Agrega resultados por player (
ok/partial/error) y actualizadeployment_results.
Estado final: deployed, failed o partial.
Flujos
Scheduled Download (principal SpinetiX):
Operador → edita Playlist → asigna a SignagePlayer (current_playlist)
SpinetiX HMP → GET /signage/publish/<token>/spx-listing.xml (periódico)
→ _get_playlist_items() resuelve MediaAssets
→ compose_project_svg() genera project.svg dinámico
→ respuesta DAV:multistatus con ETags
HMP → compara ETags, descarga solo archivos nuevos
→ GET /signage/publish/<token>/project.svg
→ GET /signage/publish/<token>/<imagen_o_video>
HMP → reproduce nativamente (animaciones SVG + spx:repeatCount)
Cada fetch → actualiza last_heartbeat (proof-of-life)
Despliegue activo (push para otros adapters):
API POST /api/signage/deployments/ → Huey → execute_deployment(id)
→ _deploy_to_player() por cada player
→ adapter.push_content() via WebDAV
→ adapter.set_playlist() via JSON-RPC
→ adapter.set_schedule() via JSON-RPC
→ ContentDeployment.status = deployed|partial|failed
Proof-of-play:
- Pasivo: cada fetch SpinetiX actualiza
last_heartbeatystatus. - Activo:
SpinetiXAdapter.get_playback_logs(since=...)via JSON-RPCgetPlaybackLog;take_screenshot()captura desde/screenshot.
Related
entity--signage--model--signageplayer— contienepublish_token,current_playlist/schedule,last_heartbeat.entity--signage--model--mediaasset— archivos referenciados.entity--signage--model--playlist— lista ordenada conasset_id,duration_seconds,transition.
Véase también
- [[entity—signage—model—signageplayer]]
- [[entity—signage—model—mediaasset]]
- [[entity—signage—model—playlist]]
Referenciado desde
- Agente · dev-signage
- Digital Signage SaaS — Guía Completa
- Falsas alarmas HighErrorRate por el 501 deliberado de SpinetiX WebDAV
- MediaAsset · Modelo signage
- Servicio publish_misses — enlaces de publicación de Signage rechazados (v1.124.0, task #276)
- SignagePlayer · Modelo signage
- SpinetiX HMP Integration Guide — CreaRack Pro