restreamer-ui-v2/WHIP_UI_INTEGRATION_PROMPT.md
Cesar Mendivil 00e98a19b3 feat: add InternalWHIP component and associated tests
- Implemented the InternalWHIP component for managing WHIP server configurations.
- Added functionality to load live WHIP state from Core and handle OBS URL generation.
- Included polling for active streams and notifying parent components of state changes.
- Created comprehensive tests for the InternalWHIP component covering various scenarios including fallback mechanisms and state changes.

test: add integration tests for WHIP source component

- Developed end-to-end tests for the InternalWHIP component to verify its behavior under different configurations.
- Ensured that the component correctly handles the loading of WHIP state, displays appropriate messages, and emits the correct onChange events.

test: add Settings WHIP configuration tests

- Implemented tests for the WHIP settings tab to validate loading and saving of WHIP configurations.
- Verified that the correct values are sent back to the Core when the user saves changes.
- Ensured that the UI reflects the current state of the WHIP configuration after Core restarts or changes.
2026-03-14 12:27:53 -07:00

14 KiB

Prompt de integración WHIP para Restreamer UI

Este documento es el brief técnico completo para adaptar la UI de Restreamer de modo que exponga el servidor WHIP del Core de la misma manera que ya expone RTMP Server. Incluye dos casos de uso: WHIP Server (panel de estado + URL para OBS) y WHIP Receive mode (fuente de entrada en un proceso).


Contexto del Core

El Core de datarhei expone las siguientes APIs relevantes:

Config (GET /api/v3/config)

La sección whip dentro de config tiene esta forma:

"whip": {
  "enable": true,
  "address": ":8555",
  "token": ""
}

El campo address puede ser :8555 (solo puerto) o host:8555.

Canales activos (GET /api/v3/whip)

Devuelve la lista de streams que OBS/clientes están publicando en este momento:

[
  {
    "name": "9VGyRCkCVCgj",
    "published_at": "2026-03-14T02:51:36.799550551Z"
  }
]

URL de publicación WHIP (para OBS)

http://<host>:<whip_port>/whip/<stream_key>

Ejemplo: http://192.168.1.15:8555/whip/mistream

URL de relay SDP (para FFmpeg / proceso interno)

http://localhost:<whip_port>/whip/<stream_key>/sdp

Esta es la URL que el Core inyecta automáticamente con {whip} como placeholder de input.

Placeholder de proceso

En el config de un proceso de FFmpeg, el input address puede usar:

{whip:name=<stream_key>}

El Core lo expande a http://localhost:<whip_port>/whip/<stream_key>/sdp y agrega automáticamente -protocol_whitelist file,crypto,http,rtp,udp,tcp en las input options.


Parte 1 — Panel "WHIP Server" (equivalente a "RTMP Server")

Dónde ubicarlo

En la misma sección de configuración/status donde aparece RTMP Server y SRT Server. Añadir una tarjeta o sección llamada WHIP Server.

Comportamiento esperado

1.1 Indicador de estado

  • Leer config.whip.enable de GET /api/v3/config
  • Mostrar badge Enabled (verde) / Disabled (gris)
  • Mostrar el puerto: extraer de config.whip.address (ej. :85558555)

1.2 Campo "Stream URL para OBS"

Construir la URL de publicación a mostrar:

http://<host_público>:<whip_port>/whip/
  • host_público: usar config.host.name[0] si config.host.auto === true, o el primer valor de config.host.name
  • whip_port: extraer de config.whip.address
  • Mostrar un campo de texto read-only con botón Copiar
  • Indicar al usuario que al final de la URL debe agregar su stream key (ej. mistream)

Ejemplo visual:

┌─────────────────────────────────────────────────────┐
│  WHIP Server URL                                    │
│  http://192.168.1.15:8555/whip/          [Copiar]   │
│  Ingresá tu stream key al final de la URL           │
└─────────────────────────────────────────────────────┘

1.3 Campo "Stream Key"

  • Input de texto editable donde el usuario escribe su stream key (ej. mistream, obs-live, etc.)
  • Al escribirla, actualizar dinámicamente la URL completa a copiar: http://192.168.1.15:8555/whip/mistream
  • Botón Copiar URL completa

1.4 Token de autenticación (opcional)

  • Si config.whip.token no está vacío, mostrar un aviso: "Este servidor requiere un token. Agregá ?token=<token> al final de la URL."
  • Opcionalmente, ofrecer un checkbox "Incluir token en la URL" que lo appende automáticamente.

1.5 Tabla de streams activos

  • Hacer polling a GET /api/v3/whip cada 5 segundos
  • Mostrar una tabla con columnas: Stream Key | Publicando desde
  • Si la lista está vacía, mostrar "Sin streams activos"
┌──────────────────┬──────────────────────┐
│ Stream Key       │ Publicando desde      │
├──────────────────┼──────────────────────┤
│ 9VGyRCkCVCgj    │ hace 3 minutos        │
│ mistream         │ hace 12 segundos      │
└──────────────────┴──────────────────────┘

