6

Pitch: Apresentação do Projeto: Crom Video Gen & Miniflow Go - Como arquitetamos um gerador de vídeos autônomo com IA (Python) e motor de renderização concorrente (Go)

Existe um grande mercado de SaaS para geração automática de vídeos. Mas a maioria dessas soluções depende de processamento pesado em nuvem ou de APIs caras e de código fechado.

Para ter controle total sobre a performance, decidimos construir um ecossistema local e modular composto por duas partes:

  1. Orquestrador de Agentes (Python): Responsável pela ingestão do briefing, modelagem da história (roteiro em 3 atos) e decupagem dos ativos de mídia.
  2. Motor de Renderização Concorrente (Go): Um motor de baixo nível que compõe layouts responsivos, sobreposições gráficas, síntese de voz (TTS) e mixagem de áudio nativa por meio do FFmpeg.

Abaixo, detalho as decisões de engenharia, arquitetura e soluções que tornaram este projeto viável.


🏗️ Fluxo de Trabalho (Workflow Híbrido)

A orquestração separa a camada de decisão criativa (IA) da camada de execução física (gráficos e áudio):

graph TD
    A["📄 briefing.txt (Briefing)"] --> B["🐍 Orquestrador (Python)"]
    B --> C["🤖 Pipeline de Agentes Especialistas"]
    C --> D["🛡️ Revisor de Qualidade do Template"]
    D -- "Reprovado (Auto-Correção)" --> C
    D -- "Aprovado" --> E["🚀 Engine Go (Miniflow)"]
    E --> F["🔊 Síntese TTS (Cromyvoice)"]
    E --> G["🎞️ Renderizador de Frames (FFmpeg)"]
    G --> H["🎬 video_final.mp4"]
    
    subgraph "Pipeline de Agentes"
        C1["🔍 Pesquisador (pesquisa.md)"] --> C2["✍️ Roteirista (roteiro.md)"]
        C2 --> C3["🕵️ Revisor Narrativo"]
        C3 --> C4["🎬 Diretor (direcao.json)"]
        C4 --> C5["📦 Produtor (producao.json)"]
        C5 --> C6["✂️ Editor (video_template.json)"]
    end

🛠️ Desafios Técnicos de Engenharia e Como os Resolvemos

1. Robustez contra Alucinações de Caminhos de LLM

O maior problema prático ao usar IAs para editar arquivos JSON complexos (como o nosso video_template.json) é que os modelos frequentemente erram as estruturas de diretórios dos ativos de mídia local, escrevendo por exemplo "midias/video.mp4" quando o arquivo correto está na pasta "inputs/backgrounds/video.mp4".

Para blindar o motor contra falhas, adicionamos uma rotina de busca recursiva com fallback em Go na função ResolveRelativePaths. Se o caminho indicado pela IA falhar na checagem inicial de existência do arquivo, o motor faz uma busca recursiva inteligente (filepath.Walk) no diretório inputs/ pelo nome base do arquivo (basename):

pathDirect := filepath.Clean(filepath.Join(workspaceDir, el.Content))
if _, err := os.Stat(pathDirect); err != nil {
	pathInputs := filepath.Clean(filepath.Join(workspaceDir, "inputs", el.Content))
	if _, err2 := os.Stat(pathInputs); err2 == nil {
		el.Content = pathInputs
	} else {
		// Fallback recursivo: busca o nome base em qualquer subdiretório de inputs/
		baseName := filepath.Base(el.Content)
		_ = filepath.Walk(filepath.Join(workspaceDir, "inputs"), func(path string, info os.FileInfo, err error) error {
			if err == nil && !info.IsDir() && info.Name() == baseName {
				el.Content = path
				return filepath.SkipAll
			}
			return nil
		})
	}
}

2. Sincronismo Fino de Áudio (TTS) e Margens Naturais

Para evitar transições bruscas onde o narrador começa a falar no instante exato da mudança de slide, implementamos um mecanismo de controle temporal baseado em duas frentes:

  • Duração Dinâmica por TTS: No arquivo Go tts.go, a duração do card não é estática. Ela é calculada após a geração do áudio e ajustada com uma folga fixa de 2 segundos:
    Durac¸a˜o=AudioDuration+2.0s\text{Duração} = \lceil\text{AudioDuration} + 2.0\text{s}\rceil
  • Filtro de Atraso e Padding: No renderizador Go renderer.go, aplicamos o filtro adelay do FFmpeg (adelay=delays=1000:all=1) no canal de áudio da narração. Isso cria uma margem de 1.0 segundo de silêncio de entrada na cena, seguido pela locução fluida e finalizando com 1.0 segundo de silêncio de saída, gerando transições suaves de áudio e vídeo.

3. Layouts Responsivos e Contraste das Legendas

O texto precisa ser legível sobre qualquer tipo de vídeo ou imagem (sejam mídias claras, escuras ou saturadas). A nossa solução desenha as legendas em renderer.go com uma sombra/contorno de 2px em 4 direções diagonais:

