Ir al contenido
Documentación
Descargar
Español

Estado y eventos

Sound Show envía el estado actual del espectáculo tras autenticar y siempre que cambia. Construye el controlador a partir de estas instantáneas y usa la referencia de comandos para solicitar cambios.

Un mensaje state sustituye todo el estado local. Se recibe automáticamente tras hello_ok, tras cambios generales o de proyecto y en respuesta a request_state. Este ejemplo reducido muestra los campos principales; los proyectos reales tienen arrays poblados y más metadatos.

{
"type": "state",
"protocol_version": 2,
"server_time_ms": 1712345678901,
"state": {
"project": { "name": "My show", "categories": [] },
"players": [],
"playable_runtime": [],
"playlists": { "current_index": 0, "playlists": [] },
"instructions": { "current_index": 0, "players": [] },
"timers": [],
"logical_devices": [],
"control": {
"next_sound_volume": 70,
"selected_category_id": null,
"low_volume_active": false,
"volume_level_presets": [],
"active_volume_level_ids": [],
"effective_volume_level_id": null
},
"capabilities": { "audio_controls": [], "manual_grid_layout": false },
"audio_controls": { "revision": 1, "logical_devices": [], "players": [] },
"lights": { "revision": 1, "lights": [] }
}
}

Gestiona proyectos ausentes o null, arrays vacíos, campos opcionales y nuevos campos desconocidos. Estas páginas describen la implementación v2 actual. Una versión antigua de Sound Show 2 puede exponer menos campos, comandos o funciones; comprueba hello_ok.features y las capacidades antes de usar funciones opcionales.

Instantáneas de dominio en directo

Sección «Instantáneas de dominio en directo»

Tras el estado completo, la mayoría de actualizaciones sustituyen solo un dominio, una parte del estado con nombre. Un array vacío tiene significado: por ejemplo, players: [] borra los reproductores actuales. No combines sus entradas con la lista anterior.

type del mensaje Campo local que sustituye Envío
control_snapshot control Respuestas directas a comandos de nivel; actualizaciones de controles de todos los operadores con runtime_snapshots.
players_snapshot players Cambios de reproductores.
instructions_snapshot instructions Con runtime_snapshots.
playlists_snapshot playlists Con runtime_snapshots.
playable_runtime_snapshot playable_runtime Con runtime_snapshots.
logical_devices_snapshot logical_devices Cambios de salidas.
timers_snapshot timers Cambios de temporizadores.
audio_controls_snapshot audio_controls Cambios de efectos; comparar revision.
lights_snapshot lights Cambios de luces; comparar revision.

Cada mensaje de dominio tiene el campo de datos del mismo nombre y server_time_ms. Por ejemplo:

{
"type": "players_snapshot",
"players": [],
"server_time_ms": 1712345678901
}

Los mensajes de controles de audio y luces también incluyen una revisión del dominio:

{
"type": "audio_controls_snapshot",
"revision": 5,
"audio_controls": { "revision": 5, "logical_devices": [], "players": [] },
"server_time_ms": 1712345678901
}

Para estos dos dominios, ignora mensajes con revisión inferior a la ya aplicada a ese dominio. No compares revisiones entre dominios. Un state completo restablece la referencia; borra todo el estado local y el seguimiento de revisiones al desconectar. Aplica los otros dominios en orden de recepción.

Solicita runtime_snapshots en hello.features. Sin esta función, los cambios de controles, instrucciones y listas usan estados completos agrupados, salvo respuestas directas a controles. Los cambios solo de actividad de elementos no generan estados completos para clientes sin esta función.

Los cambios en ejecución se agrupan en ciclos de 50 ms. No garantiza un mensaje cada 50 ms ni un registro de todos los cambios intermedios. Un estado completo puede sustituir actualizaciones de dominio pendientes. Consulta el reductor de todos los tipos actuales de instantánea en el ejemplo JavaScript.

Elegir el objetivo correcto

Sección «Elegir el objetivo correcto»
Para… Usa…
Iniciar un botón del proyecto project.categories[].playables[].id como playable_id.
Seleccionar una categoría project.categories[].id como category_id.
Detener, pausar, desplazar o ajustar una instancia en ejecución players[].id como player_id.
Controlar una salida logical_devices[].id como logical_device_id.
Activar un preajuste de volumen control.volume_level_presets[].id como level_id.
Ajustar un efecto id del descriptor como control_id, más un objetivo actual de reproductor o dispositivo lógico.
Ajustar una luz lights.lights[].id como project_light_id.
Reproducir un elemento de lista Posiciones actuales de lista y cola desde cero.
Seleccionar una instrucción Posición actual del reproductor de instrucciones desde cero y path del elemento.
Controlar un temporizador Su posición actual desde cero como timer_index.

