
Subir un vídeo es fácil. Convertirlo en un servicio seguro, escalable, medible y completamente integrado con WordPress es un problema de arquitectura.
Un vídeo no es simplemente un archivo MP4 acompañado de un botón de reproducción. Cuando el objetivo es ofrecer alojamiento profesional dentro de una plataforma multisite aparecen muchas más preguntas: ¿cómo se suben archivos de varios gigabytes sin saturar PHP?, ¿cómo se generan distintas resoluciones?, ¿cómo se adapta la calidad al ancho de banda?, ¿cómo se impide el acceso público al archivo original?, ¿cómo se mide el tráfico de cada cliente?, ¿qué ocurre si un proceso falla a mitad?, ¿cómo se eliminan de forma segura todos los archivos derivados?
Para resolverlo construimos una plataforma completa de vídeo sobre WordPress y AWS. No incorporamos un reproductor externo ni envolvimos la API de un proveedor. Diseñamos la ingesta, el procesamiento, la distribución privada, la medición, las cuotas, el panel de gestión y su integración con el multisite.
WordPress no es el problema. El problema es utilizarlo como si fuera 2012.
El problema que queríamos resolver
La plataforma debía permitir que cada sitio del multisite pudiera gestionar sus propios vídeos desde el panel de WordPress, pero sin convertir al servidor web en un intermediario para archivos pesados.
También necesitábamos cumplir varios requisitos operativos:
- Subidas grandes, reanudables y resistentes a interrupciones.
- Procesamiento automático en varias resoluciones.
- Reproducción adaptativa mediante HLS.
- Una copia MP4 progresiva compatible con reproductores nativos y vídeos de fondo.
- Miniaturas, imágenes de portada y previsualizaciones sobre la línea de tiempo.
- Distribución privada mediante CDN.
- Separación estricta entre los vídeos de distintos sitios.
- Medición del tráfico servido a cada cliente.
- Cuotas de almacenamiento, transferencia y procesamiento.
- Operaciones asíncronas recuperables e idempotentes.
- Un sistema de carpetas, playlists y gestión editorial integrado en WordPress.
- Observabilidad suficiente para operar el servicio después del lanzamiento.
La última condición es importante. La arquitectura no se diseñó solamente para que una demostración funcionara. Se diseñó para el día siguiente, cuando hay archivos incompletos, reintentos, concurrencia, costes, eliminaciones, incidencias y clientes utilizando el sistema al mismo tiempo.
Una arquitectura dividida en planos
La solución separa responsabilidades en cuatro grandes áreas:
- Plano de control: WordPress gestiona usuarios, permisos, productos, planes, cuotas, metadatos, carpetas, playlists y estados de los vídeos.
- Plano de procesamiento: AWS coordina la inspección de los archivos, la transcodificación y la generación de derivados.
- Plano de distribución: CloudFront entrega los vídeos mediante credenciales temporales y políticas restringidas.
- Plano de observabilidad: los registros de distribución, las colas, las métricas y las alarmas permiten medir uso, detectar fallos y controlar costes.
Esta separación evita que WordPress tenga que hacer trabajos para los que no está diseñado. WordPress decide quién puede realizar una operación y conserva el estado de negocio. AWS mueve, transforma y distribuye los bytes.
CONTROL PLANE
┌────────────────────────┐
│ WORDPRESS │
│ users · plans · quota │
│ metadata · REST · UI │
└───────────┬────────────┘
│
Authorize / orchestrate
│
▼
┌─────────┐ ┌─────────────────┐
│ Browser │──────▶│ S3 INGEST │
└─────────┘ direct│ private original│
upload └────────┬────────┘
│
▼
┌───────────────┐
│ STEP FUNCTIONS│
└───────┬───────┘
│
┌──────────┴──────────┐
▼ ▼
┌───────────────┐ ┌────────────────┐
│ ECS FARGATE │ │ MEDIACONVERT │
│ ffprobe │ │ HLS / MP4 │
│ sprites │ │ transcoding │
│ scroll video │ └───────┬────────┘
└───────┬───────┘ │
└──────────┬───────────┘
▼
┌───────────────┐
│ S3 OUTPUTS │
│ HLS · MP4 │
│ sprites · VTT │
└───────┬───────┘
│
▼
┌───────────────┐
│ CLOUDFRONT │
│ private CDN │
└───────┬───────┘
│
▼
┌─────────────┐
│ POM PLAYER │
└─────────────┘
OBSERVABILITY / METERING
CloudFront logs
│
▼
S3 ──▶ SQS ──▶ Lambda ──▶ WordPress usage
│
└──▶ DLQ
Step Functions / Lambda / ECS / SQS
│
▼
CloudWatch
Gobierno y costes antes que infraestructura
El primer paso no fue crear recursos. Fue inventariar lo que ya existía.
Revisamos certificados, dominios, distribuciones, identidades, redes y recursos compartidos para evitar duplicidades. Después definimos una etiqueta de coste común para todos los componentes del servicio, un presupuesto mensual y detección de anomalías.
Este orden puede parecer poco espectacular, pero evita uno de los errores más frecuentes en proyectos cloud: construir primero y descubrir después que nadie puede explicar la factura.
La infraestructura del servicio se puede filtrar de forma independiente en las herramientas financieras de AWS. El procesamiento, el almacenamiento, la transferencia y los componentes auxiliares quedan vinculados al mismo producto. Esto permite comparar consumo real, límites comerciales y margen operativo sin depender de estimaciones genéricas.
Subidas multipart sin hacer pasar los vídeos por PHP
Los archivos se suben directamente desde el navegador a un almacenamiento privado de Amazon S3 utilizando multipart upload.
WordPress participa en la autorización, pero no transporta el contenido. Cuando un usuario inicia una subida, el backend comprueba su identidad, sus capacidades, la licencia del sitio, el tamaño máximo permitido, el número de subidas concurrentes y la cuota disponible. Si todo es correcto, crea el registro del vídeo y prepara la operación multipart.

