;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Afinal, o que é streaming? Veja como séries da Netflix e outros chegam à TV

Rodrigo Lara

Colaboração para Tilt

20/02/2020 04h00

Como você assiste a filmes e séries hoje em dia? Há boas chances de que a sua resposta envolva um serviço de streaming. Para termos ideia, estima-se que apenas a Netflix tenha mais de 12 milhões de s no Brasil. Mas o que acontece entre o momento que você pega a pipoca, aperta o "play" e o filme começa a rodar na sua TV?

A tecnologia por trás do streaming de vídeo envolve "picotar" o filme ou o episódio da série que você vai assistir, transportar esses "pedaços" até a sua casa e, então, juntá-los novamente. E tudo no menor tempo possível.

O primeiro ponto a ser considerado é que os grandes provedores de serviços de streaming alocam seus arquivos de vídeo em diversos servidores. Dessa forma, quando o usuário solicita o o a um arquivo, o provedor identifica o servidor mais próximo para diminuir o tempo de latência.

A seguir, o arquivo percorre o caminho até a casa do usuário, ando pela rede do provedor de internet.

Nesse caminho, o arquivo do filme viaja "picotado" em pacotes, que são endereçados de maneira independente e viajam separadamente. A parte interessante disso é que diferentes pacotes podem viajar por "rotas" diferentes. Quando eles chegam à casa do usuário, o cliente de streaming (o aplicativo da Netflix ou do Amazon Prime Video, por exemplo) agrupa e decodifica esses dados, exibindo o filme.

A grande diferença é que, no caso do streaming, o arquivo de mídia não é armazenado por completo no aparelho do usuário (ainda que alguns serviços permitam baixar arquivos para executar offline), mas sim reproduzidos conforme eles são baixados.

Apesar dos arquivos de vídeo serem baixados "sob demanda", os streamings trabalham com uma certa "gordura", o chamado buffer. Funciona assim: conforme o arquivo é reproduzido, dados referentes aos próximos minutos do arquivo de mídia já são transferidos previamente. Com isso, a experiência de quem assiste fica menos sujeita a oscilações no fluxo de dados, uma vez que a transferência já cuidou de baixar o que está "à frente" do atual momento do vídeo.

Por que a velocidade da internet influencia a qualidade do vídeo?

Isso ocorre porque vídeos com maior resolução (Full HD, 4K etc) são mais "pesados". Para serem transmitidos, há a necessidade de que o usuário tenha uma largura de banda grande o suficiente para garantir o fluxo de dados contínuo e, assim, ter uma boa experiência.

Geralmente os serviços de streaming detectam automaticamente a velocidade da conexão do usuário e, com base nisso, determinam qual é a qualidade do vídeo ideal para ser transmitido —o provedor de streaming tem o mesmo arquivo, com várias qualidades diferentes.

Operadoras de internet podem barrar o streaming?

É possível, sim, que operadoras de internet barrem o streaming, o que pode ocorrer tanto limitando o o a sites do tipo quanto diminuindo a largura de banda quando se usa esse tipo de serviço.

Apesar de possível, ao menos no Brasil isso teoricamente não é permitido: o Marco Civil da Internet (Lei n° 12.965/2014) determina a neutralidade da rede no seu artigo 9º, quando determina a obrigatoriedade de se "tratar de forma isonômica quaisquer pacotes de dados, sem distinção por conteúdo, origem e destino, serviço, terminal ou aplicação".

Fontes:

João Carlos Lopes Fernandes, professor do curso de Engenharia de Computação do Instituto Mauá de Tecnologia
Marcelo Parada, professor do departamento de Engenharia Elétrica do Centro Universitário FEI

Toda quinta, Tilt mostra que há tecnologia por trás de (quase) tudo que nos rodeia. Tem dúvida de algum objeto? Mande para a gente que vamos investigar.

SIGA TILT NAS REDES SOCIAIS