Reproducción

Una sola regla: nadie arma URLs de video a mano. Pedís GET /v1/videos/{id}/playback y le pasás hls_url a tu player. Nuestro propio dashboard funciona igual.

Cuándo llamarlo

Llamá a /playback cuando el player se abre, nunca antes. En Strict, un link tiene diez minutos para arrancar; uno preparado con anticipación puede estar muerto para cuando el espectador apreta play.

Lo llamás desde Lo usás para
Tu página web o app, sin key Videos públicos en Open o Protected
Tu backend, con la secret key Videos privados y workspaces en Strict

Parámetros de query opcionales:

  • viewer_id: un id opaco tuyo (el id de tu usuario, un asiento de curso). Viaja dentro del link y llega a nuestros logs, así que un link filtrado se puede rastrear hasta quién lo recibió.

Qué te devuelve

Campo Qué es
hls_url Playlist maestro. Pasáselo al player. null si se renderiza o es original.
original_url El original sin tocar. Mismo vencimiento y seguridad que hls_url.
poster_url Imagen fija para el poster del player, o null.
thumbnails_url Sprite WebVTT para las vistas previas del seek, o null.
embed_url Nuestro player alojado (iframe). En Strict solo funciona con esta URL exacta.
expires_at Cuándo deja de funcionar el link (ISO 8601), o null en Open.
security El nivel que se aplicó: open, protected, strict o maximum.
delivery hls u original. Ver abajo.
duration_sec Duración del video en segundos.

El token vive en el path (/hls/t/{token}/…) porque AVPlayer, Chromecast y las apps nativas no pueden mandar headers. Cada playlist y segmento bajo ese path ya está firmado; nunca firmás nada vos mismo.

Original o HLS

Cada video conserva su archivo original tal cual lo subiste o importaste. Nunca lo transcodificamos. Elegís un delivery al subir o importar:

  • hls (default): XonaPlay renderiza HLS adaptativo desde el original. Reproducí hls_url.
  • original: ninguna transcodificación. El original es lo que reproducís y descargás. Usá original_url.

Mientras el HLS se está renderizando, hls_url es null y original_url ya funciona. original_url acepta pedidos por rango de bytes. Con original, hls_url siempre es null.

XonaPlay garantiza hls_url en todos los dispositivos. Qué players pueden reproducir original_url depende de su formato: mp4 con H.264 se reproduce casi en todos lados; mkv y HEVC puede que no. Esa elección es tuya.

Sin HLS, poster_url y thumbnails_url son null, salvo que el dueño del video haya subido un poster propio.

Los videos guardados en tu propio servidor (BYO) devuelven original_url: null.

Para pasar un video subido con original a HLS, mandá PATCH /v1/videos/{id} con "delivery": "hls". Solo se puede en un sentido, y original_url sigue funcionando mientras tanto.

Vencimiento

Nivel El link funciona durante
Open Para siempre
Protected Duración del video + 1 hora (2 a 24 horas)
Strict 10 minutos para arrancar, después duración del video + 30 minutos (1 a 24 horas)

Una pestaña en pausa puede sobrevivir a su link. Es esperado: el player se recupera.

Regla de "Recargar"

Todas las recetas de estos docs siguen los mismos cuatro pasos:

  1. Ante cualquier error fatal del player (un 403 en un segmento, un error de red, un error de decodificación), pedí /playback de nuevo — como máximo una vez por minuto — y retomá en el mismo segundo.
  2. Si la respuesta trae hls_url, cargala y hacé seek hacia atrás.
  3. Si la respuesta es un error, mostrá su message. Ofrecé un botón Recargar solo cuando el code sea reintentable (ver la tabla de abajo).
  4. Si el player vuelve a fallar dentro de los 60 segundos, no llames a nada: mostrá Recargar, que vuelve al paso 1.

La decisión sale del JSON de /playback, que cualquier cliente HTTP puede leer. No dependas de headers HTTP del host del video: AVPlayer no puede leerlos.

Errores

Los errores usan el mismo sobre que el resto de la API:

json
{ "status": "error", "code": "KEY_REQUIRED", "message": "This video needs a secret key." }
code HTTP ¿Reintentar?
NOT_FOUND 404 No
KEY_REQUIRED 401 No. Llamalo desde tu backend con la key.
INVALID_KEY 401 No
DOMAIN_NOT_ALLOWED 403 No
WORKSPACE_UNAVAILABLE 403 No
ACCESS_DENIED 403 No
VIDEO_NOT_READY 409 Sí, más tarde
LIVE_NOT_ACTIVE 409 Sí, más tarde
RATE_LIMITED 429 Sí, después de Retry-After
5xx o una respuesta sin JSON — Sí

El host del video (no /playback) responde a un link muerto con un 401/403/503 plano y un header X-Xona-Error — TOKEN_EXPIRED, TOKEN_REVOKED, NETWORK_CHANGED, MAXIMUM_UNAVAILABLE… Está ahí para debuguear; tu player solo sigue la regla de recargar, y MAXIMUM_UNAVAILABLE (503) es reintentable como el resto.

Vivo

Las transmisiones en vivo usan el mismo contrato:

bash
curl https://api.xonaplay.com/v1/live/{STREAM_ID}/playback

LIVE_NOT_ACTIVE significa que la transmisión todavía no salió al aire. Reintentá más tarde o mostrá una cuenta regresiva.