El navegador divide el archivo en partes y las envía directamente a S3 mediante autorizaciones temporales. Esto aporta varias ventajas:
- PHP no necesita aceptar peticiones de varios gigabytes.
- No se consume ancho de banda del servidor de WordPress.
- Una interrupción no obliga a empezar desde cero.
- Las partes pueden enviarse con concurrencia controlada.
- La interfaz puede pausar, reanudar, cancelar y reintentar la subida.
- El progreso refleja los bytes realmente enviados.
El almacenamiento se separa por función. Existe un área privada de ingesta para los originales, otra para las salidas procesadas y otra para los registros operativos. Los buckets bloquean el acceso público, exigen conexiones cifradas y aplican políticas de ciclo de vida específicas.
Las subidas multipart abandonadas se eliminan automáticamente. Los registros se conservan durante un periodo limitado. Los archivos de salida, en cambio, permanecen asociados a la generación activa del vídeo hasta que una operación de borrado autorizada los elimina.
Cuotas resistentes a la concurrencia
Comprobar una cuota con una consulta y actualizarla después no es suficiente. Dos usuarios podrían iniciar operaciones simultáneas y superar el límite antes de que ninguno de los dos procesos hubiese terminado.
Por eso el sistema utiliza reservas. Antes de autorizar una operación costosa, WordPress reserva de forma atómica la parte correspondiente de almacenamiento o procesamiento. Cuando AWS termina, la reserva se reconcilia con el resultado real. Si la operación falla, se libera.
El servicio diferencia además entre varios conceptos:
- El tamaño del archivo original aceptado.
- El almacenamiento lógico incluido en el plan.
- El almacenamiento físico ocupado por todos los derivados.
- Los segundos de procesamiento consumidos.
- La transferencia mensual entregada por la CDN.
- El número de operaciones simultáneas.
Separar estas magnitudes permite aplicar límites comerciales comprensibles sin perder de vista el coste físico de la infraestructura.