1.6 Configuración WHIP (settings)

Sección colapsable o en la misma pantalla de configuración del Core:

  • Toggle Habilitar WHIP Server → modifica config.whip.enable via PATCH /api/v3/config
  • Campo Puerto → modifica config.whip.address
  • Campo Token → modifica config.whip.token

Parte 2 — Modo de recepción WHIP ("Receive mode")

Dónde ubicarlo

En el wizard de creación/edición de un proceso (input source selector), junto a las opciones existentes como:

  • Network Source (HLS, RTP, RTSP, etc.)
  • RTMP Source
  • SRT Source
  • WHIP Source ← (nueva opción)

Comportamiento esperado

2.1 Selector de protocolo

En la lista de protocolos de entrada agregar la opción:

WHIP (WebRTC HTTP Ingestion Protocol)

2.2 Formulario de configuración de la fuente WHIP

Al seleccionar WHIP como fuente, mostrar:

Stream Key — campo de texto editable
(Se recomienda usar el ID del proceso por defecto, o dejar que el usuario lo cambie)

URL de publicación para OBS (campo read-only + botón Copiar):

http://<host_público>:<whip_port>/whip/<stream_key>

Actualiza en tiempo real mientras el usuario escribe el stream key.

┌──────────────────────────────────────────────────────┐
│  Protocolo de entrada: WHIP                          │
│                                                      │
│  Stream Key:  [mistream               ]              │
│                                                      │
│  URL para OBS (copiar en OBS → Servicio WHIP):       │
│  http://192.168.1.15:8555/whip/mistream   [Copiar]   │
│                                                      │
│  Estado: ● Esperando publicador...                   │
│           ✓ Transmitiendo  (si hay publisher activo) │
└──────────────────────────────────────────────────────┘

2.3 Indicador de estado en tiempo real

  • Consultar GET /api/v3/whip cada 5 segundos
  • Si name === stream_key aparece en la lista → mostrar "✓ Transmitiendo" (verde)
  • Si no → "● Esperando publicador..." (gris/naranja)

2.4 Address interno del proceso

Cuando el usuario guarda el proceso, el input.address debe configurarse como:

{whip:name=<stream_key>}

El Core lo expande a http://localhost:<whip_port>/whip/<stream_key>/sdp y agrega -protocol_whitelist automáticamente.

Si la UI no soporta el placeholder {whip}, puede usar directamente:

http://localhost:<whip_port>/whip/<stream_key>/sdp

Y agregar en input.options (ANTES de la URL, es decir, al principio del array):

["-protocol_whitelist", "file,crypto,http,rtp,udp,tcp"]

IMPORTANTE: -protocol_whitelist file,crypto,http,rtp,udp,tcp debe estar presente para que FFmpeg pueda abrir los sub-protocolos RTP/UDP anidados dentro de la URL HTTP. Sin esta opción el probe devuelve 0x0 none.

2.5 Probe automático

Cuando el usuario hace clic en "Probe" o "Detectar streams":

  • La UI puede invocar GET /api/v3/process/<id>/probe si el proceso ya existe
  • O construir un payload de probe temporal equivalente
  • El resultado correcto debe ser: Video: h264, yuv420p, 1920x1080, 30fps + Audio: opus, 48000 Hz, stereo

Parte 3 — API endpoints completos de WHIP

3.1 GET /api/v3/whip

Lista todos los publishers activos en este momento.

Response 200:

[
  {
    "name": "mistream",
    "published_at": "2026-03-14T02:51:36.799550551Z"
  }
]

Usar con polling cada 5s para el panel de streams activos y el indicador de estado en Receive mode.


3.2 GET /api/v3/whip/url nuevo

Devuelve la URL base del servidor WHIP y toda la info que la UI necesita para el panel "WHIP Server".

Response 200:

{
  "base_publish_url": "http://192.168.1.15:8555/whip/",
  "base_sdp_url": "http://localhost:8555/whip/",
  "has_token": false,
  "example_obs_url": "http://192.168.1.15:8555/whip/<stream-key>",
  "input_address_template": "{whip:name=<stream-key>}"
}
  • base_publish_url → mostrar en el panel WHIP Server; el usuario agrega su stream key al final
  • has_token → si es true, mostrar aviso de token y el campo para incluirlo en la URL
  • example_obs_url → texto de ayuda con placeholder visual
  • input_address_template → usar como input.address al crear un proceso con WHIP como fuente

3.3 GET /api/v3/whip/:name/url nuevo

Devuelve la URL completa de publicación para un stream key específico. Este es el endpoint principal para generar la URL que el usuario copia en OBS.

Ejemplo: GET /api/v3/whip/mistream/url

Response 200:

{
  "publish_url": "http://192.168.1.15:8555/whip/mistream",
  "sdp_url": "http://localhost:8555/whip/mistream/sdp",
  "stream_key": "mistream"
}
  • publish_url → campo read-only en la UI con botón Copiar. Es exactamente la URL que se pega en OBS → Configuración → Transmisión → Servidor.
  • sdp_url → URL interna para FFmpeg (referencia, no se muestra al usuario en general).
  • stream_key → confirmación del key procesado.

