
George fechou o laptop e esfregou os olhos vermelhos privados de sono. "Os clientes continuam reclamando sobre o congelamento do fluxo; o novo pacote de correções não ajudou em nada! O que faço com este HLS (censurado)?" ele disse.
O navegador não é apenas um hipertexto, mas também uma serpentina
Os navegadores possuem players há muito tempo, mas a história é diferente com o codificador de vídeo e o streaming. Agora, em quase qualquer navegador da versão mais recente, podemos encontrar módulos para codificação, streaming, decodificação e reprodução. Essas funções estão disponíveis através da API JavaScript e a implementação é chamada Web Real Time Communications ou WebRTC. Essa biblioteca incorporada nos navegadores pode fazer bastante: capturar vídeo de uma câmera embutida, virtual ou USB, compactá-lo com os codecs H.264, VP8 e VP9 e enviá-lo à rede via protocolo SRTP; isto é, funciona como um codificador de vídeo de serpentina de software. Como resultado, vemos um navegador que tem algo semelhante ao ffmpeg ou gstreamer, compacta bem o vídeo, transmite em RTP e reproduz fluxos de vídeo.
O WebRTC nos dá a liberdade de implementar uma variedade de casos de streaming em JavaScript:
- transmitir do navegador para o servidor para gravação e distribuição subsequente
- distribuir fluxos ponto a ponto
- reproduzir o fluxo de outro usuário e enviar o seu próprio (bate-papo por vídeo)
- converter outros protocolos pelo servidor, por exemplo, RTMP, RTSP, etc., e reproduzi-los no navegador como WebRTC
Os scripts de controle de fluxo refinados podem ter esta aparência:
HLS funciona onde o WebRTC não funciona
O WebRTC é executado nas versões mais recentes dos navegadores, no entanto, existem os dois fatores a seguir: 1) Nem todos os usuários atualizam seus navegadores em tempo hábil e podem usar a versão antiga do Chrome por três anos. 2) Atualizações e novos navegadores, o WebView, assim como outros clientes e mensageiros instantâneos que ajudam os usuários a navegar na Internet são lançados quase uma vez por semana. Escusado será dizer que nem todos eles têm suporte WebRTC e, se tiverem, pode ser limitado. Veja como estão as coisas agora:

Os dispositivos favoritos de todos da Apple podem ser uma dor de cabeça. Eles começaram a dar suporte ao WebRTC apenas recentemente e, às vezes, seu comportamento em comparação com os navegadores de kits da web pode parecer surpreendente. Onde o WebRTC não funciona ou não funciona muito bem, o HLS funciona bem. Nesse sentido, é necessária compatibilidade, e algo como um conversor que nos permita converter o WebRTC para HLS e reproduzi-lo em praticamente qualquer dispositivo.
O HLS não foi originalmente concebido para fluxos em tempo real. De fato, como podemos transmitir vídeo em tempo real via HTTP? A tarefa do HLS é cortar o vídeo em pedaços e entregá-lo ao player sem problemas, sem pressa, baixando-o um por um. Um player HLS espera um fluxo de vídeo estritamente formado e suave. Aqui temos um conflito, já que o WebRTC, ao contrário, pode se dar ao luxo de perder pacotes devido a requisitos em tempo real e baixa latência e ter um FPS / GOP flutuante e uma taxa de bits variável - ser exatamente o oposto do HLS em termos de previsibilidade e regularidade do fluxo.
Uma abordagem óbvia - a despacketization (WebRTC) (SRTP) e a subsequente conversão para HLS podem não funcionar em um player Apple HLS nativo ou funcionar com congelamento, que é um formato inadequado para produção. O player nativo significa um player usado no Apple iOS Safari, Mac OS Safari e Apple TV.
Portanto, se você observar o congelamento do HLS no player nativo, talvez seja esse o caso, e a origem do fluxo seja WebRTC ou outro fluxo dinâmico com marcação irregular. Além disso, na implementação dos players nativos da Apple, existe um comportamento que só pode ser entendido empiricamente. Por exemplo, o servidor deve começar a enviar segmentos HLS imediatamente após o retorno da lista de reprodução m3u8. Um atraso de 1 segundo pode resultar em congelamento. Se a configuração do fluxo de bits tiver sido alterada no processo (o que é bastante comum durante o streaming do WebRTC), também haverá congelamento.
Combate ao congelamento em jogadores nativos
Assim, a despacketization WebRTC e a embalagem HLS geralmente não funcionam. No servidor de streaming de vídeo do Web Call Server (WCS) , resolvemos o problema de duas maneiras e oferecemos o terceiro como alternativa:
1) Transcodificação.
Essa é a maneira mais confiável de alinhar um fluxo WebRTC com os requisitos de HLS, definir o GOP, FPS desejado etc. No entanto, em alguns casos, a transcodificação não é uma boa solução; por exemplo, transcodificando fluxos de 4k
de vídeo VR é realmente uma má ideia. Tais fluxos pesados são muito caros para transcodificar em termos de tempo de CPU ou recursos de GPU.