Step Functions como columna vertebral
Cuando la subida termina, comienza una ejecución de AWS Step Functions Standard. Elegimos una máquina de estados porque el procesamiento de vídeo no es una única tarea: es una cadena de operaciones distribuidas, con tiempos de ejecución diferentes y posibilidades de fallo independientes.
De forma simplificada, el flujo realiza estas etapas:
- Notifica a WordPress que el vídeo ha entrado en procesamiento.
- Ejecuta una inspección técnica del archivo original.
- Calcula qué salidas debe generar según el vídeo y el plan contratado.
- Reserva la capacidad de procesamiento.
- Envía el trabajo de transcodificación a AWS Elemental MediaConvert.
- Genera los sprites y sus metadatos de navegación.
- Crea derivados opcionales para casos de uso específicos.
- Comprueba que las salidas esperadas existen y no están vacías.
- Calcula el almacenamiento físico resultante.
- Notifica a WordPress que el vídeo está listo.
IMAGEN: Captura REAL de AWS. Captura del gráfico de la State Machine real en AWS Step Functions. Esta es de las capturas que más credibilidad aportan: estados de probe, cálculo outputs, reserva, MediaConvert, sprites, validate/finalize/error cleanup, etc.

Cada estado tiene límites de tiempo, reintentos acotados y una estrategia de error. Si una etapa falla, el workflow no deja el vídeo indefinidamente en un estado ambiguo. Ejecuta la limpieza correspondiente y devuelve un error normalizado al plano de control.
Las notificaciones utilizan identificadores de evento y operaciones idempotentes. Si AWS reintenta una comunicación ya procesada, WordPress puede reconocerla sin aplicar dos veces el mismo cambio.
Inspeccionar antes de transcodificar
Antes de decidir qué versiones generar, un contenedor ejecutado en Amazon ECS Fargate analiza el archivo mediante FFmpeg y ffprobe.
Esta inspección obtiene, entre otros datos, la duración, las dimensiones, la velocidad de fotogramas y la presencia de audio y vídeo válidos. También permite rechazar archivos dañados o incompatibles antes de iniciar una transcodificación más costosa.
El resultado se utiliza para construir un trabajo dinámico. No todas las fuentes necesitan las mismas salidas y no tiene sentido ampliar artificialmente un vídeo de baja resolución.
Si el original tiene 720 píxeles de altura, el sistema no genera versiones 1080p y 2160p que solo añadirían peso y coste. La escalera se limita tanto por la fuente como por las capacidades del plan.
MediaConvert y una escalera adaptada a cada vídeo
AWS Elemental MediaConvert se encarga de la transcodificación principal. El trabajo no depende de una plantilla estática: una función prepara su configuración después de conocer las características del archivo y los límites de la cuenta.
El resultado puede incluir varias resoluciones, desde 360p hasta 2160p, codificadas en H.264 mediante control de calidad variable. Si la fuente contiene audio, se genera una pista AAC compatible con navegadores y dispositivos habituales.
La plataforma produce dos formatos de reproducción principales.

