Episodes¶
vision.index.episodes
Un episodio describe un evento del stream y lo vincula con un momento del vídeo. Central almacena el último estado del episodio y sus imágenes; el historial está disponible mediante la API y la consola de Optic.
Episodios del stream en Optic¶
Abra la página del stream y la pestaña Episodios. Muestra los episodios guardados de este stream, los más recientes primero. Cada mosaico contiene una vista previa y la hora del evento, y la matrícula cuando está disponible. Esta pestaña solo está habilitada en Optic.
Si la cámara envió un evento sin imagen, el mosaico y la ficha cargan un fotograma del archivo de vídeo correspondiente al inicio del episodio. Esto también funciona para eventos ya guardados. El fotograma está disponible mientras la vista previa correspondiente permanezca en el archivo; si no se puede leer, la interfaz muestra un error de carga de imagen.
Configure los filtros de búsqueda y pulse Aplicar:
- Tipo — el tipo de episodio.
- Regla — el código de la regla para las activaciones, por ejemplo
lcd. - Matrícula — la matrícula exacta reconocida.
Cargar más obtiene la siguiente página con los mismos filtros. Actualizar vuelve a leer el historial desde el principio; la lista no se actualiza automáticamente.
Pulse un mosaico para abrir su ficha. La ficha muestra la descripción y el fotograma completo, si está guardado. Cuando hay un archivo de vídeo configurado, abre el reproductor con cinco segundos antes y después del episodio. Un episodio puede permanecer en el historial después de eliminar su vídeo: la retención de los metadatos se configura por separado.
Episodios creados mediante la API en un stream que se está grabando:

Ficha del episodio con reproducción del archivo de vídeo:

Retención de episodios en central¶
Central recopila el último estado de los episodios y sus imágenes de los streamers y los guarda en PostgreSQL. Los episodios retenidos siguen disponibles cuando el streamer de origen no responde. Este almacenamiento es independiente de la grabación de vídeo.
En DVR del stream o de su plantilla, Retención adicional de episodios (horas) configura dvr.episodes_additional_depth; la API y YAML usan segundos. El total es dvr.max_depth + dvr.episodes_additional_depth. La profundidad adicional no definida equivale a cero. Si existe la sección DVR pero falta max_depth, se usan diez años; un cero explícito sigue siendo cero. Sin sección DVR, o con un total de cero, central no retiene episodios.
El plazo empieza en closed_at para episodios cerrados y en updated_at para los abiertos. Cambiar la configuración DVR efectiva, incluida la plantilla, recalcula la retención de todos los episodios restantes. La sección DVR propia del stream sustituye por completo la sección de la plantilla. Eliminar un stream elimina sus episodios e imágenes. Aumentar la retención no recupera episodios ya eliminados físicamente por la limpieza en segundo plano.
API de episodios¶
GET /central/api-v4/episodes consulta el historial en PostgreSQL; GET /central/api-v4/episodes/{episode_id} devuelve un episodio. El origen GET /streamer/api-v4/episodes contiene la ventana actual en memoria del streamer; una interrupción prolongada puede causar omisiones.
Estas rutas pertenecen a la API de gestión; el rol viewer puede leerlas. Los espectadores pueden usar las API streaming y playback con el token del stream. La ficha obtiene el vídeo mediante la API de reproducción habitual.
El límite predeterminado es 100, el máximo 1000 y cada página serializada, incluido el envelope, está limitada a 32 MiB. Continúe con next_cursor; offset está prohibido. Los episodios demasiado grandes se omiten con un contador para permitir el avance. sort admite -opened_at (predeterminado), opened_at, -updated_at y updated_at; el ID resuelve empates en la misma dirección. Esta paginación no es un feed incremental global.
Filtros: listas separadas por comas en media, episode_type y episode_subtype; episode_id; license_plate_text exacto y license_plate_text_like con SQL LIKE. from y to son Unix ms y seleccionan la intersección con [from,to). Un episodio abierto continúa después de su última actualización. Los campos temporales opened_at, started_at, updated_at y closed_at admiten _gt, _gte, _lt, _lte. Los filtros distintos se combinan con AND y las listas con OR. El vencimiento no oculta registros hasta su eliminación física.
details.type identifica el tipo. Dentro de vehicle, los campos purpose, emergency_subtype, facing_side, color, model no llevan vehicle_. La vista previa inline está en preview.data (base64), con preview.timestamp. Las imágenes completas incluyen sha256 y MIME sin URL; el cliente construye GET /central/api-v4/episodes/{episode_id}/images/{sha256}. El hash debe pertenecer al estado actual del episodio. Se conservan bytes y MIME originales; sin MIME se usa application/octet-stream.
episodes_stale_timeout_secs cierra episodios sin una versión nueva tras 86400 segundos por defecto, usando el updated_at anterior como cierre. Una versión más reciente puede reabrirlos; repetir una versión no reinicia el plazo. La unicidad global del ID y el feed global siguen siendo requisitos separados para activar la función. El plazo se cuenta desde updated_at del episodio; la hora de recepción no lo prolonga. Central no modifica updated_at al cerrar un episodio abandonado.
Se configura en la página Ajustes de central de la consola y se guarda en el documento compartido /central/api-v4/config. Se aplica sin reiniciar; vaciar el campo restaura el valor predeterminado.
Lectura con un token del stream¶
Los episodios y sus imágenes aceptan los mismos tokens que el vídeo del stream. Estas solicitudes no requieren acceso de gestión. Use Authorization: Bearer o el parámetro de consulta token; si están presentes ambos, tiene prioridad el parámetro de consulta.
Rutas relativas a /playback en central y a /streaming en un nodo:
GET /v/{stream_name}/episodes
GET /v/{stream_name}/episodes/{episode_id}
GET /v/{stream_name}/episodes/{episode_id}/preview
GET /v/{stream_name}/episodes/{episode_id}/images/{sha256}
Playback lee el historial de PostgreSQL, incluidos los episodios externos, aunque el nodo no esté disponible. Los filtros y el orden coinciden con los del historial de gestión; media está prohibido porque el stream ya se indica en la ruta. Streaming del nodo lee su ventana actual de analítica en memoria y admite cursor y limit; solicite el historial persistente a central. Un token de stream no permite abrir episodios ni imágenes de otro stream.
Leer una lista, un episodio, una vista previa o una imagen completa no crea ni prolonga una sesión, no inicia la captura o grabación bajo demanda ni cuenta como visualización de vídeo. El acceso se comprueba en cada solicitud; las respuestas usan Cache-Control: no-store. El vídeo abierto por separado mediante playback se contabiliza de la forma habitual.
curl -H "Authorization: Bearer $PLAY_TOKEN" \
"$CENTRAL/playback/v/episode-demo/episodes?limit=100"
Crear un episodio externo¶
Los sistemas externos envían episodios a POST /central/api-v4/episodes. Basta con conocer el nombre del stream: central guarda el episodio y las imágenes directamente en PostgreSQL. El nodo puede estar no disponible y no es necesario que haya vídeo. Se requiere permiso de escritura en la API de gestión; el rol viewer no puede crear episodios.
Cree episode.json. Los tiempos son milisegundos Unix en la escala temporal del vídeo; sustituya el nombre del stream y los tiempos del evento por los suyos.
{
"media": "episode-demo",
"opened_at": 1700000000000,
"closed_at": 1700000004000,
"details": { "type": "motion", "is_motion": true }
}
Envíe el documento con la dirección de central y sus credenciales:
curl --user "$API_LOGIN:$API_PASSWORD" \
--header 'Content-Type: application/json' \
--data-binary @episode.json \
"$CENTRAL_URL/central/api-v4/episodes"
La primera solicitud devuelve 201 y un episode_id como cadena decimal. El episodio ya está disponible mediante GET y Actualizar en la pestaña Episodios. Una repetición con los mismos media, opened_at y details.type devuelve 200 y el ID original sin modificar los datos ni el plazo de retención. Los demás atributos, incluida la regla de trigger, no forman parte de la clave. Los episodios custom usan la etiqueta literal custom. La eliminación física del episodio libera la clave.
details tiene la misma forma que en las respuestas de lectura. Puede incluir preview y frame_preview con data en base64 y mime_type; el tiempo de la vista previa es preview.timestamp. Envíe los bytes completos de las imágenes: una referencia sha256 no es suficiente. Central asigna el ID y updated_at. El límite de la solicitud completa es de 32 MiB.
El stream debe existir y su configuración DVR efectiva debe permitir la retención de episodios. Respuestas de error:
- 404 — stream desconocido.
- 409 — retención desactivada.
- 422 — documento incorrecto, con rutas de campos.
- 413 — tamaño de solicitud excedido.
Tras un tiempo de espera agotado, repita la misma clave. POST crea un episodio; la repetición no cierra ni actualiza un episodio abierto existente. Los episodios generados por la analítica del nodo siguen llegando mediante el harvester.
Datos adicionales del episodio¶
Vea un ejemplo completo de escritura, modificación y búsqueda de meta en Datos personalizados de episodios.