De onde veio
A edição que eu fazia
Pra quem não me conhece: fui editor de vídeo por 4 anos e hoje sou engenheiro de software. Trabalhei no Ossos Perdidos, um canal de true crime bem famoso, hoje com mais de um milhão de inscritos, e participava de todas as partes da criação de um vídeo profissional. Se quiser saber mais sobre essa jornada, está tudo em Minha jornada até aqui.
A gente já usava IA na época em que eu editava, mas ela ainda engatinhava. Quando virei engenheiro de software, em algum momento pensei: e se eu pegasse todo aquele processo e automatizasse com as ferramentas que tenho hoje? Foi daí que surgiu o primeiro resquício deste projeto.
Como surgiu o projeto
Hoje eu trabalho para a consultoria do meu amigo e parceiro Dyego Maas, e este projeto caiu como uma luva. Ele vai fazer parte de um ecossistema bem maior, mas a ideia aqui é que os vídeos que a empresa posta em qualquer mídia digital passem por um pipeline automático.
E esse pipeline é exatamente isso: automatizar todo o processo criativo de um vídeo, do arquivo cru ao vídeo exportado, usando IA. O Dyego me ajudou muito com ferramentas e conselhos sobre qual caminho seguir, e assim começamos o projeto, que batizamos de My-Little-Studio.
A engenharia
Pipes and Filters
Já tínhamos a ideia mapeada, mas precisávamos de um padrão de arquitetura decente para ela. Depois de muita pesquisa, o que mais se encaixava no que queríamos era o Pipes and Filters.
Pipes and Filters (canos e filtros) é um padrão com duas peças. Os filtros são etapas independentes: cada uma recebe um dado, transforma e entrega. Os canos ligam uma etapa à próxima, levando o que uma produziu para a outra consumir.
É o mesmo desenho dos pipes do Unix, a família de sistemas operacionais nascida nos anos 70 que deu base ao macOS e inspirou o Linux. No terminal, "cat arquivo | grep erro | sort" liga três programas pequenos pelo caractere "|": cada um faz uma coisa só, e a saída de um vira a entrada do próximo.
Para vídeo, isso serve muito bem, porque precisávamos que cada etapa pudesse ser rodada, testada e trocada sozinha.
O projeto por dentro
Além da arquitetura, a regra que queríamos seguir era simples: uma parte determinística e uma parte não determinística. A determinística são os scripts, que fazem sempre a mesma coisa. A não determinística é a conversa com o agente: ele segue as instruções que ficam no projeto, mas cada conversa sai de um jeito.
Os scripts, que no projeto chamamos de runners, são as etapas determinísticas: cada um faz uma operação do pipeline de vídeo. Junto deles ficam os recibos de cada execução, para saber exatamente o que aconteceu, e os ajustes, onde ficam os parâmetros e os setups de cor.
Os filtros: os scripts
Cada script faz uma coisa só. Hoje já são 29, divididos em categorias: corte e limpeza, legenda, cor, corpo e gesto, imagem e animação. Todos têm um parâmetro --help que explica como usar, e dá para rodar qualquer um sozinho pelo terminal. Na próxima parte mostro os principais, categoria por categoria.
E eles são determinísticos: com a mesma entrada, dão sempre o mesmo resultado. As exceções são os scripts que chamam um serviço de IA de fora, como a AssemblyAI na legenda e o gpt-image-2 na geração de imagem, cuja resposta pode variar. Mesmo assim, tudo o que eles pedem e recebem fica registrado no recibo.
Os canos: o acervo e o rastro
Os scripts precisam conversar. Dá para rodar cada um sozinho, mas alguns dependem do resultado de outros: o que coloca a borda do corte no começo da sílaba, por exemplo, precisa antes saber quais trechos ficaram. Para isso existem o acervo e o rastro.
O acervo guarda cada vídeo numa pasta própria: o original, cada arquivo derivado e, dentro dela, o rastro. No rastro, cada etapa grava o que decidiu e anota a impressão digital (um hash sha256) de cada arquivo que leu.
Antes de trabalhar, a etapa confere essas impressões digitais. Se um dado de antes mudou, ela percebe que está trabalhando em cima de algo velho, se recusa a rodar e diz exatamente qual comando falta. Isso aconteceu de verdade neste vídeo: a revisão foi recusada duas vezes, porque uma etapa anterior tinha rodado de novo.
Além disso, toda execução deixa um recibo: o que entrou, o que saiu, os parâmetros, o tempo e o custo. Ela termina de um de três jeitos: deu certo, falhou (e nada pela metade fica no acervo) ou já estava feito (e nada é refeito nem pago).
O agente e as skills
O agente, que por enquanto é só o Claude Code, não precisa ler os scripts: isso consumiria muito contexto. Em vez disso, cada tipo de trabalho tem uma skill dentro do projeto.
As skills são manuais de trabalho. Elas não explicam cada script; explicam o procedimento para um tipo de trabalho, como cortar, analisar o enquadramento ou legendar: quando usar, qual script rodar, com quais parâmetros e onde olhar se der problema. Só aí, quando algo dá errado, o agente abre o código. Hoje são 10 skills para os 29 scripts.
Os scripts, categoria por categoria
Corte e limpeza
Para cortar direito, primeiro precisávamos fixar o frame rate. Muita gravação vem com frame rate variável, e aí um corte cai num quadro na imagem e em outro no som. O fix-framerate faz exatamente isso: normaliza o vídeo para 30 quadros por segundo fixos. Depois vêm os scripts básicos de áudio: tirar o áudio alinhado ao vídeo e limpar o ruído, que só é tratado se a medição mostrar que precisa.
O grande diferencial é o transcribe-tape, que monta o que chamamos de fita. Ele usa um modelo de reconhecimento de fala em português (wav2vec2) que roda no próprio computador e diz qual letra soa a cada 20 milissegundos. A transcrição comercial escondia as frases repetidas, juntando as duas tentativas numa só. Na fita, a retomada aparece escrita duas vezes, e é ela que decide o corte.
Com a fita, o resto da cadeia acha os trechos de voz, fica com a última tentativa de cada frase, coloca cada borda do corte no começo da sílaba e prepara um formulário de revisão, que o agente preenche como um editor. Depois vêm o corte em si e o volume nivelado. O roteiro não decide o corte: ele só aparece na revisão, para mostrar se alguma linha ficou sem ser dita.
fix-framerateextract-audiodenoisetranscribe-tapeO fix-framerate deixa o vídeo com 30 quadros por segundo fixos, o extract-audio tira o áudio alinhado ao primeiro quadro, o denoise mede o ruído e só limpa quando precisa, e o transcribe-tape monta a fita, que diz qual letra soa a cada 20 ms.
detect-speechdedupe-retakespad-edgesreview-draftapply-reviewO detect-speech acha os trechos de voz, o dedupe-retakes fica com a última tentativa de cada frase repetida, o pad-edges põe cada borda do corte no começo da sílaba, o review-draft prepara o formulário que o agente preenche como um editor e o apply-review confere e aplica essas decisões.
render-cutloudnormO render-cut corta imagem e som como duas entradas separadas, e o loudnorm nivela o volume em −14 LUFS.
clean-recordingplan-showO clean-recording roda a cadeia inteira em ordem e para na revisão, e o plan-show mostra onde a cadeia está e o que ficou velho.
Legenda
Na legenda, usamos a AssemblyAI como uma segunda camada. A fita já sabe exatamente quando cada palavra é dita, mas escreve do jeito que soa, sem dicionário. A AssemblyAI entra com o texto bem escrito, e a fita cola cada palavra no tempo certo e confere se o que foi escrito bate com o que soou.
Quando uma palavra não bate, ela vira uma dúvida para o agente resolver, em vez de ir errada para a tela. Assim os erros não passam e a legenda sai melhor. Nenhuma das duas sozinha dava conta: a AssemblyAI erra o fim da palavra em até 150 ms, e a fita sozinha cola palavras.
captionO caption pede o texto à AssemblyAI, usa a fita para dar o tempo de cada palavra, marca como dúvida a palavra que não bate com o som e guarda no glossário a grafia que eu confirmo.
Cor
Aqui a ideia é aplicar LUTs e ter sempre um lugar salvo para buscar depois. O color-grade aplica um Setup, que é o LUT mais o ganho e a nitidez calibrados uma vez para uma câmera, uma luz e um cenário, e esse Setup fica guardado para os próximos vídeos.
color-gradeO color-grade aplica um Setup, com LUT, ganho e nitidez, calibrado uma vez para uma câmera, uma luz e um cenário.
Corpo e gesto
No vídeo lá do começo eu simplifiquei: o OpenCV é responsável só por achar o meu rosto. Na verdade são três ferramentas para captar tudo:
- o YuNet, um modelo do OpenCV, acha o rosto;
- o MediaPipe, do Google, recorta a minha silhueta do fundo;
- o RTMPose segue as duas mãos, o rosto e os ombros, quadro a quadro.
Com esse rastreio, o gesture-events tira cada gesto no quadro exato em que aconteceu, e o framing-analysis monta um mapa do corpo, com cabeça, tronco, braços e mãos, que diz onde um elemento cabe sem encostar em mim. Uma lição que aprendemos medindo: a posição nunca vem de um modelo de linguagem. O Gemini errava 12% da largura da tela.
track-personhand-detaildetect-cutsO track-person segue as duas mãos, o rosto e os ombros em cada quadro, o hand-detail lê se a mão está aberta ou fechada e o detect-cuts acha as emendas de um vídeo que não passou pelo corte do studio.
gesture-eventsO gesture-events tira do rastreio cada gesto no quadro exato: o pico de movimento, a mão abrindo, a batida do dedo, o arrasto e para onde o indicador aponta.
framing-analysisframing-queryO framing-analysis nomeia as partes do quadro e desenha o corpo a cada 0,2 s, e o framing-query diz onde um elemento cabe sem encostar no corpo e o que o fez encolher.
Imagem
A imagem é mais tranquila. O gpt-image-2 fica só para as coisas premium: neste vídeo, foram só algumas janelas. Os resultados só com React já são impressionantes: quase todos os cartões e janelas do vídeo saíram dele.
generate-assetsupscalecompressO generate-assets cria imagem com o gpt-image-2, o upscale aumenta a resolução pelo Replicate e o compress deixa o arquivo mais leve.
Animação
A animação é onde o HyperFrames faz a mágica acontecer (explico ele melhor no fim). Escolhemos ele em vez do Remotion porque tem uma documentação mais completa e foi pensado para ser usado por agentes.
Hoje dois scripts já preparam a animação: a página onde eu desenho (o quadro de rascunho, que mostro mais abaixo) e o cruzamento desse desenho com a minha mão. O resto ainda foi feito pelo agente em código, e cada parte vira um script na próxima fase.
sketchsketch-compareO sketch gera a página onde eu desenho em cima do vídeo, quadro a quadro, e o sketch-compare cruza esse desenho com a palma da mão e devolve em números onde o elemento nasce e onde assenta.
planoassetscomposiçãosonsrenderO plano é a animação escrita por IA antes de virar código, o catálogo de assets guarda os componentes React prontos para reusar, a composição é uma página HTML animada com GSAP no HyperFrames, os sons acompanham cada movimento e o render junta voz, sons e trilha. Hoje o agente faz isso em código, e cada parte vira um script na fase 2.
Os quadros de edição visual
Prompts visuais
Por mais que o agente conseguisse fazer as animações, eu tinha muita dificuldade de fazer animações personalizadas. E acho que esse é o maior problema hoje na geração de qualquer conteúdo com IA, seja vídeo ou asset: conseguir pedir algo específico.
Já trabalhei em projetos em que muita gente esbarrava nisso, principalmente na geração de vídeo. O resultado vem bom, mas não vem o que você tinha na cabeça, porque é difícil fazer a ferramenta entender em texto uma coisa visual.
Aqui aconteceu o mesmo. Os scripts já faziam um vídeo tranquilo, mas eu queria algo mais específico. Então criamos um quadro que funciona quase como um Premiere: ele mostra o vídeo quadro a quadro, eu desenho em cima e escrevo instruções para o agente.
Como é HTML, o quadro exporta exatamente em qual quadro eu estava, qual era a instrução e o desenho. E, por incrível que pareça, a IA lê muito bem imagem: vendo o meu desenho, ela entendeu o que eu queria melhor do que eu tinha conseguido explicar antes só com texto. Chamei isso de prompts visuais.
E tem um bônus: depois de ver o desenho, a IA explica em texto o que entendeu, e melhor do que eu. Essas explicações viram prompts melhores para os scripts automatizados do futuro. Só no primeiro rascunho deste vídeo foram 123 traços e 15 notas.
O quadro de animação
Com a animação foi a mesma coisa: ela errava, e a animação é um pouco diferente, porque trabalha mais com o tempo. Não é tanto desenhar, é dizer quando. Então criei também o quadro de animação, que mostra o vídeo inteiro e cada animação separada, quadro a quadro.
Ali eu consigo definir exatamente quando uma animação entra e quando sai, avançar e voltar quadro a quadro e apontar onde ela estava travada. Do mesmo jeito, isso gera resultados que eu posso reaproveitar para fazer scripts de animação automatizados melhores.
O quadro de corte
A mesma ideia foi aplicada ao corte. Os scripts já cortavam bem, mas, estressando o projeto, apareceram problemas específicos: com um respiro, ou com uma frase em que ele não sabia se cortava ou não, ele cortava errado.
No quadro de corte, eu marco na agulha o que está errado, o agente muda e explica o que mudou. E cada correção vira aprendizado para os próprios scripts: o projeto se melhora a cada rodada. É o conceito que mais me interessa aqui, e provavelmente vou levar esse tipo de quadro para outras etapas também.
Resultado e o que vem
Os números
Hoje, com os scripts prontos, o corte leva minutos, e isso já deixa a etapa de limpeza pronta. A animação é o que mais demora: uns 30 minutos para eu desenhar e ajustar. Mas é tudo com linguagem natural e desenho na mão, é bem tranquilo e sai algo muito funcional e bem feito.
A ideia é que, quando esses scripts ficarem prontos, o vídeo inteiro leve minutos, e os testes que venho fazendo já apontam para isso. O vídeo lá do começo tem pouco mais de 2 minutos; é claro que, quanto maior o vídeo, maior o tempo, mas acredito que ainda vai ser muito bom. Quando eu editava, um vídeo nesse estilo levava mais de uma semana.
E ferramenta de geração pronta não resolve. O resultado vem bom, mas não específico, e quando você precisa de algo que a ferramenta não faz, acaba tendo que buscar outras tecnologias, que geralmente custam dinheiro.
Cada sessão deixa o projeto melhor
Cada sessão do Claude é valiosa. Cada sessão em que trabalhamos deixa o projeto melhor, porque ela tem dados muito bons: o que o agente errou, o que ele precisou, como trabalhou e o que executou.
Um exercício muito interessante é perguntar para o próprio agente que dificuldades ele teve para rodar um script ou fazer um trabalho, onde houve divergência e onde deu problema. Trabalhando em cima disso, o projeto fica cada vez mais robusto. A gente vem usando muito isso, e vale para qualquer projeto.
O que vem
O projeto acabou de começar e ainda está longe de acabar, mas já está entregando. A ideia é ter logo uma versão funcional de ponta a ponta. Hoje estou focado nos scripts de animação, que são os que mais têm problema: o mapa do corpo já entrou, e agora vêm o plano de animação, o catálogo de assets, a composição, os sons e o render.
Depois disso, a maioria dos scripts já está sólida e só precisa de uma leve afiada: corte, legenda e o resto. Com tudo pronto, a ideia é estressar o projeto, ver os pontos fracos e começar a trabalhar nas ideias do backlog.
E teve uma parte que eu nem mostrei aqui: o storyboard. Antes de gravar, uma etapa inteira gera as ideias, escreve o roteiro e monta uma folha de storyboard com um esboço para cada quadro, e o resultado ficou impressionante. Mas ela tem mais a ver com a criação da ideia do que com a edição, então vale outra postagem, quando esse processo estiver mais consolidado.
E quero deixar um adendo sobre o Jev, da TypeSafe AI, lançado agora em setembro. Ele é o primeiro de uma nova classe de modelos que eles chamam de System One, nome tirado da ideia do Kahneman: o Sistema 1 é o pensamento rápido e intuitivo, e o Sistema 2, o lento e deliberado. Em vez de escrever texto palavra por palavra, como um LLM, o Jev recebe a situação e as respostas possíveis, e devolve uma delas já no formato certo, com a probabilidade de cada uma.
Segundo eles, ele responde entre 70 e 500 milissegundos, custa uma fração de um LLM e, como só escolhe entre as opções que você deu, não tem como inventar uma resposta fora delas. Pra este projeto isso é muito interessante: várias decisões pequenas ainda passam pela conversa com o agente, como se uma tentativa fica ou sai na revisão, ou se uma palavra duvidosa da legenda está certa. São perguntas de resposta fechada, e um modelo assim poderia responder rápido, barato e sempre no formato certo, deixando a parte não determinística bem menor. Ele ainda está em acesso antecipado e eu não testei, mas é uma das coisas que mais quero trazer para cá.
LinkIntroducing System One models and Jev ↗As tecnologias
HyperFrames
O HyperFrames é o coração da animação: é ele que faz tudo funcionar. Pra mim, é provavelmente a tecnologia mais interessante do projeto, e a que mais me surpreendeu.
A ideia é simples: cada animação é uma página HTML, com o movimento feito em GSAP. Para virar vídeo, ele abre essa página num Chrome invisível, avança quadro a quadro, fotografa cada um e junta tudo com o FFmpeg. Como é tudo HTML, qualquer coisa que um navegador consegue desenhar vira vídeo, e a mesma página dá sempre o mesmo resultado.
Além disso, a documentação é incrível. Acredito que não usei nem 30% do que essa biblioteca consegue fazer, e dá para ter muito mais criatividade do que eu tive até aqui. Estou começando agora, e acho que ela é um ponto de partida muito bom para criar qualquer coisa em vídeo.
LinkDocumentação do HyperFrames ↗A fita: o modelo que lê som a som
A fita, com certeza, foi uma das que mais me surpreenderam. Testei várias coisas para conseguir uma transcrição exata do que eu estava falando, e essa foi a melhor de todas.
É a fita que expliquei no corte: ela sabe os sons do que você falou, letra por letra, inclusive quando você repete uma frase.
Nos testes de estresse, nada chegou perto. A AssemblyAI, em todas as configurações que testei, juntava as duas tentativas de uma frase numa só, e, das outras que pesquisei, a única que marcava as repetições nem instalava direito no Windows. E o melhor de tudo: a fita roda local, no meu computador, e bem tranquila.
LinkO modelo no Hugging Face ↗O som: DeepFilterNet3 e DNSMOS
Essas duas cuidam da limpeza do áudio, e trabalham em dupla. O DNSMOS, da Microsoft, é um modelo que escuta a gravação e dá três notas, como uma pessoa daria: para a voz, para o fundo e para o conjunto. É por essas notas que o projeto decide se tem ruído para tirar e, depois, se a limpeza preservou a voz.
O DeepFilterNet3 é quem tira o ruído de fato. É um modelo de código aberto que separa a voz do barulho de fundo, e roda no computador sem precisar de placa de vídeo. Antes dele, usávamos um filtro fixo, e ele acabava piorando as gravações que já estavam limpas.
LinkDeepFilterNet no GitHub ↗O corpo: RTMPose, MediaPipe e YuNet
Essas foram as ferramentas que deixaram as coisas mais legais. As animações já funcionavam, mas eu queria algo que rastreasse o meu movimento. Sabia que não ia ser tão difícil, porque provavelmente já existia algo pronto.
Do OpenCV, usei uma coisa bem específica, o YuNet, que acha o rosto. Sei que o OpenCV tem muito mais, e talvez eu não tenha visto tudo.
Aqui também fiz testes de estresse: coloquei oito bibliotecas lado a lado no mesmo vídeo, entre elas o SAM 2 e o CoTracker, da Meta, o YOLO e até o Gemini, e essas três foram as que deram melhor. E, como eu já tinha falado, o mais surpreendente é que tudo roda no PC tranquilamente, sem nenhum problema.
Linkrtmlib no GitHub ↗Os serviços de fora
Sobre custos: tudo aqui roda essencialmente local, e para o projeto inteiro eu só precisei de um plano do Claude: tudo foi rodado pelo Claude Code. Mas usei duas coisas de fora, a AssemblyAI e o gpt-image-2. Dá para fazer o vídeo sem elas: sem a AssemblyAI, ele só sai sem legenda.
O gpt-image-2 foi usado só para os assets premium. Os assets que o React fazia já eram suficientes para um vídeo de muita qualidade, mas como eu queria algo um pouco mais personalizado e bonito, gerei alguns com ele. Foram poucos, só algumas janelas.
A AssemblyAI é usada numa etapa só, a da legenda, para trazer o texto bem escrito. Ela é só por enquanto: já conheço alternativas melhores, só ainda não tive tempo de testar, e acredito que dá para fazer o mesmo com um modelo que não custa nada. A gente só está usando porque queria responder rápido uma pergunta e fazer funcionar de um jeito eficiente.