HLS para reproducción adaptativa
HLS, o HTTP Live Streaming, divide el vídeo en pequeños segmentos y publica un manifiesto que describe las distintas calidades disponibles.
El reproductor no descarga necesariamente una única versión completa. Puede empezar con una calidad razonable y cambiar de nivel mientras reproduce. Si aumenta el ancho de banda, puede solicitar segmentos de mayor calidad. Si la red se degrada, puede reducirla antes de que aparezcan pausas prolongadas.
La selección automática tiene en cuenta tanto el ancho de banda observado como el tamaño físico del reproductor. Esto último incluye la densidad de píxeles de la pantalla. Un vídeo pequeño dentro de una pantalla retina puede necesitar una resolución distinta a la de ese mismo contenedor en una pantalla convencional.
El objetivo no es reproducir siempre la versión de mayor resolución. El objetivo es servir la mejor versión que tenga sentido para ese dispositivo, ese contenedor y esa conexión.
MP4 progresivo para compatibilidad y fondos
También se genera una salida MP4 progresiva estándar, optimizada para empezar a reproducirse antes de que el archivo se haya descargado por completo.
Esta versión permite utilizar el vídeo con el reproductor nativo del navegador, con Jarallax y en composiciones de fondo sin cargar el runtime del reproductor HLS. También ofrece una ruta de compatibilidad para integraciones que esperan una URL de vídeo convencional.
La salida progresiva no sustituye a HLS. Resuelve otro problema. HLS ofrece adaptación dinámica y una experiencia más resistente en vídeos largos; el MP4 progresivo aporta simplicidad, compatibilidad y menor sobrecarga en usos visuales.
Por qué MediaConvert no hace todo el trabajo
MediaConvert es muy eficiente transcodificando vídeo, pero la plataforma necesita operaciones que no encajan bien en una plantilla de encoding convencional.
Por eso utilizamos tareas efímeras de ECS Fargate con una imagen Docker propia para ejecutar FFmpeg y ffprobe. Estas tareas realizan tres trabajos especializados:
- Probe: inspección y validación técnica del original.
- Sprites: generación de previsualizaciones para la línea de tiempo.
- Scroll: creación opcional de un derivado corto, ligero, sin audio y optimizado para determinados efectos visuales.
La imagen se construye para Linux y se publica en un repositorio privado de Amazon ECR. Las definiciones de tarea utilizan revisiones inmutables y fijan la imagen por su digest. Así evitamos que una etiqueta reutilizada cambie silenciosamente el software que ejecuta un workflow ya desplegado.
Separar MediaConvert y Fargate nos permite utilizar un servicio gestionado para la transcodificación principal y conservar control sobre las tareas que requieren lógica audiovisual propia.
Sprites: navegar por un vídeo sin reproducirlo
Los sprites son mosaicos de pequeñas capturas extraídas a intervalos regulares. En lugar de solicitar una imagen independiente cada vez que el usuario mueve el cursor sobre la barra de progreso, el reproductor descarga una hoja que contiene muchas miniaturas.
Junto a cada sprite se genera un archivo WebVTT. Este documento indica qué región de la imagen corresponde a cada intervalo temporal. El reproductor puede mostrar así una previsualización precisa sin iniciar el vídeo ni realizar decenas de peticiones.
Es una mejora visible para el usuario, pero también una decisión de rendimiento: menos solicitudes, mejor reutilización de caché y una navegación mucho más rápida.
![]()
Una URL estable sobre archivos inmutables
Los vídeos se insertan en WordPress mediante una URL lógica estable. Esa URL no apunta directamente al archivo de S3 ni contiene una autorización permanente.
Cuando el reproductor necesita comenzar una sesión, solicita los datos de reproducción al backend. WordPress comprueba el sitio, el usuario cuando corresponde, el estado del vídeo y el derecho de uso del servicio. Solo entonces genera una sesión temporal de distribución.
Esta capa de indirección resuelve dos problemas:
- El contenido puede seguir utilizando la misma URL aunque se regenere el vídeo.
- Las rutas físicas y las credenciales de CDN no se almacenan de forma permanente dentro de páginas y plantillas.
Cada procesamiento crea una generación inmutable. Cuando una nueva generación se valida, el activo pasa a señalarla. Una página publicada no necesita conocer sus rutas internas.