2) Adaptação e alinhamento do fluxo WebRTC em movimento para atender aos requisitos de HLS.
Estes são analisadores especiais que analisam o fluxo de bits H.264 e o ajustam para corresponder aos recursos / bugs dos players HLS nativos da Apple. É certo que jogadores não nativos como video.js e hls.js são mais tolerantes com fluxos
com taxa de bits dinâmica e FPS em execução no WebRTC e não diminua a velocidade onde a implementação de referência do Apple HLS resulta essencialmente em congelamento.

3) Usando RTMP como fonte de fluxo em vez de WebRTC.
Apesar do Flash player já estar obsoleto, o protocolo RTMP é usado ativamente para streaming; Veja o OBS Studio, por exemplo. Devemos reconhecer que os codificadores RTMP produzem geralmente mais
fluxos que WebRTC e, portanto, praticamente não causam congelamento no HLS, ou seja, a conversão RTMP> HLS parece muito mais adequada em termos de congelamento, inclusive em players nativos de HLS. Portanto, se a transmissão for
feito usando a área de trabalho e o OBS, é melhor usá-lo para a conversão em HLS. Se a fonte for o navegador Chrome, o RTMP não poderá ser usado sem a instalação de plug-ins e apenas o WebRTC funcionará nesse caso.

Todos os três métodos descritos acima foram testados e funcionam, para que você possa escolher com base na tarefa.
WebRTC para HLS na CDN
Existem alguns indesejáveis que você encontrará em um sistema distribuído quando houver vários servidores de entrega de fluxo WebRTC entre a fonte de fluxo WebRTC e o player HLS, ou seja, CDN , no nosso caso, com base em um servidor WCS. É assim: Existe o Origin - um servidor que aceita o fluxo WebRTC e o Edge - servidores que distribuem esse fluxo, inclusive via HLS. Pode haver muitos servidores, o que permite o dimensionamento horizontal do sistema. Por exemplo, 1000 servidores HLS podem ser conectados a um servidor Origin; nesse caso, a capacidade do sistema é escalada 1000 vezes.

O problema já foi destacado acima; geralmente surge em players nativos: iOS Safari, Mac OS Safari e Apple TV. Por nativo, queremos dizer um jogador que trabalha com uma indicação direta do URL da playlist em
a tag, por exemplo <video src="https://host/test.m3u8"/>
. Assim que o jogador solicita uma lista de reprodução - e essa ação é realmente o primeiro passo na reprodução do fluxo HLS - o servidor deve imediatamente, sem
atraso, comece a enviar segmentos de vídeo HLS. Se o servidor não começar a enviar segmentos imediatamente, o jogador decidirá que foi enganado e parará de jogar. Esse comportamento é típico dos players HLS nativos da Apple, mas não podemos apenas dizer aos usuários "por favor, não use o iPhone Mac e o Apple TV para reproduzir fluxos HLS".
Portanto, quando você tenta reproduzir um fluxo HLS no servidor de Borda, o servidor deve começar imediatamente a retornar segmentos, mas como ele deve ser feito se não tiver um fluxo? De fato, quando você tenta jogar, há
não há fluxo neste servidor. A lógica da CDN funciona com o princípio do Lazy Loading - não carrega o fluxo no servidor até que alguém solicite esse fluxo neste servidor. Há um problema da primeira conexão
usuário; o primeiro que solicitou o fluxo HLS do servidor de borda e teve a imprudência de fazer isso no Apple player padrão ficará congelado pelo motivo de levar algum tempo para solicitar esse fluxo
no servidor Origin, coloque-o no Edge e inicie o fatiamento HLS. Mesmo se demorar três segundos, isso não ajudará. Vai congelar.

