# DataFirefly Native Live Shopping — Documentación

> Visión general DataFirefly Native Live Shopping convierte tu tienda WooCommerce en una plataforma de live shopping autónoma, sin dependencia de servicios de terceros tipo Bambuser o CommentSold. La emisión utiliza…

- Página: <https://www.datafirefly.com/es/documentation/dfnativeliveshopping/>
- Idioma: es
- Actualizado el: 2026-07-01
- Otros idiomas: [fr](https://www.datafirefly.com/documentation/dfnativeliveshopping/index.md), [en](https://www.datafirefly.com/en/documentation/dfnativeliveshopping/index.md), [de](https://www.datafirefly.com/de/documentation/dfnativeliveshopping/index.md), [it](https://www.datafirefly.com/it/documentation/dfnativeliveshopping/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfnativeliveshopping/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfnativeliveshopping/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfnativeliveshopping/index.md)
- Índice: <https://www.datafirefly.com/es/documentation/llms.txt>

## Visión general

DataFirefly Native Live Shopping convierte tu tienda WooCommerce en una plataforma de live shopping autónoma, sin dependencia de servicios de terceros tipo Bambuser o CommentSold. La emisión utiliza **WebRTC peer-to-peer mesh** desde el navegador del anfitrión hacia cada espectador, la señalización pasa por la API REST de WordPress y la grabación del replay se realiza del lado del cliente a través de la API MediaRecorder y se almacena como adjuntos de WordPress.

El plugin proporciona:

- Un CPT `dfnls_live_show` para crear y programar tus lives
- Una consola del anfitrión integrada en el admin de WordPress (vista previa de cámara, controles, productos, chat)
- Una experiencia del espectador llave en mano con productos clicables superpuestos y chat
- Un bridge del carrito WooCommerce (añadir al carrito oficial sin abandonar el live)
- Un replay automático sincronizado con los eventos del live (spotlights, cupones, mensajes)
- Un bloque Gutenberg dedicado y el shortcode `[dfnls_live]`

**Arquitectura** — La topología WebRTC mesh es ideal hasta ~25 espectadores simultáneos por anfitrión. Más allá, prevé un servidor TURN externo o considera un SFU. El ancho de banda de subida del anfitrión debe ser de aproximadamente 500 kbps por espectador conectado.

## Requisitos

- **WordPress** 6.3 o superior
- **WooCommerce** 8.0 o superior (compatible HPOS)
- **PHP** 8.1 o superior (probado hasta 8.3)
- **HTTPS obligatorio** — `getUserMedia()` y `getDisplayMedia()` se niegan a funcionar sobre HTTP no seguro
- Navegadores compatibles del lado del espectador: Chrome 80+, Firefox 75+, Edge 80+, Safari 14+, Opera 67+
- Un navegador reciente del lado del anfitrión con cámara y micrófono accesibles

**Importante** — Sin un certificado HTTPS válido (Let's Encrypt basta), la consola del anfitrión no podrá acceder a la cámara ni al micrófono. Prueba en `localhost` o en un dominio con certificado TLS.

## Instalación

1. Descarga el archivo `df-native-live-shopping.zip` desde tu cuenta DataFirefly.
2. En WordPress, ve a _Plugins → Añadir nuevo_ → _Subir plugin_.
3. Selecciona el archivo ZIP y haz clic en _Instalar ahora_.
4. Una vez instalado, haz clic en _Activar plugin_.
5. Un nuevo menú **Live Shopping** aparece en la barra lateral del admin.

En la activación, el plugin:

- Crea 5 tablas personalizadas (`wp_dfnls_signaling`, `_sessions`, `_events`, `_replay_parts`, `_chat`)
- Añade las capabilities `manage_dfnls_lives` y `host_dfnls_lives` a los roles `administrator` y `shop_manager`
- Programa dos crons: purga diaria de replays antiguos, purga horaria de mensajes de señalización obsoletos
- Registra las opciones por defecto (servidores STUN de Google, retención de 90 días, 25 espectadores máx., etc.)

## Primer live en 5 minutos

El camino más corto para lanzar tu primer live:

1. Menú **Live Shopping → Nuevo live**
2. Introduce un título (ej. « Ventas flash primavera »)
3. En la metabox _Productos_, busca y selecciona los productos WooCommerce que quieres presentar (arrastra y suelta para reordenar)
4. Opcional: en _Programación_, define una fecha y hora de inicio (aparecerá una cuenta atrás del lado del espectador)
5. Publica el live
6. Ve a **Live Shopping → Consola del anfitrión** y selecciona tu live
7. Haz clic en _Iniciar emisión_, autoriza el acceso a la cámara y al micrófono
8. Comparte la URL pública del live (`/live/tu-slug/`) con tu audiencia

## Consola del anfitrión

La consola del anfitrión es el panel desde el que animas tu live. Es accesible vía _Live Shopping → Consola del anfitrión_. Funcionalidades:

### Vista previa de vídeo y controles

- **Cámara**: alterna activación/desactivación de la cámara
- **Micrófono**: alterna activación/desactivación del micrófono
- **Compartir pantalla**: reemplaza el flujo de la cámara por compartir pantalla (útil para demos)
- **Iniciar / Detener**: botones de control principal del live

### Destacar productos

La lista de productos vinculados al live aparece a la derecha. Cada producto tiene un botón _Destacar_. Al hacer clic:

- Aparece inmediatamente el producto superpuesto en la pantalla de todos los espectadores
- Registra un evento `product.spotlight` con timestamp para sincronizar el replay
- Un segundo clic en el mismo botón retira la superposición

### Difusión de cupones

Introduce un código promocional (ej. `LIVE20`) y opcionalmente una descripción, luego haz clic en _Difundir_. Un flash animado aparece en la pantalla de los espectadores con un botón « Copiar » para obtener el código con un clic.

### Mensajes del animador

Un campo de texto libre te permite enviar un mensaje que se muestra como banner temporal del lado del espectador (8 segundos por defecto).

### Chat en directo

El chat animador/espectadores está integrado en la consola. Los mensajes del animador se distinguen visualmente (badge y borde rojo) en todas las vistas.

### Registro de actividad

Un log en la parte inferior de la consola muestra en tiempo real las conexiones/desconexiones, los eventos difundidos, las subidas de chunks del replay y los posibles errores.

## Vista del espectador

Lo que vive la audiencia una vez en la URL pública del live:

- **Antes del live** — Si el live está programado, se muestra una pantalla de espera con cuenta atrás hasta la hora prevista. Poll automático del estado cada 5 segundos para detectar el inicio.
- **Durante el live** — Vídeo en directo con pastilla « EN DIRECTO » pulsante y contador de espectadores. Sidebar con dos pestañas: _Productos_ (lista clicable de los productos del live) y _Chat_.
- **Superposición de producto** — Cuando el animador destaca un producto, una tarjeta se desliza en pantalla (por defecto abajo a la derecha) con foto, nombre, precio y botón _Añadir al carrito_.
- **Añadir al carrito** — Un clic en el botón añade el producto al carrito WooCommerce oficial. Aparece un FAB (botón flotante) abajo a la derecha con el contador de artículos del carrito.
- **Cupón flash** — Difundido por el animador, aparece arriba con animación y botón de copia.
- **Después del live** — Si el replay está activado, un botón « Ver el replay » permite volver a reproducir el live con sincronización íntegra de los eventos.

## Ajustes globales

Menú **Live Shopping → Ajustes**. Secciones principales:

### Servidores STUN

Por defecto, se usan los servidores STUN públicos de Google:

```
stun:stun.l.google.com:19302
stun:stun1.l.google.com:19302
```

Puedes añadir tus propios servidores STUN (uno por línea).

### Servidores TURN

Opcional pero recomendado para espectadores detrás de NAT simétrico (algunos operadores 4G, VPN corporativos). Formato:

```
turn:turn.ejemplo.com:3478
turns:turn.ejemplo.com:5349
```

Introduce los credenciales _Usuario TURN_ y _Contraseña TURN_ asociados.

### Grabación y replay

- **Grabación activada**: sí / no global
- **Duración de los chunks** (ms): 5000 por defecto. Más corto = más resiliencia a caídas pero más peticiones; más largo = menos peticiones pero mayor pérdida en caso de caída
- **Retención de replays** (días): 90 por defecto. Más allá, el cron diario elimina automáticamente los archivos WebM y las entradas asociadas

### Capacidad y superposición

- **Número máximo de espectadores por anfitrión**: 25 por defecto. Ajusta según tu ancho de banda de subida
- **Posición de la superposición**: derecha, izquierda o abajo

### Predeterminados por live

- Chat activado por defecto
- Replay activado por defecto
- Inicio de sesión obligatorio por defecto

## Servidores STUN y TURN — cuándo configurar un TURN

STUN es un simple servidor de descubrimiento de IP pública, gratuito y suficiente en ~85 % de los casos. TURN, en cambio, relaya efectivamente el tráfico multimedia: consume ancho de banda, pero permite conectar dos clientes que no pueden llegar directamente el uno al otro.

Configura un TURN si:

- Tus espectadores se quejan regularmente de no ver el vídeo (estado de conexión WebRTC atascado en « connecting »)
- Tu audiencia contiene muchos móviles 4G/5G con operadores de NAT simétrico (Free Mobile en Francia notablemente)
- Tu anfitrión o tus espectadores están detrás de un VPN corporativo estricto

**Solución recomendada** — Desplegar un [coturn](https://github.com/coturn/coturn) auto-alojado en un pequeño VPS (5 a 10 € / mes) basta para 30-40 espectadores simultáneos. Alternativa de pago: Xirsys, Twilio Network Traversal Service.

## Grabación y replay

### Cómo funciona la grabación

La grabación se realiza enteramente **del lado del navegador del anfitrión** vía la API MediaRecorder:

1. Al inicio del live, MediaRecorder se instancia con detección automática del mejor códec disponible (VP9 > VP8 > H.264, opus para audio, ~1,5 Mbps vídeo + 96 kbps audio)
2. Cada 5 segundos (configurable), se dispara un chunk WebM y se sube vía `POST /wp-json/df-nls/v1/shows/{id}/replay/chunk`
3. El chunk se almacena como adjunto WordPress, nombrado `dfnls-show-{id}-part-{NNNNN}.webm`, con `post_parent` apuntando al live
4. La tabla `wp_dfnls_replay_parts` conserva el orden y la duración de cada chunk

### Cómo funciona el replay

Al cargar la página en modo replay:

1. El viewer llama a `GET /wp-json/df-nls/v1/shows/{id}/replay` que devuelve la lista ordenada de segmentos y la timeline de eventos
2. Los segmentos se cargan secuencialmente vía el evento `ended` del `` (fallback nativo)
3. Una variante MediaSource permite la concatenación transparente si el navegador lo soporta
4. La posición de reproducción (tiempo acumulado) se compara con los `offset_ms` de cada evento — cuando el punto se cruza, el viewer dispara localmente el mismo comportamiento que en vivo (mostrar superposición, flash cupón, mensaje)

### Almacenamiento y espacio en disco

Orden de magnitud: un live de una hora a 1,5 Mbps de vídeo + 96 kbps de audio produce aproximadamente **720 MB** de archivos WebM. Con 90 días de retención y 4 lives por mes, cuenta ~10 GB de espacio en disco dedicado a los replays.

**MIME y subida** — El plugin añade un filtro `upload_mimes` para autorizar `video/webm` y `video/mp4` desde la biblioteca multimedia. Verifica que tu servidor no tenga reglas `LimitRequestBody` o `upload_max_filesize` demasiado estrictas (apunta a 20 MB mínimo por chunk).

## Integración: shortcode, bloque, URL directa

### URL pública directa

Cada live publicado posee su propia URL generada automáticamente:

```
https://tu-sitio.com/live/tu-slug/
```

Es la manera más simple: comparte este enlace con tu audiencia.

### Shortcode

Para insertar un live en una página o artículo existente:

```
[dfnls_live id="42"]
[dfnls_live id="42" mode="live"]
[dfnls_live id="42" mode="replay"]
[dfnls_live id="42" mode="auto"]
```

Modos disponibles:

- `auto` (por defecto): detecta el estado del live y muestra live / espera / replay según
- `live`: fuerza la visualización en modo emisión (útil para pruebas)
- `replay`: fuerza el modo replay incluso si el live sigue en curso

### Bloque Gutenberg

En el editor de bloques, busca _« Live Shopping »_. El bloque soporta las alineaciones `wide` y `full`, expone un selector para elegir el live y un selector de modo en la barra lateral del inspector.

### Plantilla PHP personalizada

El CPT usa `templates/single-live-show.php`. Para sobrecargar, copia este archivo en tu tema bajo `tu-tema/df-native-live-shopping/single-live-show.php`.

## Multilingüe con Polylang

El plugin declara el CPT `dfnls_live_show` como traducible en Polylang. En la activación, si Polylang ya está instalado:

- Cada live puede tener una versión FR, EN, ES, DE, IT, etc.
- Los metadatos críticos (`_dfnls_product_ids`, `_dfnls_scheduled_at`, opciones de live) se copian automáticamente entre traducciones
- Los 5 idiomas integrados (FR, EN, ES, DE, IT) se cargan automáticamente según la locale de WordPress

**Consejo Polylang Pro** — Si usas Polylang Pro y tus productos WooCommerce están traducidos ellos mismos, cada traducción del live debe estar asociada con la versión lingüística correspondiente de los productos. El plugin no realiza mapeo automático entre idiomas sobre los IDs de productos.

## HPOS y compatibilidades

El plugin declara oficialmente su compatibilidad con el almacenamiento de alto rendimiento de pedidos de WooCommerce (HPOS) vía `FeaturesUtil`. Puedes activar HPOS en tu instalación sin riesgo de disfunción del bridge de carrito.

Compatible también con:

- WordPress Multisite (instalación por sitio, sin modo red)
- Hosting compartido (o2switch, OVH, Infomaniak, PlanetHoster) — la señalización usa polling REST, sin WebSocket
- Plugins de caché (WP Rocket, WP Super Cache) — los endpoints REST del plugin se excluyen automáticamente

## Seguridad y capabilities

El plugin añade dos capabilities dedicadas:

- `manage_dfnls_lives` — creación, edición, eliminación de lives; acceso a los ajustes
- `host_dfnls_lives` — acceso a la consola del anfitrión, inicio / parada de un live

Ambas capabilities se asignan por defecto a los roles `administrator` y `shop_manager`. Para dar a un usuario únicamente el derecho de animar sin poder crear lives:

```
$user = get_user_by('login', 'presentador');
$user->add_cap('host_dfnls_lives');
```

### Nonces REST

Todas las rutas de acción (POST) están protegidas por nonce `wp_rest`. El viewer y el host reciben su nonce respectivo vía `wp_localize_script` al cargar la página.

### Validación MIME uploads

La subida de chunks replay se valida estrictamente vía `wp_check_filetype_and_ext` para aceptar únicamente `video/webm` y `video/mp4`. Los archivos se renombran del lado del servidor (`dfnls-show-{id}-part-{NNNNN}.webm`).

## Cron y mantenimiento

Dos crons WordPress están programados en la activación:

- `dfnls_cleanup_expired_replays` — **diario**. Elimina los replays de lives terminados hace más de N días (retención configurable). Usa `wp_delete_attachment(..., true)` para eliminar también el archivo físico.
- `dfnls_cleanup_stale_signaling` — **horario**. Purga los mensajes de señalización de más de 24 h y las sesiones inactivas de más de 90 segundos.

**WP-Cron desactivado** — Si has desactivado WP-Cron a favor de un cron del sistema, asegúrate de llamar a `wp-cron.php` al menos una vez por hora para que las purgas se ejecuten.

## Para desarrolladores — API REST

Todas las rutas están bajo el namespace `df-nls/v1`.

### Show

- `GET /shows/{id}` — recupera un live (estado, productos, opciones)
- `POST /shows/{id}/join` — se une como viewer o host (body: `peer_id`, `role`)
- `POST /shows/{id}/leave` — sale limpiamente
- `POST /shows/{id}/heartbeat` — mantiene la sesión abierta (auto cada 15 s del lado del viewer)
- `POST /shows/{id}/start` — inicia el live (host únicamente)
- `POST /shows/{id}/end` — termina el live (host únicamente)
- `GET /shows/{id}/viewers` — contador de espectadores activos

### Signaling WebRTC

- `POST /signal/send` — envía un mensaje SDP/ICE a un peer remoto
- `GET /signal/pull?peer={id}` — recupera los mensajes pendientes y realiza un heartbeat implícito

### Events

- `POST /shows/{id}/event` — registra un evento (spotlight, mensaje, cupón)
- `GET /shows/{id}/events?since={id}` — pull de eventos desde un ID dado

### Chat

- `GET /shows/{id}/chat?since={id}` — pull de mensajes desde un ID
- `POST /shows/{id}/chat` — envía un mensaje

### Cart bridge

- `POST /cart/add` — añade un producto al carrito con seguimiento de origen (`show_id`, `product_id`, `quantity`)
- `GET /cart/summary` — contador y total del carrito actual

### Recording y replay

- `POST /shows/{id}/replay/chunk` — subida multipart de un chunk WebM
- `GET /shows/{id}/replay` — segmentos + timeline events para lectura

## Estructura del plugin (PSR-4)

```
df-native-live-shopping/
├── df-native-live-shopping.php        # Bootstrap
├── uninstall.php
├── readme.txt
├── assets/
│   ├── js/    (host.js, viewer.js, admin.js, block-editor.js)
│   └── css/   (host.css, viewer.css, admin.css)
├── languages/                          # 5 .po/.mo + .pot
├── templates/                          # single-live-show.php, viewer-container.php, ...
└── src/
    ├── Plugin.php
    ├── Activator.php   Deactivator.php
    ├── PostType/       (LiveShow.php)
    ├── Database/       (Schema + 5 Repository.php)
    ├── Admin/          (AdminPages, MetaBoxes, SettingsPage)
    ├── Api/            (RestController, SignalingController, CartController)
    ├── Recording/      (RecordingHandler)
    ├── Replay/         (ReplayHandler)
    ├── Frontend/       (Renderer, Shortcode, Block)
    └── Compat/         (PolylangCompat)
```

Namespace raíz: `DataFirefly / NativeLiveShopping`, autoloader manual PSR-4 declarado en `df-native-live-shopping.php`.

## Resolución de problemas

### Los espectadores no ven el vídeo

- Verifica que el sitio esté en HTTPS (obligatorio para WebRTC)
- Abre la consola del navegador del lado del espectador, busca los errores `ICE failed` o `connection state failed`
- Configura un servidor TURN si la audiencia contiene muchos móviles 4G
- Verifica que el ancho de banda de subida del anfitrión sea suficiente (utilidad fast.com del lado del anfitrión)

### La consola del anfitrión no detecta la cámara

- Verifica que el navegador haya concedido la autorización (icono candado en la barra de URL)
- En macOS, verifica los permisos del sistema: _Preferencias → Seguridad → Cámara_
- Cierra las otras aplicaciones que usen la cámara (Zoom, Teams, OBS...)

### Los chunks del replay no se suben

- Verifica `upload_max_filesize` y `post_max_size` en php.ini (apunta a 20 MB mínimo)
- Verifica `LimitRequestBody` del lado Apache si aplica
- Mira el registro de actividad de la consola del anfitrión para identificar el error exacto
- Verifica los permisos de la carpeta `wp-content/uploads`

### El carrito no conserva los añadidos

- Verifica que ningún plugin de caché cachee los endpoints `/wp-json/df-nls/v1/*`
- Verifica que las cookies WooCommerce (`woocommerce_cart_hash`, `wp_woocommerce_session_*`) se emitan correctamente
- En HTTPS estricto, verifica que las cookies tengan la flag `Secure`

### Los replays ocupan demasiado espacio

- Reduce la retención (por ej. de 90 a 30 días) en los ajustes
- Desactiva la grabación para los lives donde no sea necesaria (casilla « Permitir replay » en la metabox _Opciones_)
- Reduce el bitrate modificando `host.js` (variable `videoBitsPerSecond`)

## Desinstalación

En la desactivación simple, los datos se conservan y los crons se desprograman. En la **eliminación completa** del plugin desde _Plugins_, `uninstall.php` realiza:

- Eliminación de las 5 tablas personalizadas
- Eliminación de todas las opciones `dfnls_*`
- Retirada de las capabilities de los roles
- Desprogramación de los crons
- Opcional: eliminación de los CPT y de todos los adjuntos replay si la opción `dfnls_uninstall_delete_data` se activó antes de la desinstalación

**Atención** — Por defecto, los lives y sus replays NO se eliminan en la desinstalación. Para eliminar todo, activa la opción _Eliminar todos los datos al desinstalar_ en los ajustes antes de desinstalar.

## Soporte y evoluciones

Soporte técnico incluido durante 12 meses vía el área de cliente DataFirefly. Las actualizaciones del plugin están disponibles desde tu cuenta, con notificación por email de las versiones mayores.

Ideas de evolución en la hoja de ruta:

- Basculación SFU automática más allá de un umbral de espectadores
- Encuestas live (poll.open / poll.close ya reservados en el protocolo de eventos)
- Analíticas nativas (tiempo medio de visionado, tasa de conversión por live)
- Multi-anfitriones (dos animadores simultáneos)