Distribución privada con CloudFront
Los originales y derivados no se publican como objetos anónimos de S3. La reproducción se realiza a través de Amazon CloudFront mediante autorizaciones de corta duración y políticas restringidas a la generación correspondiente.
El sitio licenciado es quien puede solicitar una sesión nueva. La resolución del vídeo está además aislada por el identificador del sitio dentro del multisite. Copiar la URL lógica o conservar una URL de CDN caducada no concede acceso permanente.
El sistema tampoco necesita cookies publicitarias o de seguimiento para reproducir el contenido. La autorización se resuelve mediante credenciales temporales de distribución. Los registros utilizados para contabilizar tráfico se diseñan sin depender de cookies ni de perfiles de usuario.
Esto no se presenta como DRM. Ningún sistema reproducible en un navegador puede impedir de forma absoluta una captura de pantalla o la grabación del dispositivo. Lo que sí evitamos es ofrecer públicamente el bucket, una dirección permanente reutilizable o un botón de descarga directa.
La seguridad no depende de ocultar una URL. Depende de varias capas: almacenamiento privado, permisos mínimos, aislamiento entre sitios, validación de licencias, sesiones temporales, rutas limitadas, expiración y callbacks autenticados.
Integración real dentro de WordPress Multisite
WordPress actúa como plano de control de toda la plataforma. El servicio se integra dentro de Pomatio y se activa solamente para los sitios con un entitlement válido.
La cuenta central mantiene la relación entre productos, planes, variaciones de WooCommerce, licencias y sitios. Cada instalación de la red conserva una identidad estable que permite aislar sus activos, carpetas, playlists, consumos y operaciones.
El modelo no se limita a comprobar si un plugin está activo. Evalúa el producto contratado, el plan, su estado, su fecha de validez y las capacidades incluidas. A partir de ahí expone límites como almacenamiento, transferencia, resolución máxima, procesamiento o concurrencia.
Los vídeos no se gestionan como simples adjuntos de la biblioteca de medios. Utilizan tablas específicas e indexadas para representar:
- Activos y generaciones.
- Subidas multipart.
- Carpetas.
- Playlists y elementos ordenados.
- Eventos de callback.
- Reservas de recursos.
- Consumo agregado.
- Operaciones de borrado.
- Eventos de auditoría.
Los cambios de esquema se aplican mediante migraciones versionadas y explícitas. No dejamos que una operación genérica intente reinterpretar la base de datos en cada carga de WordPress.
Callbacks autenticados e idempotentes
Los workflows de AWS necesitan informar a WordPress cuando cambia el estado de un vídeo. Esas comunicaciones no se aceptan como simples peticiones anónimas.
Cada callback contiene una firma criptográfica, una marca temporal y un identificador de evento. WordPress valida la autenticidad, rechaza mensajes fuera de su ventana temporal y registra los eventos ya procesados.
Esta última parte es esencial porque los sistemas distribuidos trabajan, en muchos casos, bajo un modelo de entrega de “al menos una vez”. Un timeout no significa necesariamente que la operación anterior no se ejecutara. La idempotencia permite reintentar sin duplicar consumos, transiciones o eliminaciones.
El panel de gestión
IMAGEN: Captura REAL de WordPress. Screenshot grande de vuestra biblioteca de vídeo dentro de WP: árbol de carpetas, vídeos, estados, buscador, filtros, etc. Aquí sí mostraría producto, no arquitectura. Es probablemente la captura comercial más importante de todo el artículo.
La experiencia administrativa se integra en el área de medios de WordPress. Desde ahí el usuario puede subir vídeos, consultar su estado, organizarlos en carpetas, editar sus datos, reproducir una vista privada, crear playlists y solicitar su eliminación.
La biblioteca incluye búsqueda, filtros, ordenación, paginación y operaciones masivas. El árbol de carpetas permanece visible, muestra recuentos directos y admite reorganización. Las playlists permiten ordenar los vídeos mediante arrastre o controles accesibles de movimiento.
Durante una subida, la interfaz controla las partes multipart, el número de archivos concurrentes, el progreso, los reintentos y la cancelación. Durante el procesamiento, consulta el estado sin obligar al usuario a recargar manualmente la pantalla.
IMAGEN: Captura REAL de WordPress. Interfaz durante una subida real: nombre del vídeo, porcentaje, barra de progreso, velocidad/estado, pausa/cancelación si existen. Si el estado posterior muestra “Processing”, mejor hacer una composición con Uploading → Processing → Ready.
Una precisión importante: aquí no utilizamos React
Es habitual afirmar que cualquier interfaz moderna de WordPress está construida con React. En este caso no sería cierto.
El gestor utiliza JavaScript modular, controladores de vista y la API REST de WordPress sobre una pantalla administrativa renderizada por PHP. También utiliza las herramientas de internacionalización y seguridad de WordPress, pero no carga React ni convierte el panel en una SPA independiente.
La decisión fue deliberada. La aplicación necesitaba una interfaz dinámica, no otro runtime completo. El comportamiento se podía resolver con un paquete más pequeño, menos dependencias y una integración más natural con el panel existente.
React habría sido una opción válida si la complejidad de estados, composición o reutilización de componentes lo hubiera justificado. No lo elegimos por inercia. Saber construir con una tecnología importa; saber cuándo no introducirla importa todavía más.
Esta es una parte importante de cómo trabajamos en POM: la arquitectura responde al problema, no a una lista de palabras de moda.
Una API REST con límites claros
La interfaz administrativa se comunica con controladores REST propios. Cada ruta define los parámetros admitidos, valida sus tipos y comprueba las capacidades del usuario.
Las operaciones que modifican datos requieren autenticación y protección frente a solicitudes externas. Los permisos distinguen entre administrar la configuración del servicio y gestionar la biblioteca editorial, lo que permite trabajar con perfiles como editores o responsables de tienda sin entregarles privilegios de administración general.
Las respuestas no exponen credenciales permanentes ni detalles internos de AWS. La API devuelve solamente la información necesaria para completar la operación actual.
Reproductores integrados con POM Theme
El vídeo se integra también en POM Theme como una fuente self-hosted. Para la plantilla, un vídeo alojado en la plataforma se comporta como un recurso propio, aunque su resolución real pase por el servicio privado de reproducción.
Existen dos estrategias de reproducción:
- Reproductor predeterminado: utiliza el MP4 progresivo y mantiene un comportamiento cercano al vídeo nativo.
- Reproductor personalizado: utiliza Video.js 10, HLS, selección adaptativa de calidad, sprites, velocidades y una apariencia configurable.

