Como contornar a limitação de download de vídeos do YouTube
(blog.0x7d0.dev)- A URL do arquivo do YouTube pode ser obtida pela API
/youtubei/v1/player, mas, se for baixada diretamente, a velocidade fica extremamente lenta por causa de uma limitação não oficial de download - Desde meados de 2021, o parâmetro de consulta
nanexado à URL precisa ser transformado pelo algoritmo JavaScript debase.js; se isso falhar, o YouTube limita silenciosamente a velocidade - Mesmo tratando
ncorretamente, o tempo de download é ajustado de acordo com a duração e o tamanho do vídeo; no exemplo, um vídeo de 1,5GB é baixado a cerca de 4,0MB/s - Ao dividir o arquivo em blocos de 10MB com o cabeçalho HTTP
Range, cada bloco pode ser obtido rapidamente em uma nova conexão antes que a limitação entre em ação - O arquivo final precisa unir os streams separados de vídeo e áudio com
ffmpeg; yt-dlp, VLC media player, NewPipe e node-ytdl-core também usam técnicas semelhantes
Fluxo para obter a URL do arquivo do YouTube
- A URL real do arquivo de mídia pode ser obtida chamando o endpoint
/youtubei/v1/player - Essa API retorna o título do vídeo, descrição, miniatura e informações de formato, e é possível escolher a URL do arquivo na qualidade desejada a partir da lista de formatos
- O ID do vídeo de exemplo é
aqz-KE-bpKQ - O corpo da requisição inclui valores como
videoId,context.client.clientNameecontext.client.clientVersion - Os outros valores do objeto
contextsão pré-condições validadas pela API, e os valores aceitos podem ser encontrados observando requisições do navegador
- O ID do vídeo de exemplo é
- Se
adaptiveFormats[0].urlretornada pela API for usada diretamente, o download fica praticamente bloqueado de tão lento- No exemplo, um arquivo de 1,5GB aparece com velocidade em torno de 66,7kB/s
- A velocidade costuma ficar limitada a 40~70kB/s
- Baixar todo um vídeo de 10 minutos pode levar cerca de 6 horas e 30 minutos
A primeira limitação causada pelo parâmetro n
- Desde meados de 2021, o YouTube inclui o parâmetro de consulta
nna maioria das URLs de arquivo - Esse valor precisa ser transformado por um algoritmo JavaScript dentro de
base.js, distribuído junto com a página web - O YouTube usa o valor
ncomo uma espécie de desafio para distinguir clientes oficiais- Se
nestiver ausente ou não for transformado corretamente, a limitação de velocidade é aplicada silenciosamente
- Se
- Como o algoritmo de transformação é ofuscado e muda com frequência, fazer engenharia reversa manual a cada vez não é prático
- A implementação de exemplo baixa o
base.jsda versão atual do player, extrai o código de transformação dene o executa com o valor original den- Localiza a URL de
base.jsna página embed do YouTube - Extrai com expressões regulares o nome da função do desafio e o corpo da função
- Executa a função de transformação com
vm.runInNewContextdo Node.js - Substitui o parâmetro
nda URL pelo valor transformado
- Localiza a URL de
A limitação de velocidade que permanece mesmo após transformar n
- Ao transformar corretamente o parâmetro
n, a limitação extrema inicial desaparece, mas o YouTube ainda aplica uma limitação variável de download - O grau da limitação varia conforme o tamanho e a duração do vídeo, ajustando o download para que leve aproximadamente metade da duração do vídeo
- Do ponto de vista de um serviço de streaming, entregar sempre o arquivo na velocidade máxima possível pode representar grande desperdício de banda
- No download de exemplo, um arquivo de 1,5GB é baixado a cerca de 4,0MB/s
Recebendo pequenos blocos rapidamente com HTTP Range
- O ponto central do método de contorno é dividir o arquivo em vários pequenos intervalos de download com o cabeçalho HTTP
Range - O cabeçalho
Rangeespecifica qual intervalo do arquivo será recebido em cada requisição- Ex.:
Range: bytes=2000-3000
- Ex.:
- O código de exemplo processa o arquivo de mídia em segmentos de 10MB
- Remove o arquivo de saída existente
- Calcula o próximo intervalo de 10MB com base na quantidade de bytes já recebida
- Envia o cabeçalho
Rangeem cada requisição e recebe comresponseType: 'stream' - Grava os dados recebidos no fim do arquivo
- Exibe progresso, tamanho total e velocidade por segmento
- Esse método funciona porque as regras de limitação levam algum tempo para entrar em vigor, e segmentos pequenos podem ser recebidos muito rapidamente em uma nova conexão
- Na saída de teste, para um arquivo de 1464.99MB, apareceram as seguintes velocidades
- No ponto de 0,68%: 46.73MB/s
- No ponto de 1,37%: 60.98MB/s
- No ponto de 2,05%: 71.94MB/s
- No ponto de 6,14%: 104.17MB/s
- Alguns downloads chegaram a usar quase toda uma conexão de 1Gb/s, e a velocidade média normalmente ficou na faixa de 50~70MB/s, ou seja, 400~560Mb/s
Mesclagem de vídeo e áudio e implementações existentes
- O YouTube distribui os canais de vídeo e áudio em arquivos separados
- Nessa estrutura, vídeos HD ou UHD podem reutilizar o mesmo arquivo de áudio, economizando espaço de armazenamento
- Alguns vídeos também oferecem canais de áudio diferentes por idioma
- Na etapa final, usa-se
ffmpegpara unir o arquivo de vídeo e o arquivo de áudio em um só-c copycopia os streams sem recodificação-map 0:v:0seleciona o stream de vídeo da primeira entrada-map 1:a:0seleciona o stream de áudio da segunda entrada- Após a mesclagem, os arquivos temporários de vídeo e áudio são excluídos
- O código completo de exemplo é fornecido em youtube-download.js
- Vários projetos usam técnicas parecidas para contornar as limitações do YouTube
- yt-dlp: fork em Python do youtube-dl, incluindo seu próprio interpretador JavaScript para transformar o parâmetro
n - VLC media player
- NewPipe
- node-ytdl-core
- yt-dlp: fork em Python do youtube-dl, incluindo seu próprio interpretador JavaScript para transformar o parâmetro
1 comentários
Opiniões no Hacker News
Pelo que vi nas discussões do repositório do yt-dlp, era possível contornar essa restrição não com o cabeçalho HTTP Range, mas simplesmente adicionando o parâmetro de consulta
range=xxxMesmo definindo o intervalo como o arquivo inteiro, a velocidade máxima voltava e, se minha memória não falha, o YouTube já removeu essa restrição
Referência: https://github.com/yt-dlp/yt-dlp/issues/6400
Não testei no YouTube, mas já baixei vídeos de sites de streaming mais suspeitos usando as ferramentas de desenvolvedor da web
Na maioria das vezes, quando você abre as ferramentas de desenvolvedor, eles usam uma proteção que cria instruções
debuggerimpossíveis de pular e executa código que consome muita CPU — talvez um loop infinito ou um minerador de criptomoedas — fazendo o vídeo travarO mais importante é que esse código também apaga as informações de requisições de rede, dificultando a análise do tráfego enviado até então, e o “preservar log” do Firefox deveria realmente preservar o log
Não é uma defesa perfeita, então no fim nunca houve um vídeo que eu não conseguisse baixar, mas gostaria de ver algum material explicando esse mecanismo com mais profundidade
debuggerFoi algo de dar risada
https://news.ycombinator.com/item?id=36961445
É uma extensão simples que fiz em algumas horas, por motivos parecidos, algum tempo atrás
0: https://chrome.google.com/webstore/detail/anti-anti-debug/mn...
Uma página web nunca deveria conseguir descobrir se as ferramentas de desenvolvedor estão abertas, e parece algo que daria para implementar corretamente
shift+clique com o botão direito→This Frame→Open Frame in New TabNa nova aba, as ferramentas de desenvolvedor funcionam
Na etapa final, para continuar vendo a tela, vai ser preciso pagar com WorldCoin, e essa WorldCoin inegociável só poderá ser ganha assistindo a anúncios
Um pequeno Orb embutido na tela vai fiscalizar isso; você não achava mesmo que aquilo era para renda básica, achava?
O problema da renda básica já foi resolvido há muito tempo com contas bancárias e verificação de identidade (KYC)
Estou curioso se alguém anda enfrentando o problema de limitação de velocidade no yt-dlp
Sempre assisto ao YouTube com
mpv, que usa yt-dlp internamente, e desde a semana passada a situação ficou bem ruimNo começo ele inicia rápido, no limite que defini de 500 kB/s, mas depois de um tempo só baixa 1 segundo de reprodução a cada 3 segundos de download, então preciso deixar bastante tempo em buffer antes de reproduzir
Estou usando a versão git do yt-dlp, mas não vi nenhuma issue relacionada
mpvusa o yt-dlp apenas para obter a URL do vídeo e passa essa URL para offmpegO
ffmpegnão implementa a solução de contorno relacionada ao cabeçalho Range, então fica sujeito à limitação de velocidadeDá para fazer o yt-dlp baixar diretamente e passar isso por pipe para o
mpv, reproduzindo a partir da entrada padrão, mas aí a busca para trechos que ainda não foram baixados quebraHá muitas issues sobre esse problema no rastreador de issues do mpv
O YouTube fica mudando pequenos detalhes nesse processo
Antigamente eu criei uma ferramenta interna de edição para vídeos do YouTube que precisava de arquivos MP4 e, mais ou menos uma vez por mês, o editor quebrava por causa de uma mudança no YouTube, então eu tinha que abrir o depurador para ver o que tinha mudado e ajustar
É um desvio do assunto, mas fico me perguntando se é impressão minha que, visto no YouTube, o vídeo parece um pouquinho melhor
Baixo vídeos que gosto de assistir e vejo no VLC ou no Infuse da AppleTV, e consigo confirmar pelo “nerd stats” do app do YouTube que estou vendo o mesmo stream de vídeo/áudio
Mas parece que o YouTube aplica um filtro muito sutil que deixa os artefatos de compressão em blocos mais suaves
Não é que ele realce as bordas; a sensação é de que ele encontra áreas de mudança de cor sem bordas e torna os artefatos em blocos menos perceptíveis
Pode ser só impressão, mas no YouTube a imagem parece mais viva e firme, enquanto no vídeo baixado dá para ver artefatos e tremulações muito sutis, mas perceptíveis, em fundos ou sombras, fazendo até vídeos em 1440p parecerem ter uma qualidade final pior
No áudio a diferença também é clara: no YouTube o volume em geral é uniforme, enquanto nos vídeos baixados preciso aumentar o volume, o que é incômodo
Gostaria que VLC ou Infuse também fizessem algum processamento para deixar o vídeo mais agradável como o YouTube; parece mais algo como nivelamento de áudio, para tornar a experiência consistente entre canais, do que um filtro de cor ou nitidez
A maioria dos sites de streaming, como YouTube e Spotify, usa algo chamado ReplayGain
É uma tag que calcula o volume médio do vídeo ou da música, e é calculada no momento do upload
O cliente oficial do YouTube usa essa tag para ajustar o volume durante a reprodução, mas, ao baixar, a tag pode ficar de fora, ou o MKV talvez não tenha suporte padrão a tags ReplayGain
Se você reproduzir em tela cheia um stream na resolução original, a diferença deve desaparecer nas bordas em preto e branco
Dependendo do sistema operacional, dá para testar a diferença alternando rapidamente entre dois apps em tela cheia, e a ISO 29170-2 recomenda 5 Hz
Mudanças de cor podem vir de falhas no tratamento do espaço de cor do vídeo ou do perfil do monitor; nesse caso, capturas de tela também podem parecer diferentes da tela real do app
Tremulação pode ser queda de frames, e, se você vê pixelização nas bordas de objetos coloridos, a causa pode ser upscaling de crominância por vizinho mais próximo
O stream escolhido pelo navegador pode ser diferente do escolhido por padrão pelo youtube-dl ou por algum fork
Antigamente, por um tempo, ele escolhia por padrão o melhor stream combinado, mas streams separados de melhor áudio e melhor vídeo têm qualidade superior
Gosto especialmente do pacote de shaders
anime4k: ele é baseado em aprendizado de máquina, mas roda em tempo real nompve acho que também deve funcionar no VLCComo o nome sugere, ele é ajustado para animações, mas a redução de ruído e de desfoque é boa, então muitas vezes deixa conteúdos do YouTube mais agradáveis de ver, e a etapa de restauração lida bem com artefatos de compressão
Porém, por ser ajustado demais para animações, nem sempre funciona bem e pode até piorar a imagem
https://github.com/bloc97/Anime4K/releases
Dá para comparar criando um documento HTML simples com um elemento
videoapontando para um arquivo localFico surpreso sempre que o YT lança mais uma medida meia-boca contra downloaders
A GOOG também tem o Widevine, então me pergunto por que não o usa
Para o usuário nada mudaria, e o YouTube só ficaria com o ônus de operar o Widevine
Se usassem a versão baseada em hardware, poderia haver muitos problemas em dispositivos não suportados
O que importa para eles é desperdício de largura de banda
Em sites de streaming de vídeo baseados em anúncios, normalmente o custo de banda é maior que a receita, e isso só fecha porque o Google consegue largura de banda barata o bastante para pressionar ISPs a fazerem peering gratuito
Esse tipo de limitação de velocidade é uma medida para deixar a maior parte da largura de banda para usuários reais, não para quem sai raspando todo o conteúdo
Além de não ser muito eficaz para atingir o objetivo, provavelmente empurraria uma parte considerável dos usuários para fora da plataforma
Na escala do YouTube, eles querem reduzir ao máximo esse tipo de sistema
Além disso, transformaria o Widevine Level 3 em um alvo de ataque enorme
No fim, é uma equação financeira: o dinheiro perdido com bloqueio de anúncios ainda não é suficiente para acionar o interruptor do Widevine, mas já é suficiente para medidas mais fracas; e também deve haver pressão das gravadoras, então é possível que isso seja implantado de forma mais ampla nos próximos anos
Se eu fosse prever, começaria por vídeos que contenham músicas de gravadoras ou clipes de estúdios detectados pelo Content ID, e talvez oferecessem uma tag opcional para outros criadores
Esses vídeos são mais úteis para monetização e não fariam perder de uma vez os benefícios da CDN
Tomar discretamente esse tipo de medida meia-boca é a solução perfeita e talvez a única para atingir esse objetivo
Sempre tive curiosidade sobre como o YouTube distribui vídeos
Ele funcionava bem mesmo quando a internet estava uma bagunça, e na América do Sul nem todas as plataformas rodam bem, mas o YouTube é a plataforma de vídeo mais fluida
O mais próximo é a Netflix, mas ainda fica bem atrás
O ISP também se beneficia disso, então permite
O gargalo do ISP é a conexão entre a própria rede e o backbone mais amplo da internet, e os servidores de cache de uma grande CDN aliviam bastante a carga nesse gargalo
Documentação da configuração semelhante da Netflix: https://openconnect.netflix.com/
Você já tentou baixar um vídeo diretamente do YouTube?
Fazer isso manualmente, sem depender de youtube-dl, yt-dlp ou desses sites, é bem mais complicado do que parece
Claro que o problema desses scripts é ter de ficar correndo atrás de cada mudança que o YouTube faz para impedir downloads de vídeos
Vendo o WEI, é uma abordagem que usa o meu USER AGENT, que talvez não dure muito
Em vez de tentar reimplementar assinatura, decodificação de
ne funções de limitação de velocidade, encontro oplayer.jscommatch(/(?:player\/([a-zA-Z0-9_-]+)\/)?(?:html5player|(?:www|player(?:_ias)?))[-\.]([^/]+?)(?:(?:\/html5player(?:-new)?)?|(?:\/[a-z]{2,3}_[A-Z]{2})?\/base)\.js/)e então faço grep das funções relevantes dentro dele e as chamo diretamenteDo ponto de vista do YouTube, dá para dizer que parece 100% normal, já que a própria função de DRM dele está abrindo o link
.mp4para mimTecnicamente tudo isso é interessante, mas, eticamente, se você não estiver pensando apenas “Google que se dane”, parece razoável parar na primeira otimização, ou seja, passar na verificação de navegador real e obter a velocidade de um navegador comum
Nesse nível, você não desperdiça mais recursos do YouTube do que um usuário de navegador com bloqueador de anúncios
Usar a velocidade total em Gb/s sem pagar nada parece testar a sorte de todos os usuários com bloqueador de anúncios
Claro, no fim das contas talvez seja mesmo Google que se dane
Eu não diria que atingir o YouTube na velocidade máxima chega a ser antiético, mas também não culpo o YouTube por tomar medidas para bloquear isso
Uso uma extensão de navegador que mostra imagens de redes sociais em tamanho original ao passar o mouse, e o Instagram exibiu um aviso de atividade anormal e ameaça de bloqueio da conta
Verifiquei se a extensão estava fazendo scraping por trás, mas não parecia haver nada problemático; provavelmente a Meta vê uma ordem de requisições diferente da do cliente padrão e interpreta isso como scraping de dados
É um ciclo de medidas e contramedidas, e o YouTube também vai implementar suas próprias defesas para fazer os scrapers reagirem de novo; mas, como um consumo legítimo nunca seria mais rápido que 2x a velocidade de reprodução no cliente oficial, em algum momento eles poderão limitar os downloads a algo nesse nível
Ainda assim, acho que o download em si não deveria ser limitado
O conteúdo já é protegido por lei, e a maioria das pessoas baixa vídeos por motivos legítimos, como arquivamento, análise ou criação de vídeos de crítica/review
O conteúdo do YouTube não é criado no vácuo; depois de publicado, ele cria o ambiente em que novos vídeos serão produzidos, por isso essa liberdade de criação é importante
No fim, é só receber a mesma quantidade de dados em menos tempo, então usa mais largura de banda, mas desaparece mais rápido
O caso de uso de um navegador comum parece ajustado para a situação frequente em que a pessoa não assiste ao vídeo até o fim
Se a intenção desde o começo é assistir tudo e arquivar, é difícil dizer que isso consome mais largura de banda do Google; no máximo, pode haver mais overhead por causa do número de conexões
É natural que eu aja de modo parecido
Isso porque o YouTube tem caches em praticamente todos os ISPs e pontos de troca de tráfego do mundo, e talvez seja a maior CDN já criada
Por exemplo, a URL do YouTube do autor do post aponta para o ISP canadense Videotron
https://bgp.he.net/dns/rr1---sn-8qu-t0aee.googlevideo.com
Isso é necessário até para preservar provas de que alguém espalhou discurso de ódio ou insultou você e sua família
Você poderia filmar a tela com uma filmadora, mas isso soa como uma solução da Idade da Pedra
Por exemplo, no navegador do Mac, a Netflix não permite tirar screenshots, então até a criação de memes, que se enquadraria em uso justo, foi tirada de nós