HLSEmbeddingPlayer

Cómo insertar un vídeo HLS en tu web (iframe y hls.js)

Guía paso a paso para poner un vídeo HLS en una página web: el reproductor iframe listo para usar, código adaptable, parámetros de URL y tu propio hls.js.

HLS (HTTP Live Streaming) es el formato que usan hoy la mayoría de los sitios web para el vídeo bajo demanda. En lugar de un único archivo MP4 enorme, el vídeo se describe mediante una pequeña lista de reproducción de texto que apunta a varias versiones del mismo vídeo, cada una dividida en segmentos cortos. El reproductor descarga algunos segmentos por adelantado, mide lo rápido que llegan y cambia de versión sobre la marcha. Quien ve el vídeo con conexión móvil recibe una versión ligera, quien tiene fibra recibe la nítida, y nadie espera a que se descargue un archivo entero antes de que aparezca el primer fotograma.

Esta guía muestra dos formas de poner un vídeo HLS de UFOLOAD en tu propia página web: el reproductor listo para usar en un iframe, que lleva alrededor de un minuto, y tu propio elemento <video> controlado por hls.js, que te da control total sobre la página. Ambas usan el mismo stream, así que puedes empezar con el iframe y pasar a hls.js más adelante sin volver a subir nada.

Cómo es un stream HLS de UFOLOAD

Después de subir un archivo, el conversor lo codifica con vídeo H.264 y audio AAC estéreo en entre una y cuatro versiones: 360p, 720p, 1080p y 2160p (4K). Una versión nunca es mayor que el original, así que una subida de 720p produce 720p y 360p, nunca un 1080p escalado. La versión más alta que obtienes depende también de tu plan; la página de precios indica los límites actuales. Si quieres conocer a fondo cómo se eligen los escalones, lee escaleras de bitrate adaptativo.

Cada versión se almacena como un MP4 normal con el índice al principio del archivo. Cuando un espectador inicia la reproducción, la capa de almacenamiento empaqueta esos archivos MP4 en HLS sobre la marcha: una lista de reproducción maestra (master.m3u8) enumera todas las versiones con su ancho de banda de pico, resolución y códecs, y cada versión tiene su propia lista de segmentos de cuatro segundos. Los fotogramas clave se colocan alineados con los límites de los segmentos, lo que permite al reproductor cambiar de calidad limpiamente en mitad de un vídeo.

La lista de reproducción y los segmentos se sirven desde nodos de caché con una cabecera Access-Control-Allow-Origin: *, así que un reproductor que se ejecuta en tu dominio puede solicitarlos directamente. Cada URL está firmada y tiene una fecha de caducidad, algo que importará más adelante, cuando hablemos de hls.js.

Paso 1: sube el vídeo y espera a que esté listo

Sube el archivo desde el panel arrastrándolo o pegando un enlace directo, o usa FTP, WebDAV o la API (consulta subir vídeos por API para ver ejemplos en curl, Python y Node.js). Un archivo pasa por los estados uploading, queued, processing y ready; failed se indica con un motivo y se puede reintentar desde el panel. Los clips cortos están listos en minutos, las películas largas tardan más y los planes de pago tienen una cola de codificación prioritaria.

No tienes que esperar para terminar la página. Si alguien abre el reproductor mientras el archivo aún se procesa, verá un aviso de procesamiento con el progreso, y el reproductor cambiará al vídeo por sí solo cuando termine. Aun así, comprueba que el estado es ready antes de publicar la página, para que tus primeros visitantes no vean una barra de progreso.

Necesitarás el identificador del vídeo. El panel lo muestra en el panel de compartir, y la API lo devuelve como public_id, un código corto de 11 caracteres. Ese código es el que va en la dirección de inserción.

Paso 2: inserta el reproductor con un iframe

El panel te da un fragmento de código iframe justo después de cada subida y en el panel de compartir de cada vídeo. Se parece al primer bloque de abajo. Sustituye VIDEO_ID por el identificador de tu vídeo. La página del reproductor en sí no la indexan los buscadores, que es lo que quieres para una inserción: posiciona tu página, no el marco del reproductor.