Los colores y el aspecto general del reproductor se configuran en el theme. Las opciones específicas de cada vídeo —controles, autoplay, loop, poster o relación de aspecto— permanecen en la instancia correspondiente.
Los scripts de Video.js se cargan solamente cuando una página contiene un reproductor que los necesita. Un vídeo de fondo basado en el MP4 progresivo y Jarallax no tiene por qué descargar el runtime de Video.js.
Esta carga condicional evita que una capacidad audiovisual termine penalizando todas las páginas del sitio.
Autoplay sin ignorar al usuario
La integración contempla varios modos de reproducción automática: al cargar la página, al entrar en el viewport, al pasar el cursor o después de la primera interacción.
Los vídeos de fondo se pausan cuando salen del área visible y cuando la pestaña queda oculta. Si el usuario había detenido manualmente un vídeo, el sistema no lo reanuda por su cuenta. Solo se recuperan las reproducciones iniciadas por la lógica de autoplay.
Este comportamiento mejora el consumo de batería, CPU y ancho de banda. También evita que un vídeo siga transfiriendo segmentos mientras el visitante está mirando otra parte de la página.
En loops HLS cortos, el reproductor conserva los segmentos necesarios para favorecer su reutilización en ciclos posteriores. Cuando el navegador mantiene esos datos en memoria o caché, repetir el vídeo no implica necesariamente volver a transferir todo su contenido desde la CDN.
Cómo medimos el tráfico
El consumo no se calcula multiplicando reproducciones por duración. Se contabilizan los bytes que CloudFront entrega realmente.
Esta diferencia importa. Dos usuarios pueden ver el mismo minuto de vídeo y generar consumos distintos si utilizan resoluciones diferentes. Del mismo modo, una repetición servida desde la caché local del navegador puede no producir una nueva transferencia completa desde la CDN.
CloudFront genera registros de distribución que se almacenan en S3. La llegada de nuevos registros publica eventos en una cola de Amazon SQS. Una función Lambda consume esos mensajes, procesa los registros con límites acotados y agrupa los bytes por sitio y día.

