§1O problema
A capturadora só abre em um programa por vez, então vários apps brigavam por ela, e não havia um jeito simples de ver a tela capturada no iPad.
§2O que eu construí
- Duas páginasUma página no computador que abre a capturadora e transmite; outra no iPad que só assiste.
- Capturadora compartilhadaCinco cópias virtuais da capturadora, uma por app, mantidas por um repassador.
- AjustesAjuste fino do atraso e da qualidade da imagem.
§3As partes difíceis
5 itens- 01
Um leitor por dispositivo virtual
O driver virtual só aceita um leitor por dispositivo: solução com uma cópia por app e uma só codificação distribuída para todas.
- 02
Tela preta sem erro
A capturadora troca o tamanho do JPEG no meio e o Chrome descarta; e o formato de cor errado chega mas não decodifica. Medido contando quadros reais.
- 03
Texto borrado quando o sinal HDMI muda
Detectado lendo o log do ffmpeg e reabrindo a entrada.
- 04
Atraso de ~290 ms para ~90 ms
Limitando as threads do codificador e enviando cada pacote na hora.
- 05
Processos órfãos segurando a capturadora
Resolvidos com tratamento de sinais e encerramento dos filhos.
§4Resultado
- de atraso do repassador (era ~290 ms)
- ~90 ms
- cópias virtuais de uma capturadora
- 5
Rodando no meu computador; as cópias virtuais atendem vários apps ao mesmo tempo. O atraso do repassador é de ~90 ms (medição minha, comparada à leitura direta da capturadora). A transmissão é até 1080p, 30 fps, sem som.
§5Stack
- Node puro + WebSocket
- WebRTC (H.264)
- ffmpeg
- v4l2loopback (Linux)
- Shell script
- pm2
- Tailscale