Fragmento del panel · html
<iframe width="640" height="360"
  src="https://iframe.andromedans.live/e/VIDEO_ID"
  title="My video"
  frameborder="0"
  allow="autoplay; fullscreen; picture-in-picture"
  allowfullscreen></iframe>

Los tamaños fijos en píxeles se rompen en los teléfonos. Para una página adaptable, envuelve el iframe en un contenedor que mantenga la proporción 16:9 y deja que el marco lo llene. El reproductor ocupa todo el marco, así que el vídeo se escala limpiamente.

Inserción adaptable · html
<div style="position:relative;aspect-ratio:16/9;max-width:960px">
  <iframe src="https://iframe.andromedans.live/e/VIDEO_ID"
    title="My video"
    style="position:absolute;inset:0;width:100%;height:100%;border:0"
    loading="lazy"
    allow="autoplay; fullscreen; picture-in-picture"
    allowfullscreen></iframe>
</div>

Parámetros que puedes añadir a la dirección

  • autoplay=1 inicia la reproducción cuando se carga el reproductor. En la mayoría de los casos los navegadores bloquean la reproducción automática con sonido, así que combínalo con mute=1.
  • mute=1 inicia el vídeo silenciado; el espectador puede activar el sonido en cualquier momento.
  • loop=1 vuelve a empezar el vídeo cuando termina.
  • t=30 inicia la reproducción en el segundo 30, útil para enlazar a un momento concreto de un vídeo largo.

Un parámetro en la dirección siempre prevalece sobre el mismo ajuste del estudio del reproductor. Usa el estudio del reproductor para los valores predeterminados que se aplican en todas partes, como la skin, el color de acento, el logotipo y la disposición de los botones, y usa parámetros cuando una página concreta deba comportarse de otra manera. Incluso puedes tener un perfil de reproductor distinto para cada dominio de inserción.

Consejo

Si el reproductor muestra un mensaje de que la inserción no está permitida, probablemente falta el dominio de tu página en la lista de dominios de inserción permitidos. Consulta bloqueo por dominio y restricciones geográficas para entender cómo funciona esa lista.

Paso 3 (opcional): reproduce el stream con hls.js

El iframe es el camino más corto, pero a veces quieres tu propio marcado: una barra de controles personalizada, el vídeo dentro de un carrusel, eventos de analítica desde tu propio código. Entonces necesitas la dirección de la lista de reproducción y una biblioteca de reproductor. Los navegadores distintos de Safari no reproducen HLS de forma nativa, así que la opción habitual es hls.js, una biblioteca JavaScript que alimenta un elemento <video> estándar con segmentos HLS. Safari e iOS reproducen HLS de forma nativa y no la necesitan.

La dirección de la lista de reproducción es el campo links.playback del objeto de vídeo. Solicítala desde tu servidor con una clave de API, porque la clave nunca debe aparecer en el código del navegador. La misma llamada devuelve links.expires_at, y los enlaces están firmados y tienen un tiempo limitado, así que pide un enlace nuevo cada vez que generes la página en lugar de guardarlo en tu base de datos.

Lado del servidor (Node.js 18+): obtener un enlace firmado a la lista de reproducción · js
const BASE = 'https://ufoload.com/api/v1'

export async function playbackUrl(fileId) {
  const res = await fetch(`${BASE}/files/${fileId}`, {
    headers: { Authorization: `Bearer ${process.env.UFOLOAD_API_KEY}` },
  })
  if (!res.ok) throw new Error(`UFOLOAD API: ${res.status}`)
  const { file, links } = await res.json()
  if (file.status !== 'ready') return null // still processing
  return links.playback // signed master.m3u8 URL
}

Si necesitas una vida útil distinta de la predeterminada, POST /files/{id}/links acepta un ttl de 60 segundos a 30 días y puede vincular el enlace a una dirección IP o a una cookie. La documentación de la API lo explica a fondo. También hay un endpoint público, GET /api/v1/public/files/{id}, que no necesita clave; lo usan las páginas de visualización y de inserción, y sus enlaces son válidos durante seis horas.