La cola incorpora una dead-letter queue para los mensajes que no pueden procesarse después de varios intentos. Esto evita perder silenciosamente datos de consumo y permite inspeccionar errores sin bloquear el resto del flujo.
La consolidación es idempotente. Un mismo registro no puede sumarse indefinidamente por culpa de un reintento. Los agregados se envían al plano de control mediante callbacks autenticados y terminan formando el consumo mensual del sitio.
Las cuotas siguen periodos UTC y aplican distintos niveles de aviso. Antes de llegar al límite, el panel puede mostrar advertencias. Cerca del máximo se pueden impedir nuevas sesiones sin borrar contenidos ni interrumpir administrativamente la biblioteca.
Eliminación asíncrona y segura
Borrar un vídeo distribuido no consiste en eliminar una fila.
Puede haber un original, varias generaciones, manifiestos, segmentos HLS, MP4 progresivos, portadas, sprites, archivos WebVTT y derivados opcionales. Además, alguna operación anterior puede seguir intentando enviar un callback.
La eliminación utiliza su propia máquina de estados. WordPress marca el activo como pendiente de borrado y crea un token de operación. AWS elimina únicamente los prefijos autorizados y devuelve ese mismo token en cada notificación.
Si llega tarde un callback perteneciente a una operación anterior, WordPress puede reconocer que ya no corresponde a la solicitud vigente. Así evitamos que un reintento antiguo cambie el estado de un vídeo recreado o de una operación posterior.
Una vez confirmada la eliminación física, el plano de control libera el almacenamiento contabilizado y cierra la operación.
Observabilidad para el día después del lanzamiento