Los ID de reproductor describen instancias en ejecución y no deben guardarse como identidad permanente del proyecto. Un elemento puede tener varios reproductores activos. Busca source_playable_id o state_playable_id correspondientes en la instantánea actual y elige explícitamente la instancia deseada. Los nombres sirven para mostrar, pero no tienen por qué ser únicos.

Proyecto y elementos reproducibles

Sección «Proyecto y elementos reproducibles»

project.categories[] contiene, para categorías, id, name, color, is_hidden, el icon_url opcional y playables. Un elemento incluye:

{
"id": "playable-id",
"name": "Wind",
"kind": "sound",
"color": "#3b82f6",
"tags": [],
"is_searchable": true,
"runtime_state_key": "playable-id",
"target_category_id": null
}

Los tipos comunes son sound, video, image, random, timer, playlist, action, webbrowser, category_link y instruction. Tolera tipos nuevos o unsupported. Los metadatos opcionales incluyen icon_url, atajos de teclado e ID configurados de acciones de clic.

playable_runtime contiene entradas con state_playable_id, play_count, is_locked y is_playing. Relaciona el runtime_state_key del elemento, o su id si falta aquel, con state_playable_id. Los elementos vinculados pueden compartir actividad y bloqueo. Este bloqueo del botón del proyecto es distinto del bloqueo de control de un reproductor en ejecución.

Las categorías pueden incluir grid_layout opcional con enabled, columns, rows, pages, positions y revision. Comprueba capabilities.manual_grid_layout antes de seguirlo. Los clientes pueden ignorar estos metadatos y mostrar la lista normal; no existe un comando remoto para editar la distribución.

{
"id": "runtime-player-id",
"kind": "sound",
"title": "Wind",
"color": "#3b82f6",
"panel_position": 0,
"position_seconds": 12.3,
"duration_seconds": 95,
"start_time_seconds": 5,
"stop_time_seconds": 90,
"timeline_duration_seconds": 95,
"volume_percent": 70,
"muted": false,
"is_playing": true,
"is_locked": false,
"loop_enabled": true,
"output_logical_device_id": "main",
"source_playable_id": "playable-id",
"state_playable_id": "playable-id"
}

Usa volume_percent directamente para mostrar. El campo bruto separado volume, si existe, no es un porcentaje que multiplicar por 100; la aplicación puede usar una escala de volumen no lineal.

Los campos de la línea temporal están en segundos. start_time_seconds, stop_time_seconds y timeline_duration_seconds pueden faltar o ser null. Úsalos para relacionar la ventana recortada con la línea temporal de origen al buscar una posición. Otros campos opcionales: remaining_playback_seconds, markers y icon_url.

Salidas y controles compartidos

Sección «Salidas y controles compartidos»

logical_devices[] proporciona id, label, display_label, color, output_role, available, selected y volume_percent. Usa display_label para mostrar y id para comandos.

control expone el volumen del próximo inicio y la categoría seleccionada, más volume_level_presets, active_volume_level_ids y effective_volume_level_id. Los preajustes incluyen id, name, direction (both, up_only o down_only), target_volume_percent, fade_down_ms y fade_up_ms. low_volume_active admite controladores antiguos. Lee los ID activos en la instantánea; otros operadores también pueden cambiarlos.

Listas, instrucciones y temporizadores

Sección «Listas, instrucciones y temporizadores»
Dominio Campos útiles
playlists current_index y playlists[]. Cada lista tiene id, title, autoplay, loop_enabled y queue. Los elementos de cola incluyen playable_id, title y icon_url opcional. Los metadatos de ejecución pueden incluir active_item_id, active_item_title y active_player_id.
instructions current_index y players[]. Los reproductores tienen id, title, has_instruction, waiting_for_go, next_instruction_text y items. Los elementos exponen item_id, title, kind, depth, path, can_set_next, is_next_to_play y is_visibly_playing.
timers Array con id numérico, mode, is_running, is_locked, elapsed_ms, duration_ms, remaining_ms y is_over_time. Los tiempos usan milisegundos.

Para previsualizar GO, prefiere el siguiente elemento más profundo con path no vacío y kind distinto de group; en su defecto, cualquiera de los siguientes más profundos. Para seleccionar el siguiente, usa su path real, no una ruta deducida del título o la profundidad.

Controles de audio y capacidades

Sección «Controles de audio y capacidades»

capabilities.audio_controls[] describe los controles de efectos disponibles. Cada descriptor proporciona:

Campo Significado
id, label Identificador del protocolo y etiqueta visible.
scopes Tipos de objetivo admitidos: logical_device y/o player.
min, max, default_value Límites numéricos nativos y valor de restablecimiento.
suggested_step Paso de ajuste sugerido.
unit, scale Unidad visible y escala. log2 expresa pasos en octavas.
display_multiplier Multiplicar valores nativos para mostrar; dividir la entrada del usuario por este factor antes de enviar.

Por ejemplo, una proporción de 0.5 con display_multiplier: 100 se muestra como 50%. Usa el catálogo anunciado en vez de fijar rangos en el código.

audio_controls contiene revision, logical_devices[] y players[]. Cada objetivo tiene kind, id, label, available, locked y un objeto values que relaciona ID de controles con valores numéricos nativos. Los controles lineales aplican fundidos lineales; los log2, geométricos.

lights contiene revision y lights[]. Cada luz tiene id, name, capability (actualmente level) y available. Su value_percent se omite cuando el adaptador no está disponible. Muéstralo como no disponible, no como cero.

Las entradas pueden incluir una icon_url relativa y opaca, por ejemplo /asset/file?id=opaque-asset-id. Resuélvela respecto a la dirección HTTP del servidor remoto y obténla por HTTP. Los iconos no son mensajes WebSocket.

Usa la URL proporcionada sin construir ID ni enviar rutas de archivos. Guarda los iconos en caché para la sesión actual del servidor y espera nuevos ID tras reiniciar. Los cambios de proyecto pueden dejar recursos no disponibles; ofrece una alternativa si falla una imagen. Las instantáneas no exponen rutas del sistema de archivos local.

Una conexión autenticada puede recibir:

{
"type": "error",
"code": "invalid_value",
"command_id": "eq-change-1",
"message": "Human-readable error description"
}

code y command_id son opcionales. Los errores de audio/luces pueden incluir unknown_control, target_locked, target_not_found, invalid_value, target_unavailable o command_failed. Los comandos antiguos pueden devolver solo message. No interpretes el texto legible como un código estable. Un error puede dejar la conexión abierta; sigue procesando instantáneas.

Límite Comportamiento del cliente
Primer mensaje en 10 segundos Enviar hello al abrir.
16 conexiones WebSocket simultáneas Reutilizar conexiones y cerrar clientes sin uso. Incluye sockets no autenticados.
64 KiB por mensaje/trama entrante Un pequeño comando JSON por mensaje.
Ráfaga de 60 comandos, repuesta a 20 por segundo por conexión Limitar deslizadores y agrupar valores pendientes. Ping y actualización también consumen esta cuota.
Cinco contraseñas incorrectas desde una dirección en 60 segundos Corregir y esperar; nuevas aperturas WebSocket se bloquean durante 60 segundos con HTTP 429 y Retry-After.

Un comando rechazado por el límite de frecuencia no se aplica y devuelve code: "rate_limited". Un exceso continuado puede cerrar la conexión. Respeta Retry-After cuando el cliente exponga la respuesta HTTP. Si un navegador solo indica un fallo tras errores de autenticación repetidos, espera al menos 60 segundos. No repitas a ciegas reproducción, alternancia o GO: puedes activar una segunda acción.

Señal de actividad y reconexión

Sección «Señal de actividad y reconexión»

Si hello_ok.features incluye ping, un cliente autenticado puede enviar {"type":"ping"} y esperar {"type":"pong"}. El control remoto integrado envía un ping cada diez segundos y, en esa comprobación, reconecta si lleva más de 25 segundos sin recibir un mensaje válido. Los dominios sin cambios pueden permanecer en silencio.

Para un controlador persistente:

  1. Desactiva el envío cuando se cierre el socket o falle la señal de actividad.
  2. Borra el estado en caché, ID de reproductores y seguimiento de revisiones.
  3. Reconecta con una espera limitada que aumente tras fallos repetidos. Respeta los errores de autenticación y límites de frecuencia en vez de reintentar continuamente.
  4. Envía un nuevo hello, espera el nuevo state completo y vuelve a identificar objetivos.
  5. Reactiva los controles con ese estado. No repitas inicios, alternancias o GO pendientes tras reconectar.

Las pulsaciones de volumen asociadas a la conexión se liberan al desconectar. Trata la reconexión como una nueva sesión, aunque no cambie la dirección del servidor.

Cambiar Permitir orígenes externos en Sound Show tiene efecto inmediato y desconecta a los clientes actuales. Tras desactivarlo, navegadores de otros orígenes no pueden reconectar. Consulta los controles web personalizados para conocer la configuración y las restricciones del navegador.