Aqui temos duas soluções possíveis: uma é OK e a outra é menos. Pode-se abandonar a abordagem Lazy Loading na CDN e enviar tráfego para todos os nós, independentemente de haver ou não visualizadores. Uma solução, possivelmente adequada para quem não está limitado em recursos de tráfego e computação. O Origin enviará tráfego para todos os servidores de Borda, como resultado, todos os servidores e a rede entre eles serão carregados constantemente. Talvez esse esquema seja adequado apenas para algumas soluções específicas com um pequeno número de fluxos de entrada. Ao replicar um grande número de fluxos, esse esquema será claramente
ineficiente em termos de recursos. E se você se lembra de que estamos apenas resolvendo o “problema do primeiro usuário conectado a partir do navegador nativo”, fica claro que não vale a pena.

A segunda opção é mais elegante, mas também é apenas uma solução alternativa. Damos ao primeiro usuário conectado uma imagem de vídeo, mas ainda não é o fluxo que ele deseja ver - este é um pré-carregador. Como já devemos fornecer algo a eles e fazê-lo imediatamente, mas não temos o fluxo de origem (ele ainda está sendo solicitado e entregue pela Origin), decidimos pedir ao cliente que espere um pouco e mostre a eles um vídeo do
preloader com animação em movimento. O usuário espera alguns segundos enquanto o pré-carregador gira, e quando o fluxo real finalmente chega, o usuário começa a obter o fluxo real. Como resultado, o primeiro usuário verá o
preloader e aqueles que se conectarem depois disso finalmente verão o fluxo HLS regular vindo da CDN operando com o princípio Lazy Loading. Assim, o problema de engenharia foi resolvido.
Mas ainda não totalmente resolvido
Parece que tudo funciona bem. A CDN está funcionando, os fluxos HLS são carregados dos servidores de Borda e o problema do primeiro usuário conectado é resolvido. E aqui está outra armadilha - damos a
pré-carregador em uma proporção fixa de 16: 9, enquanto fluxos de qualquer formato podem entrar no CDN: 16: 9, 4: 3, 2: 1 (vídeo VR). E isso é um problema, porque se você enviar um pré-carregador no formato 16: 9 para o player e o fluxo ordenado for 4: 3, o player nativo voltará a congelar.
Portanto, surge uma nova tarefa - você precisa saber com qual proporção o fluxo entra na CDN e fornecer a mesma proporção ao pré-carregador. Um recurso dos fluxos WebRTC é a preservação da proporção quando
alteração da resolução e transcodificação - se o navegador decide diminuir a resolução, diminui-a na mesma proporção. Se o servidor decidir transcodificar o fluxo, ele manterá a proporção na mesma proporção. Portanto, faz sentido que, se queremos mostrar o pré-carregador para HLS, mostremos na mesma proporção em que o fluxo entra.

A CDN funciona da seguinte maneira: quando o tráfego entra no servidor Origin, ele informa outros servidores na rede, incluindo servidores Edge, sobre o novo fluxo. O problema é que, neste momento, a resolução do
o fluxo de origem ainda não pode ser conhecido. A resolução é realizada pelas configurações de fluxo de bits H.264 junto com o quadro-chave. Portanto, o servidor de borda pode receber informações sobre um fluxo, mas não saberá sobre seus
resolução e proporção, o que não permitirá gerar corretamente o pré-carregador. Nesse sentido, é necessário sinalizar a presença do fluxo na CDN apenas se houver um quadro-chave - isso garante informações ao tamanho do servidor Edge e permite que o pré-carregador correto seja gerado para evitar “o primeiro problema de visualizador conectado . ”

Sumário
A conversão do WebRTC para HLS geralmente resulta em congelamento quando reproduzida nos players padrão da Apple. O problema é resolvido analisando e ajustando o fluxo de bits H.264 aos requisitos de HLS da Apple, seja por ranscoding,
ou migrando para o protocolo RTMP e codificador como uma fonte de fluxo. Em uma rede distribuída com Carregamento Preguiçoso de fluxos, há o problema do primeiro visualizador conectado, que é resolvido usando o pré-carregador e determinando a resolução no lado do servidor Origin - o ponto de entrada do fluxo na CDN.
Ligações
Servidor de Chamada pela Web - servidor WebRTC
CDN para streaming WebRTC de baixa latência - CDN baseado em WCS
Reprodução de fluxos de vídeo WebRTC e RTMP via HLS - Funções de servidor para converter fluxos de várias fontes em HLS