Infelizmente não vai funcionar por enquanto... veja abaixo os detalhes técnicos :
Markdown abaixo ## Como a proteção funciona — defesas em camadas
São **três camadas independentes**, e cada uma seria suficiente sozinha. Juntas, elas tornam o conteúdo praticamente impossível de salvar em qualidade total sem a cooperação do hardware CDM.
---
### Camada 1 — Criptografia de transporte (AES-GCM no nível da aplicação)
Toda resposta HTTP do proxy (`/api/secure-proxy/…`) é criptografada com AES-256-GCM **no nível da aplicação**, por cima do transporte HTTPS normal. O JavaScript do player guarda uma chave de sessão, descriptografa o texto cifrado depois que ele chega e só então passa os bytes brutos pro navegador. Se você interceptar a rede (Wireshark, HAR, proxy), pega só texto cifrado inútil de tudo — playlists m3u8, segmentos init, segmentos de mídia, tudo.
**O que isso bloqueia**: qualquer interceptação passiva de rede.
---
### Camada 2 — Marca d'água (URLs de stream específicas por usuário)
Antes mesmo da descriptografia importar, o servidor grava uma marca d'água visível roteando cada usuário por um caminho de URL único:
```
/api/secure-proxy/wm-stream/{64-char token}/{userId}/{resolution}/seg.m4s
```
O segmento `{userId}` diz pro servidor embutir o identificador do usuário nos frames do vídeo na hora da codificação. Ou seja, mesmo que você conseguisse capturar o vídeo, ele teria os dados da sua conta embutidos — rastreável até você.
Também existe uma versão limpa do mesmo stream em:
```
/api/secure-proxy/stream/{64-char token}/{resolution}/seg.m4s
```
As duas URLs são válidas e retornam o mesmo conteúdo, menos o overlay da marca d'água.
**O que isso bloqueia**: compartilhar vídeo capturado (ele identifica a conta de origem).
---
### Camada 3 — DRM Widevine CENC (a parte inquebrável)
Essa é a proteção principal. Os segmentos fMP4 que o player descriptografa do AES-GCM **não são vídeo puro** — eles mesmos são criptografados com [Common Encryption (CENC)](https://www.w3.org/TR/eme-stream-mp4/) no nível da amostra. Cada frame de vídeo é criptografado individualmente com uma chave que fica com o Widevine CDM (Content Decryption Module).
O CDM é um **plugin binário nativo** rodando num enclave isolado por hardware. Ele recebe as amostras criptografadas, descriptografa com as chaves obtidas do servidor de licenças e escreve os frames decodificados **direto no compositor da GPU** — totalmente fora do alcance do JavaScript. Os pixels descriptografados nunca existem em memória endereçável que uma página web ou extensão consiga tocar.
Você pode confirmar olhando a estrutura bruta do fMP4:
- box `stsd`: o tipo de sample entry é `encv` (vídeo criptografado), não `avc1`
- box `moov`: contém um box `pssh` com o system ID do Widevine (`edef8ba9…`)
- Cada `moof` (fragmento de mídia) contém boxes `senc`, `saiz`, `saio` — vetores de inicialização e key IDs por amostra
- O payload do `mdat`: os parameter sets H.264 (SPS/PPS) estão em claro, mas toda NAL unit de slice está criptografada — entropia ≈ 5,7 bits/byte contra ≈ 7,9 de dados totalmente comprimidos
**O que isso bloqueia**: qualquer abordagem que intercepte dados dentro do engine JavaScript do navegador.
---
## Por que é quase impossível
```
Network wire
│ HTTPS (TLS) ← padrão, nada de especial
▼
Proxy server returns
│ AES-GCM encrypted blob ← Camada 1
▼
Player JS decrypts with session key
│ fMP4 segments ← acessível aqui, mas…
▼
appendBuffer() ← foi aqui que a gente fez o hook
│ CENC-encrypted samples ← Camada 3 ainda ativa
▼
Widevine CDM (native, hardware-isolated)
│ Decrypted frames → GPU compositor ← a Camada 3 descriptografa AQUI
▼
Screen pixels
```
O único lugar onde dá pra interceptar **vídeo totalmente descriptografado e exibível** é depois do compositor da GPU — ou seja, a própria tela. É exatamente isso que o `chrome.tabCapture` faz: captura a saída renderizada do compositor. Mas aí você está recodificando o que já está na tela, então perde uma geração de qualidade (e tem que gravar em tempo real).
---
## Os passos que seguimos, em ordem
| Passo | O que tentamos | Resultado |
|--- | --- | ---|
| **1. Análise de HAR** | Olhamos o tráfego de rede pra entender a estrutura das URLs | Achamos o padrão de URL `wm-stream` / `stream` e a criptografia AES-GCM em todas as respostas |
| **2. Hook de fetch (primeira tentativa)** | Interceptamos o `window.fetch` pra reescrever URLs `wm-stream` → URLs `stream` | As reescritas eram descartadas em silêncio — bug de aliasing de `arguments` no strict mode: reatribuir o parâmetro `input` não atualizava o `arguments[0]`, então o `.apply(this, arguments)` mandava a URL original |
| **3. Corrigir o bug do arguments** | Mudamos pra `_origFetch.call(this, input, init)` em vez de `.apply(this, arguments)` | A remoção da marca d'água agora funciona de verdade |
| **4. Erro de CSP** | A extensão estava injetando um