HLSEmbeddingPlayer

Como incorporar um vídeo HLS no seu site (iframe e hls.js)

Guia passo a passo para colocar um vídeo HLS numa página: o player pronto em iframe, marcação responsiva, parâmetros de URL e a sua própria configuração hls.js.

HLS (HTTP Live Streaming) é o formato que a maioria dos sites usa hoje para vídeo sob demanda. Em vez de um único arquivo MP4 enorme, o vídeo é descrito por uma pequena playlist de texto que aponta para várias versões do mesmo vídeo, cada uma cortada em segmentos curtos. O player baixa alguns segmentos à frente, mede a velocidade com que chegam e troca de versão em tempo real. Quem está numa conexão de celular recebe uma versão leve, quem tem fibra recebe a mais nítida, e ninguém espera o arquivo inteiro baixar antes de aparecer o primeiro quadro.

Este guia mostra duas formas de colocar um vídeo HLS da UFOLOAD na sua própria página: o player pronto em iframe, que leva cerca de um minuto, e o seu próprio elemento <video> controlado pelo hls.js, que dá controle total sobre a página. Os dois usam o mesmo stream, então você pode começar com o iframe e passar para o hls.js depois sem reenviar nada.

Como é um stream HLS da UFOLOAD

Depois que você envia um arquivo, o conversor o codifica com vídeo H.264 e áudio AAC estéreo em uma a quatro versões, chamadas renditions: 360p, 720p, 1080p e 2160p (4K). Uma versão nunca é maior que o original, então um envio em 720p gera 720p e 360p, nunca um 1080p ampliado. A versão mais alta que você realmente recebe também depende do plano; a página de preços lista os limites atuais. Para entender em detalhes como os degraus são escolhidos, leia escadas de bitrate adaptativo explicadas.

Cada versão é armazenada como um MP4 comum com o índice no início do arquivo. Quando um espectador inicia a reprodução, a camada de armazenamento empacota esses MP4 em HLS em tempo real: uma playlist master (master.m3u8) lista todas as versões com banda de pico, resolução e codecs, e cada versão tem a sua própria playlist de segmentos de quatro segundos. Os keyframes são posicionados para coincidir com as fronteiras dos segmentos, e é isso que permite ao player trocar de qualidade de forma limpa no meio do vídeo.

A playlist e os segmentos são servidos por nós de cache com o cabeçalho Access-Control-Allow-Origin: *, então um player rodando no seu domínio pode solicitá-los diretamente. Toda URL é assinada e tem prazo de validade, o que vai importar mais adiante, quando falarmos da abordagem com hls.js.

Passo 1: envie o vídeo e espere ficar pronto

Envie pelo painel arrastando o arquivo ou colando um link direto, ou use FTP, WebDAV ou a API (veja envio de vídeos via API para exemplos em curl, Python e Node.js). Um arquivo passa pelos status uploading, queued, processing e ready; failed é informado com um motivo e pode ser tentado novamente pelo painel. Clipes curtos ficam prontos em minutos, filmes longos demoram mais, e os planos pagos têm fila de codificação prioritária.

Você não precisa esperar a página ficar pronta. Se alguém abrir o player enquanto o arquivo ainda está sendo processado, ele mostra um aviso de processamento com o progresso e passa sozinho para o vídeo quando o processamento termina. Ainda assim, confirme que o status é ready antes de publicar a página, para não lançar uma página cujos primeiros visitantes veem uma barra de progresso.

Você vai precisar do identificador do vídeo. O painel o mostra no painel de compartilhamento, e a API o retorna como public_id, um código curto de 11 caracteres. É esse código que vai no endereço de incorporação.

Passo 2: incorpore o player com um iframe

O painel fornece um trecho de iframe logo após o envio e no painel de compartilhamento de cada vídeo. Ele se parece com o primeiro bloco abaixo. Substitua VIDEO_ID pelo identificador do seu vídeo. A página do player em si não é indexada pelos mecanismos de busca, que é o que você quer numa incorporação: quem ranqueia é a sua página, não o frame do player.

Trecho do painel · 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>

Tamanhos fixos em pixels quebram no celular. Para uma página responsiva, coloque o iframe dentro de uma caixa que mantém a proporção 16:9 e deixe o frame preenchê-la. O player ocupa o frame inteiro, então o vídeo se ajusta sem distorções.

Incorporação responsiva · 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 você pode adicionar ao endereço

  • autoplay=1 inicia a reprodução quando o player carrega. Na maioria dos casos os navegadores bloqueiam a reprodução automática com som, então combine com mute=1.
  • mute=1 inicia o vídeo sem som; o espectador pode ativar o som a qualquer momento.
  • loop=1 reinicia o vídeo quando ele termina.
  • t=30 inicia a reprodução aos 30 segundos, útil para links diretos para um momento de um vídeo mais longo.