subX := float64(res.Width) / 2.0
subY := float64(res.Height) * 0.88
maxWidth := float64(res.Width) * 0.85

// Desenha contorno preto em 4 diagonais para alto contraste
dc.SetHexColor("#000000")
dc.DrawStringWrapped(card.Narration, subX+2, subY+2, 0.5, 0.5, maxWidth, 1.4, gg.AlignCenter)
dc.DrawStringWrapped(card.Narration, subX-2, subY+2, 0.5, 0.5, maxWidth, 1.4, gg.AlignCenter)
dc.DrawStringWrapped(card.Narration, subX+2, subY-2, 0.5, 0.5, maxWidth, 1.4, gg.AlignCenter)
dc.DrawStringWrapped(card.Narration, subX-2, subY-2, 0.5, 0.5, maxWidth, 1.4, gg.AlignCenter)

// Desenha o texto branco principal por cima
dc.SetHexColor("#ffffff")
dc.DrawStringWrapped(card.Narration, subX, subY, 0.5, 0.5, maxWidth, 1.4, gg.AlignCenter)

No modo vertical (vídeos no formato retrato), a lógica do DrawCardState detecta a proporção da tela (height > width), empilha a imagem/vídeo centralizadamente no topo e desloca o bloco de texto para baixo aplicando uma escala de fonte segura (24px).

4. Concorrência e Pipeline Paralela

Go brilha quando o assunto é paralelismo. Dividimos o processamento gráfico de cada cena em workers concorrentes usando um pool paralelo gerenciado em Go. Isso nos permite renderizar múltiplos cartões simultaneamente, mantendo a CPU ocupada a quase 100%, reduzindo o tempo de processamento do vídeo de 5 minutos para pouco menos de 2 minutos.


Para quem quiser inspecionar e testar o código-fonte localmente:


O que acharam desse modelo de arquitetura híbrida (Python para IA e Go para Computação Gráfica / FFmpeg)? Feedbacks e sugestões de otimização de renderização são muito bem-vindos nos comentários!

Carregando publicação patrocinada...
5

Meus 2 cents,

Parabens pela iniciativa !

O projeto como um todo parece bem robusto - ja entrou na fila para testar.

O video de teste renderizado ficou bom, com alguns detalhes que precisam ser trabalhados (p.ex. falar siglas), mas nada que abale o resultado geral.

Repositorio devidamente starreado e forkeado - obrigado por compartilhar !

Saude e Sucesso !


Este post foi favoritado via extensão TABNEWS FAVORITOS

Tem curiosidade sobre IA ? Da uma olhada no meu LIVRO: IA PARA ENGENHEIROS

1

se fizer algum video, pode mandar mensagem no discord, ai deixo como colab no canal do youtube da crom e o seu canal(se quiser.)

4

Top. Me parece similar a alguns outros que já vi, mas da pra ver que tem uma boa base. O problema é q estes videos sempre são muito "sem sal". São slides com uma voz lendo, um tanto estático. Fico pensando e se usasse python para criar animations, gráficos etc. Estilo aqueles videos do 3blue1brown. Já vi usarem uma lib específica de react... Tenho salvo no meu github starts este projeto gringo, porém esqueci o nome

1

Eu tenho um outro projeto que é mais assim, você passa o html como template, mas eu não tenho placa de video nesse novo computador que comprei, ai preciso ficar vendo maneira de deixar o processo de renderização mais rapido. Opitei por programar boa parte em go, e o python só usei para montar os outros repositorios e a ideia em sim, provavelmente vou remover o python e deixar apenas go.

O outro projeto é mais demorado para renderizar: https://github.com/MrJc01/crom-video-gen

a ideia é passar templates em html/css/js, e depois só mandar um json para montar eles.

video gerado nesse: https://www.youtube.com/watch?v=KY_3WKwfyyI

4
1

No caso, no binario final, você pode simples definir quantas threads você quer usar. Como expliquei no outro comentário:

"eu sei, é que são projetos com finalidade gerais, ai reutilizo, se tiver adoção de pessoas, eu unifico tudo de forma idependente, é só que fica mais facil usar os outros projetos como ferramentas modulares, ai nao preciso ficare recriando tudo toda vez."

Conteúdo excluído
1

Tirar ideias proprias do papel, é supreendente com IA, recomendo o antigravity(ainda nao terminei totalmente o crom-agente, mas uso nesse projeto de video o crom-agente e o crom-agente-sdk)

Qualquer dica ou tester, chama lá no discord https://crom.run/comunidade

Conteúdo excluído
1

eu sei, é que são projetos com finalidade gerais, ai reutilizo, se tiver adoção de pessoas, eu unifico tudo de forma idependente, é só que fica mais facil usar os outros projetos como ferramentas modulares, ai nao preciso ficare recriando tudo toda vez.