En la página, crea el reproductor. El bloque de abajo usa hls.js donde es compatible, recurre a la reproducción nativa en Safari y, en otro caso, muestra un mensaje simple. Aloja tú mismo el archivo de la biblioteca o fija una versión en lugar de cargar la última que haya.

Lado del cliente · html
<video id="player" controls playsinline preload="metadata"
       poster="POSTER_URL" style="width:100%;aspect-ratio:16/9;background:#000"></video>
<script src="/vendor/hls.min.js"></script>
<script>
  const video = document.getElementById('player')
  const src = 'PLAYLIST_URL_FROM_YOUR_SERVER'

  if (window.Hls && Hls.isSupported()) {
    const hls = new Hls()
    hls.loadSource(src)
    hls.attachMedia(video)
    hls.on(Hls.Events.ERROR, (_, data) => {
      if (!data.fatal) return
      if (data.type === Hls.ErrorTypes.NETWORK_ERROR) hls.startLoad()
      else if (data.type === Hls.ErrorTypes.MEDIA_ERROR) hls.recoverMediaError()
      else hls.destroy()
    })
  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = src // Safari, iOS
  } else {
    video.outerHTML = '<p>This browser cannot play HLS video.</p>'
  }
</script>

El objeto de vídeo también incluye links.poster para la imagen de portada y links.sprite para las miniaturas de vista previa al pasar el cursor, que puedes usar si construyes tu propia barra de búsqueda. Con hls.js renuncias a lo que el reproductor de UFOLOAD hace por ti: el menú de calidad, los capítulos, la selección de subtítulos, el logotipo superpuesto y, cuando hay anuncios disponibles, los anuncios. Ese es el verdadero compromiso, y la tabla de abajo lo resume.

iframe o hls.js: cuál usar

PreguntaReproductor iframehls.js en tu página
Tiempo de configuraciónUn minuto, copiar y pegarUna hora o más, además de un pequeño endpoint en el servidor
Funciones del reproductorMenú de calidad, capítulos, subtítulos, vistas previas al pasar el cursor, logotipo, anuncios cuando están disponiblesLo que construyas tú mismo
MonetizaciónCuando hay anuncios disponibles, se muestran y se contabilizan en el reproductorNo disponible, porque la capa de anuncios está en el reproductor de UFOLOAD
EstiloSkin, colores, logotipo y botones en el estudio del reproductorCualquier HTML y CSS que quieras
Caducidad de los enlacesSe gestiona por tiPides un enlace nuevo cada vez que se genera la página
Bloqueo por dominioSe aplican los dominios de inserción permitidosNo se aplica a un enlace que sirves tú mismo, así que usa un TTL corto y vinculación a IP o cookie

Lista de comprobación para resolver problemas

  • Fotograma negro o icono de carga infinito. Abre el panel de red del navegador y busca master.m3u8. Un 403 significa que el enlace ha caducado o que el espectador está bloqueado por una regla de país o IP; solicita un enlace nuevo.
  • El navegador lo bloquea en una página HTTPS. Todo debe ser HTTPS. Nunca pegues una dirección http:// en el iframe ni en hls.js.
  • La reproducción automática no hace nada. Los navegadores bloquean la reproducción automática con sonido. Añade mute=1 o, en hls.js, establece video.muted = true antes de llamar a play().
  • Aviso de procesamiento en lugar del vídeo. El archivo aún no está listo. Consulta GET /files/{id} periódicamente hasta que status sea ready.
  • Solo se reproduce una calidad baja. El reproductor empieza con prudencia y sube en cuanto ha medido el rendimiento de la conexión. Tu plan y tu original también limitan la versión superior; compáralo con los precios y la página de funciones.

Cuando tu página funcione, quizá quieras protegerla del hotlinking o, cuando haya anuncios disponibles, ganar dinero con ella. Ambas cosas se tratan en las siguientes guías: restringe dónde se puede insertar tu vídeo y monetiza tu sitio de vídeo con anuncios en el reproductor. Si aún estás decidiendo dónde alojar tus vídeos, la lista de comprobación para elegir hosting de vídeo enumera qué comparar.

Pruébalo con una cuenta gratuita

Sube un vídeo y obtén un reproductor HLS y una clave de API en minutos. Los límites de cada plan figuran en la página de precios.