Neste artigo, você aprenderá sobre o conceito mais avançado de streaming de mídia e, ao final, deverá ter uma boa compreensão dos vários casos de uso, protocolos e extensões de streaming. Vamos começar explicando o que realmente é o streaming.
O streaming de mídia é uma maneira de entregar e reproduzir conteúdo de mídia por partes. Em vez de carregar um único arquivo, que pode ser lento se não for otimizado para a rede, o jogador lê um arquivo de manifesto que descreve como a mídia de destino é dividida em blocos individuais de dados. Os pedaços de mídia são unidos dinamicamente no momento da execução, provavelmente com diferentes taxas de bits, que você vai aprender mais tarde.
Para fornecer streaming no seu site, o servidor
precisa oferecer suporte ao cabeçalho de solicitação HTTP Range. Saiba mais sobre o cabeçalho Accept-Ranges
no artigo As tags <video> e <source>.
Casos de uso de streaming
Produzir blocos de mídia e os manifestos necessários que descrevem o stream não é
exatamente simples, mas o streaming desbloqueia alguns casos de uso interessantes que
não podem ser alcançados apenas apontando um elemento <video>
para um conjunto de arquivos de origem estáticos. Você vai aprender mais sobre como
adicionar mídia a uma página da Web em uma seção mais adiante. Primeiro, você precisa conhecer alguns
casos de uso de streaming de multimídia se quiser ir além do
carregamento de vários arquivos no elemento <video>
.
- O streaming adaptável é quando os blocos de mídia são codificados em vários bitrates, e o bloco de mídia de maior qualidade que se encaixa na largura de banda disponível do cliente é retornado ao player de mídia.
- Transmissão ao vivo é onde os blocos de mídia são codificados e disponibilizados em tempo real.
- A injeção de mídia é quando outras mídias, como anúncios, são injetadas em um stream sem que o player precise mudar a origem da mídia.
Protocolos de streaming
Os dois protocolos de streaming mais usados na Web são o Dynamic Adaptive Streaming over HTTP (DASH) e o HTTP Live Streaming (HLS). Os players com suporte a esses protocolos vão buscar o arquivo de manifesto gerado, descobrir quais blocos de mídia solicitar e, em seguida, combiná-los na experiência de mídia final.
Como usar <video>
para reproduzir um stream
Muitos navegadores não vão reproduzir sua transmissão de forma nativa. Embora haja algum
suporte nativo para reprodução HLS, os navegadores geralmente não oferecem suporte à reprodução de streaming DASH
nativa. Isso significa que, muitas vezes, não basta apontar o <source>
no elemento <video>
para um arquivo de manifesto.
<video controls>
<source src="manifest.mpd" type="application/dash+xml">
</video>
O que pode parecer um déficit, na verdade, é uma força disfarçada. Os streams são poderosos, e os aplicativos que consomem streams têm necessidades diferentes.
Os arquivos de manifesto geralmente descrevem muitas variantes de uma única mídia. Pense em diferentes taxas de bits, várias faixas de áudio e até mesmo a mesma mídia codificada em diferentes formatos.
Alguns aplicativos podem querer manter uma quantidade maior de vídeo no buffer, outros podem querer fazer preempção dos primeiros segundos de vídeo de um próximo episódio e alguns podem querer implementar a própria lógica para streaming adaptável. É aqui que você gostaria de ter algum tipo de recurso integrado do navegador para gerar streams de mídia para reprodução. O que realmente acontece é um.
Extensões de origem de mídia
Felizmente, o W3C definiu algo chamado Media Source Extensions (MSE)
que vai permitir que o JavaScript gere nossos streams de mídia. Em resumo, o MSE permite
que os desenvolvedores anexem um objeto MediaSource
a um elemento <video>
e
reproduzam os dados de mídia que são bombeados para os buffers anexados à
instância MediaSource
.
Exemplo básico
const videoEl = document.querySelector('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener(
'sourceopen',
() => {
const mimeString = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
const buffer = mediaSource.addSourceBuffer(mimeString);
buffer.appendBuffer( /* Video data as `ArrayBuffer` object. */ )
}
);
O exemplo simplificado acima ilustra algumas coisas:
- No que diz respeito a
<video>
, ele está recebendo dados de mídia de um URL. - O URL gerado é apenas um ponteiro para uma instância de
MediaSource
. - A instância
MediaSource
cria uma ou mais instânciasSourceBuffer
. - Em seguida, basta anexar dados de mídia binários ao buffer, por exemplo, usando
fetch
.
Embora esses conceitos básicos sejam simples e certamente seja possível escrever um player de vídeo compatível com DASH e HLS do zero, a maioria das pessoas geralmente escolhe uma das soluções maduras de código aberto que já existem, como Shaka Player, JW Player ou Video.js.
No entanto, criamos um PWA de mídia de demonstração chamado Kino, que demonstra como
você desenvolveria seu próprio site básico de mídia de streaming que oferece
reprodução de mídia off-line usando apenas o simples elemento <video>
. Nosso roteiro inclui planos para apoiar frameworks e gestão de direitos digitais, entre outros recursos. Por isso, confira as atualizações de tempos em tempos ou solicite um recurso.
Leia mais sobre isso no artigo PWA com streaming off-line.
Formato de blocos de mídia
Por muito tempo, o DASH e o HLS exigiam que os blocos de mídia fossem codificados em formatos diferentes. No entanto, em 2016, o suporte a arquivos MP4 fragmentado (fMP4) padrão foi adicionado ao HLS, um formato que o DASH também oferece suporte.
Os blocos de vídeo que usam o contêiner fMP4
e o codec H.264
são compatíveis
com ambos os protocolos e podem ser reproduzidos pela grande maioria dos jogadores. Isso permite
que os produtores de conteúdo codifiquem os vídeos apenas uma vez, o que economizar tempo
e espaço no disco.
Para alcançar uma qualidade melhor e tamanhos de arquivo menores, você pode codificar
vários conjuntos de fragmentos de mídia usando formatos mais eficientes, como VP9
.
No entanto, antes de avançarmos, você precisa aprender a
Preparar arquivos de mídia para a Web, que é o próximo assunto.