Um parâmetro no endereço sempre prevalece sobre a mesma configuração no estúdio do player. Use o estúdio do player para padrões que valem em todo lugar, como skin, cor de destaque, logotipo e disposição dos botões, e use parâmetros quando uma página precisa se comportar de outro jeito. Você pode até manter um perfil de player separado para cada domínio de incorporação.

Dica

Se o player mostrar uma mensagem dizendo que a incorporação não é permitida, provavelmente o domínio da sua página está faltando na lista de domínios de incorporação permitidos. Veja bloqueio por domínio e restrições geográficas para entender como essa lista funciona.

Passo 3 (opcional): reproduza o stream com hls.js

O iframe é o caminho mais curto, mas às vezes você quer a sua própria marcação: uma barra de controles personalizada, o vídeo dentro de um carrossel, eventos de analytics do seu próprio código. Aí você precisa do endereço da playlist e de uma biblioteca de player. Navegadores que não são o Safari não reproduzem HLS nativamente, então a escolha usual é o hls.js, uma biblioteca JavaScript que alimenta um elemento <video> padrão com segmentos HLS. O Safari e o iOS reproduzem HLS nativamente e não precisam dela.

O endereço da playlist é o campo links.playback do objeto do vídeo. Solicite-o a partir do seu servidor com uma chave de API, porque a chave nunca deve aparecer no código do navegador. A mesma chamada retorna links.expires_at, e os links são assinados e têm validade limitada, então peça um link novo cada vez que renderizar a página em vez de guardá-lo no banco de dados.

Lado do servidor (Node.js 18+): obter um link assinado da playlist · 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
}

Se você precisa de uma validade diferente da padrão, POST /files/{id}/links aceita um ttl de 60 segundos a 30 dias e pode vincular o link a um endereço IP ou a um cookie. A documentação da API cobre isso por completo. Há também um endpoint público, GET /api/v1/public/files/{id}, que não precisa de chave; as páginas de exibição e de incorporação o usam, e os links dele valem por seis horas.

Na página, crie o player. O bloco abaixo usa o hls.js onde há suporte, recorre à reprodução nativa no Safari e, nos demais casos, mostra uma mensagem simples. Hospede você mesmo o arquivo da biblioteca ou fixe uma versão, em vez de carregar sempre a mais recente.

Lado do 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>

O objeto do vídeo também traz links.poster para a imagem de capa e links.sprite para as miniaturas de prévia ao passar o mouse, que você pode usar se construir a sua própria barra de busca. Com o hls.js você abre mão do que o player da UFOLOAD faz por você: o menu de qualidade, os capítulos, a seleção de legendas, o logotipo sobreposto e, quando há anúncios disponíveis, os anúncios. Essa é a verdadeira troca, e a tabela abaixo a resume.

iframe ou hls.js: qual usar

PerguntaPlayer em iframehls.js na sua página
Tempo de configuraçãoUm minuto, copiar e colarUma hora ou mais, além de um pequeno endpoint no servidor
Recursos do playerMenu de qualidade, capítulos, legendas, prévias ao passar o mouse, logotipo, anúncios quando disponíveisO que você mesmo construir
MonetizaçãoQuando há anúncios disponíveis, eles são exibidos e contabilizados no playerIndisponível, porque a camada de anúncios fica no player da UFOLOAD
EstiloSkin, cores, logotipo e botões no estúdio do playerQualquer HTML e CSS que você quiser
Expiração do linkResolvida para vocêVocê solicita um link novo a cada renderização da página
Bloqueio por domínioOs domínios de incorporação permitidos são aplicadosNão se aplica a um link que você mesmo serve; use TTL curto e vinculação a IP ou cookie

Checklist de solução de problemas

  • Quadro preto ou carregamento infinito. Abra o painel de rede do navegador e procure master.m3u8. Um 403 significa que o link expirou ou que o espectador está bloqueado por uma regra de país ou IP; solicite um link novo.
  • Bloqueado pelo navegador numa página HTTPS. Tudo precisa ser HTTPS. Nunca cole um endereço http:// no iframe ou no hls.js.
  • A reprodução automática não faz nada. Os navegadores bloqueiam a reprodução automática com som. Adicione mute=1 ou, no hls.js, defina video.muted = true antes de chamar play().
  • Aviso de processamento em vez do vídeo. O arquivo ainda não está pronto. Consulte GET /files/{id} periodicamente até que status seja ready.
  • Só toca uma qualidade baixa. O player começa de forma conservadora e sobe assim que mede a vazão. O seu plano e o seu original também limitam a versão mais alta; compare com preços e a página de recursos.

Quando a sua página estiver funcionando, talvez você queira protegê-la contra hotlinking ou, quando há anúncios disponíveis, ganhar dinheiro com ela. Os dois temas estão nos próximos guias: restrinja onde o seu vídeo pode ser incorporado e monetize o seu site de vídeos com anúncios no player. Se você ainda está decidindo onde hospedar, o checklist de hospedagem de vídeo lista o que comparar.

Experimente com uma conta gratuita

Envie um vídeo e receba um player HLS e uma chave de API em minutos. Os limites dos planos estão na página de preços.