Una plataforma distribuida no se puede operar mirando solamente el log de PHP.
Configuramos grupos de logs con retención limitada, un dashboard operativo y alarmas para los puntos que pueden comprometer el servicio:
- Errores y throttling de Lambda.
- Fallos y timeouts de Step Functions.
- Mensajes acumulados en la dead-letter queue.
- Callbacks ausentes.
- Procesos que permanecen demasiado tiempo en ejecución.
- Diferencias entre almacenamiento registrado y almacenamiento físico.
- Errores de reconciliación.
- Anomalías de coste.
No todo puede observarse con las métricas nativas de AWS. La aplicación emite también métricas semánticas: una ejecución iniciada que no quedó registrada, un callback que no llegó o una reserva que no se pudo reconciliar.
Estas señales describen problemas de negocio que una gráfica de CPU nunca podría detectar.
Un modelo de permisos mínimos
Cada componente dispone de una identidad distinta y solo recibe las acciones que necesita.
WordPress puede iniciar subidas y workflows dentro de los recursos del servicio, pero no administrar indiscriminadamente la cuenta de AWS. MediaConvert puede leer los originales y escribir las salidas correspondientes. Las tareas de ECS tienen permisos diferentes de los utilizados para descargar la imagen del contenedor. Las funciones de preparación, finalización, callbacks, borrado y consolidación utilizan roles separados.
Los secretos de firma se almacenan en AWS Secrets Manager. No forman parte de la imagen Docker, del repositorio, de la base de datos editorial ni de las respuestas REST.
Esta fragmentación reduce el radio de impacto de un error o una credencial comprometida. Una función encargada de contabilizar tráfico no necesita poder eliminar vídeos. Un proceso que genera sprites no necesita administrar CloudFront.
El stack tecnológico
La solución combina tecnologías de aplicación, procesamiento audiovisual e infraestructura cloud:
- WordPress Multisite como plano de control.
- PHP para permisos, REST, licencias, cuotas, estados y lógica de negocio.
- WooCommerce para productos, planes y entitlements comerciales.
- MySQL o MariaDB con tablas específicas e índices orientados a las consultas reales.
- JavaScript modular para la interfaz administrativa.
- Subidas multipart desde el navegador.
- POM Theme para la integración editorial y visual.
- Video.js 10 para el reproductor HLS personalizado.
- Jarallax y vídeo nativo para fondos ligeros.
- HLS y CMAF para streaming adaptativo.
- WebVTT para asociar sprites con intervalos temporales.
- Amazon S3 para originales, derivados y registros.
- Amazon CloudFront para distribución privada y caché global.
- AWS Elemental MediaConvert para la transcodificación.
- AWS Step Functions Standard para la orquestación.
- AWS Lambda para preparar, validar, firmar, consolidar y comunicar operaciones.
- Amazon ECS Fargate y ECR para FFmpeg, ffprobe y procesamiento especializado.
- Amazon SQS y dead-letter queues para desacoplar la medición de tráfico.
- AWS IAM, Secrets Manager y ACM para identidades, secretos y TLS.
- Amazon CloudWatch, AWS Budgets y Cost Explorer para operación y control financiero.
- Docker e imágenes inmutables para despliegues reproducibles.
Decisiones que evitaron convertir el sistema en un Frankenstein
Buena parte del trabajo no consistió en añadir componentes, sino en decidir dónde no añadirlos.
- No hicimos pasar archivos pesados por WordPress.
- No utilizamos una Lambda larga para ejecutar todo el procesamiento.
- No intentamos resolver con MediaConvert tareas que requerían lógica propia de FFmpeg.
- No publicamos direcciones permanentes de S3.
- No tratamos una comprobación de cuota como una operación segura frente a concurrencia.
- No mezclamos el estado editorial con el estado físico de los objetos.
- No cargamos Video.js en páginas que no lo necesitan.
- No obligamos a utilizar HLS para un vídeo de fondo sencillo.
- No incorporamos React solamente para poder decir que la interfaz utiliza React.
- No confiamos en que un proceso distribuido envíe cada evento exactamente una vez.
- No dejamos la observabilidad y los costes para después del lanzamiento.
Menos Frankenstein, más sistema.
Lo que este proyecto demuestra
Esta plataforma reúne varias disciplinas que normalmente aparecen separadas: desarrollo WordPress, arquitectura cloud, vídeo, interfaces administrativas, seguridad, sistemas distribuidos, operaciones y diseño de producto.
El resultado no es una colección de servicios de AWS conectados con cinta adhesiva. Es un sistema en el que cada capa conoce su responsabilidad:
- WordPress controla el negocio.
- S3 conserva los objetos.
- Step Functions coordina.
- MediaConvert transcodifica.
- Fargate ejecuta procesamiento especializado.
- CloudFront distribuye.
- SQS desacopla.
- Lambda valida y consolida.
- CloudWatch permite operar.
La parte difícil no fue elegir esos nombres en una consola. Fue definir los contratos entre ellos: qué ocurre al reintentar, cómo se conserva la identidad de una operación, cuándo se reserva una cuota, cómo se valida una salida, qué ruta se puede firmar, quién puede emitir una sesión y cómo se recupera el sistema cuando algo no termina como estaba previsto.
Eso es desarrollo de software aplicado al negocio. Tecnología hecha para trabajar, no para decorar una presentación.
WordPress puede ser una plataforma de software seria
WordPress puede actuar como interfaz editorial y plano de control de sistemas mucho más amplios. No tiene que procesar vídeo, ejecutar inteligencia artificial o almacenar millones de eventos dentro de la misma petición PHP. Puede coordinar servicios especializados manteniendo una experiencia coherente para usuarios, editores y administradores.
La clave está en no confundir integración con acumulación de plugins. Una plataforma profesional necesita límites, modelos de datos, contratos, seguridad, métricas, procesos de recuperación y una arquitectura que siga siendo comprensible cuando crece.
En POM desarrollamos este tipo de sistemas para empresas que necesitan que WordPress se conecte de verdad con sus procesos, sus datos y su infraestructura.
Si tu proyecto ha dejado de ser una web y empieza a comportarse como una plataforma, probablemente ya no necesites otro plugin. Necesitas arquitectura.