Flujo de uso en la UI:

  1. Usuario escribe el stream key en el campo de texto
  2. UI llama GET /api/v3/whip/<stream_key>/url
  3. UI muestra publish_url en campo read-only con botón Copiar
  4. Usuario copia y pega en OBS

3.4 GET /api/v3/config

Leer configuración del servidor WHIP para el panel de settings.

Campos relevantes en la respuesta:

{
  "config": {
    "host": {
      "name": ["192.168.1.15"],
      "auto": true
    },
    "whip": {
      "enable": true,
      "address": ":8555",
      "token": ""
    }
  }
}

3.5 PATCH /api/v3/config (o PUT)

Modificar configuración WHIP desde el panel de settings.

Body:

{
  "whip": {
    "enable": true,
    "address": ":8555",
    "token": "mi-token-secreto"
  }
}

3.6 POST /api/v3/process

Crear un proceso con WHIP como fuente de entrada.

Body:

{
  "id": "mi-proceso",
  "reference": "mi-proceso",
  "input": [
    {
      "id": "in",
      "address": "{whip:name=mistream}",
      "options": []
    }
  ],
  "output": [
    {
      "id": "out",
      "address": "rtmp://...",
      "options": ["-c", "copy", "-f", "flv"]
    }
  ],
  "options": ["-loglevel", "level+info"]
}

El Core expande {whip:name=mistream}http://localhost:8555/whip/mistream/sdp e inyecta automáticamente -protocol_whitelist file,crypto,http,rtp,udp,tcp.

Si la UI no usa el placeholder {whip}, usar directamente:

{
  "address": "http://localhost:8555/whip/mistream/sdp",
  "options": ["-protocol_whitelist", "file,crypto,http,rtp,udp,tcp"]
}

3.7 GET /api/v3/process/:id/probe

Obtener información del stream (resolución, codec, fps) una vez el proceso existe.

Response 200 (cuando OBS está transmitiendo):

{
  "streams": [
    {
      "type": "video",
      "codec": "h264",
      "width": 1920,
      "height": 1080,
      "fps": 30,
      "pix_fmt": "yuv420p"
    },
    {
      "type": "audio",
      "codec": "opus",
      "sampling_hz": 48000,
      "layout": "stereo",
      "channels": 2
    }
  ]
}

Tabla resumen

Endpoint Método Cuándo usarlo
/api/v3/whip GET Polling streams activos (cada 5s)
/api/v3/whip/url GET Panel WHIP Server — info base del servidor
/api/v3/whip/:name/url GET Generar URL para OBS dado un stream key
/api/v3/config GET Leer estado enable/disable, puerto, token
/api/v3/config PATCH Cambiar configuración desde settings
/api/v3/process POST Crear proceso con WHIP como input
/api/v3/process/:id/probe GET Detectar resolución/codec del stream

Parte 4 — Instrucciones para el usuario en la UI

En el panel WHIP Server

Cómo transmitir desde OBS:
1. Abrí OBS → Configuración → Transmisión
2. Servicio: Personalizado
3. Servidor: http://<host>:<puerto>/whip/<tu-stream-key>
4. Clave de retransmisión: (dejar vacío)
5. Hacé clic en "Iniciar transmisión"

En el Receive mode WHIP

Ingresá tu stream key, copiá la URL y configurala en OBS.
El proceso comenzará a recibir video cuando OBS empiece a transmitir.

Notas técnicas para el desarrollador de la UI

  1. Compatibilidad de OBS: OBS 30+ soporta WHIP nativo. En Configuración → Transmisión, seleccionar "Servicio: Personalizado" y pegar la URL completa.

  2. ICE / WebRTC: El Core maneja ICE + DTLS-SRTP internamente. La UI no necesita gestionar nada de WebRTC, solo mostrar la URL HTTP.

  3. Protocolo WHIP: El cliente (OBS) hace un POST /whip/<key> con SDP offer → el Core responde con SDP answer → ICE handshake → fluye RTP → el Core lo relay internamente a FFmpeg.

  4. protocol_whitelist: Es obligatorio cuando FFmpeg lee la URL /whip/<key>/sdp. El Core lo inyecta automáticamente cuando detecta la URL en el config del proceso, pero si la UI construye el comando FFmpeg directamente debe asegurarse de incluirlo.

  5. Token de autenticación: Si config.whip.token está configurado, la URL de publicación para OBS debe incluirlo como query param: ?token=<value>. El OBS lo enviará en cada request al WHIP endpoint.

  6. Puertos: Por defecto el WHIP server escucha en :8555 (HTTP, sin TLS). El Core HTTP principal escucha en :8080. Son servidores independientes.

  7. Múltiples publishers: El servidor WHIP soporta múltiples stream keys simultáneos. Cada stream key es independiente y genera su propio relay interno.