1 pontos por GN⁺ 1 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • O gargalo de um arquivo de vídeos não era a ferramenta de edição, e sim a impossibilidade de busca; o foco foi transformar clipes sem rótulo em um índice consultável em inglês
  • Com um design local-first, foram criados arquivos sidecar .description.md ao lado de cada clipe, extraindo em uma única chamada de visão rating, iluminação, localização, transcrição, palavras-chave e descrição em prosa
  • O pipeline reúne ffprobe, exiftool, Nominatim, ffmpeg, WhisperX, insightface e um modelo de visão para gerar metadados, GPS, frames, transcrições e embeddings faciais
  • Um MacBook Pro de 16 polegadas de 2021 com M1 Max e 64GB rodou o Gemma 4 31B Q4 no LM Studio, e durante o processamento em lote o swap chegou a 50,89GB
  • Um esquema estruturado e restrições com enum reduziram alucinações, e foi possível montar um fluxo em que a indexação em massa roda no 31B local e só os 10~20% mais difíceis são reavaliados por um modelo em nuvem

O ponto de partida do problema: busca, não edição

  • Durante quase meio ano na Maasai Mara, vídeos gravados com iPhone, DJI Pocket, drone, Nikon Z8 e Ray-Ban Meta continuaram se acumulando, mas a maioria acabou ficando sem nunca mais ser aberta
  • Os canais sociais da Mara Hilltop ficaram parados por 3 meses não por falta de conteúdo, mas por falta de tempo de edição
  • Com Claude Code e Opus 4.5/4.6, o trabalho de desenvolvimento passou a permitir execução longa de agentes e tarefas paralelas, e isso, somado ao lançamento da primeira hospedagem paga do KaribuKit, reduziu ainda mais o tempo disponível para editar vídeo
  • A primeira solução imaginada foi uma stack SaaS de US$ 140/mês combinando Eddie AI, Higgsfield MCP, Submagic e Buffer, mas isso não atacava o gargalo real
  • Vídeo generativo por IA não combinava com uma marca de viagem real, e cenas de IA exibidas de forma incorreta poderiam prejudicar a confiança quando os hóspedes esperam ver o lugar de verdade
  • A frequência de postagem realista era mais próxima de 2 a 3 por semana, não de 3 a 5, então o plano inicial provavelmente falharia já na segunda semana
  • Como DaVinci Resolve Studio e os recursos IntelliSearch, Smart Bins e Voice to Subtitle do Resolve 21 já cobriam cerca de 70% do que o Eddie oferecia, a maior parte já estava disponível
  • O que restava era uma estrutura em que o Claude Code controlaria o Resolve via o MCP open source do DaVinci Resolve e usaria ElevenLabs para voiceover apenas em clipes informativos, reduzindo o custo para US$ 22/mês

O gargalo real: antes de um editor com IA, era preciso um índice

  • Os editores de vídeo com IA no mercado presumem que o vídeo já está rotulado, mas na prática o arquivo real estava espalhado com nomes como IMG_*.mov, DJI_*.mp4 e Mara june 2024 backup final FINAL
  • O Eddie permitia busca por transcrição, mas não conseguia encontrar cenas como “elefantes no alto da colina na golden hour” em um arquivo sem rótulos
  • Nome do arquivo, pasta pai, coordenadas GPS e texto da transcrição não são suficientes para saber o conteúdo visual de algo como “um plano aberto do nascer do sol com girafas no quadro”
  • O verdadeiro ponto de alavancagem não estava acima do editor, mas antes dele: primeiro era necessário um índice que tornasse o arquivo consultável em inglês

Design do indexador local-first

  • A estrutura geral era parecida com os builds AI-native que a SimbaStack faz para clientes, mas como a mesma pessoa era cliente e engenheiro, as decisões puderam ser tomadas rapidamente
  • Quatro restrições

    • Precisava ser local-first
      • O arquivo da Mara Hilltop estava em SSDs físicos e os vídeos pessoais no notebook, então enviar milhares de clipes de vários GB para a nuvem não fazia sentido nem em custo nem em privacidade
    • Havia preferência por arquivos sidecar em vez de um banco central
      • Um .description.md foi colocado ao lado de cada clipe para permitir busca com grep em texto puro
      • Mesmo que o indexador quebrasse depois, os arquivos permaneceriam, e ao mover entre drives os dados iriam junto
    • Era preciso extrair tudo o que importava em uma única chamada de visão
      • Como o passo de visão sobre frames extraídos é caro, o esquema foi desenhado desde o início de forma ampla para já capturar também informações que poderiam ser úteis depois
      • Isso incluía rating, qualidade técnica, iluminação, hora do dia, paleta de cores, qualidade do áudio, número de pessoas, palavras-chave, rostos, localização, transcrição e descrição em prosa
    • Era necessário poder escolher entre três backends de visão
      • O padrão era a CLI do Claude Max, já inclusa na assinatura e sem custo marginal
      • Quando velocidade era prioridade, usava-se a API da Anthropic
      • Para processamento em lote, foi usado um backend local apontando para o LM Studio, e esse backend local era a peça central

Pipeline de processamento por clipe

  • ffprobe lê os metadados
  • exiftool lê latitude, longitude e altitude do GPS, funcionando igualmente em vídeos de iPhone, DJI Pocket e drone
  • O Nominatim faz reverse geocoding; é gratuito, tem limite de taxa e não exige chave de API
  • ffmpeg extrai 5 frames de 1920px em intervalos uniformes
  • WhisperX faz a transcrição com alinhamento por palavra e diarização de falantes com pyannote, com suporte a 97 idiomas, incluindo hindi, inglês e suaíli
  • insightface detecta rostos e salva embeddings ArcFace de 512 dimensões em um banco facial SQLite central para permitir busca por pessoas em todo o arquivo depois
  • O modelo de visão lê frames, partes da transcrição e o contexto da pasta, e retorna frontmatter em YAML e uma descrição em prosa
  • O resultado final é gravado como um sidecar .description.md ao lado do clipe
  • No clipe real IMG_1103.MOV da Mara Hilltop, o nome do arquivo sozinho não dizia nada sobre o contexto, mas o sidecar gerado pelo Gemma incluía montagem de tenda de safári, um movimento de câmera do interior para a savana, tipo de plano e usos como reels de marketing e B-roll de vlog de viagem
  • No nível da pasta, além dos sidecars ao lado de cada clipe, também eram gerados _INDEX.json e _INDEX.md para grep rápido e envio para LLMs
  • A implementação toda ficou em cerca de 1.400 linhas de Python como uma skill do Claude Code; a maior parte foi escrita pelo próprio Claude Code, enquanto o papel humano ficou em arquitetura, prompts, design de esquema e triagem de bugs

Um modelo local 31B rodando em um MacBook antigo

  • O MacBook Pro de 16 polegadas com M1 Max e 64GB de RAM comprado em 2021 não foi escolhido originalmente para LLMs, mas para rodar ao mesmo tempo abas do Chrome, DaVinci Resolve, Slack, Discord e Drive
  • Cinco anos depois, o mesmo notebook rodou o Gemma 4 31B Q4 no LM Studio e processou um arquivo de vídeo de um ano inteiro
  • No LM Studio, um modelo de 28,40GB foi carregado na memória, e a API REST ficou disponível em 127.0.0.1:1234
  • Durante o processamento em lote, 64GB de RAM não foram suficientes, e o uso de swap no Activity Monitor chegou ao pico de 50,89GB
  • Isso não era um estado para manter continuamente em um dia normal de trabalho, mas foi considerado aceitável para forçar a máquina durante um fim de semana
  • O notebook esquentou, os ventiladores dispararam, mas continuou gerando sidecars enquanto outras tarefas eram feitas
  • O MacBook Pro M1 Max de 16 polegadas mostrou margem para rodar um modelo de 31B parâmetros em velocidade utilizável mesmo em hardware de 5 anos, e se os LLMs locais ficarem mais eficientes, ainda deve servir por mais 3 a 5 anos

Quatro bugs e lições aprendidas

  • Mudança de API na diarização do WhisperX 3.8

    • No WhisperX 3.8, whisperx.DiarizationPipeline foi movido para o submódulo whisperx.diarize
    • O argumento do construtor use_auth_token foi renomeado para token, acompanhando o pyannote 3.x
    • A solução foi introspecção de assinatura
    • O script tenta primeiro token= e, se o construtor lançar TypeError, faz fallback para use_auth_token=
    • Ao chamar bibliotecas de IA que mudam rápido, uma chamada defensiva ao construtor funciona como um seguro barato
  • A CLI do Claude devolvia erro de permissão como se fosse resposta bem-sucedida

    • No primeiro teste do backend da CLI, os 4 sidecars voltaram com o mesmo texto: “I need permission to read the image frames...”
    • O código de saída era 0 e a saída não estava vazia, então o script considerou aquilo um sucesso
    • Sem --permission-mode bypassPermissions no modo não interativo, a Claude CLI devolvia o texto de negação de permissão no corpo da resposta em vez do prompt
    • A solução foi adicionar essa flag e tratar respostas curtas contendo “I need permission” como erro, não como descrição
    • Ao usar ferramentas de IA em scripts, fluxos de permissão não interativos podem esconder falhas silenciosas
  • O Gemma retornava people_count: "many"

    • Como o prompt de visão instruía integer or the string "many" if >10, o Gemma na verdade estava seguindo a instrução corretamente
    • O bug não estava no modelo, mas no design do esquema
    • Depois da correção, passou-se a pedir uma estimativa inteira entre 0 e 99, e respostas antigas com "many" passaram a ser convertidas à força pelo parser
    • Campos do esquema não devem ser definidos como union do tipo int ou string específica; é melhor fixar sempre como inteiro ou sempre como string para simplificar o consumo downstream
  • Um clipe tremido de moto foi descartado por engano

    • O prompt inicial de cull seguia mais um padrão de portfólio fotográfico, então motion blur pesado, foco suave e tremor recebiam nota cull
    • Um clipe noturno handheld de uma viagem à Espanha, gravado na moto, também foi marcado para descarte, embora justamente esse desfoque carregasse a atmosfera da lembrança
    • O critério de cull foi alterado de “filmagem imperfeita” para “algo que não é um registro real”
    • Os descartes passaram a se restringir a clipes como tampa da lente, gravação dentro do bolso, testes de 2 segundos e exposição completamente estourada
    • Arquivos de fotos podem ter cull agressivo, mas memórias em vídeo exigem um cull mais tolerante; mesmo com o mesmo esquema, os modos precisam ficar explícitos

Conclusões com esquema estruturado e modelo local

  • Restrições com enum reduzem alucinações

    • O Gemma 4 E4B descreveu uma foto noturna de um coworking como “brightly lit, abundant natural light, floor-to-ceiling windows”, embora do lado de fora estivesse completamente escuro
    • Quando recebeu um esquema estruturado e teve que escolher entre golden_hour | bright_daylight | overcast | dim_interior | nighttime | mixed | unclear, o 31B recuperou nighttime tanto com thinking-off quanto com thinking-on
    • Em prosa aberta, o modelo pode inventar descrições falsas, mas em um enum ele não pode criar novos valores, só escolher o errado
    • O esquema se mostrou mais seguro do que a instrução
  • Um 31B local com prompts estruturados reduz a distância para a nuvem

    • O Gemma 4 31B Q4 em thinking-off, usando esquema estruturado, produziu em muitos clipes de teste saídas difíceis de distinguir das do Sonnet 4.6
    • O prêmio dos modelos de nuvem estava nos 10~20% de clipes mais difíceis
    • Para o trabalho em massa de indexar milhares de clipes durante a noite, fazia sentido rodar localmente e mandar para a nuvem apenas os clipes marcados como review pelo modelo local, num fluxo de duas etapas escalável
  • Editores de vídeo com IA estão competindo em uma camada alta demais

    • A camada realmente valiosa não era o editor, e sim um índice pesquisável
    • Se for possível consultar em linguagem natural algo como “clipes handheld internos na Mara, golden hour, com pessoas e mais de 8 segundos”, o editor acima disso fica muito mais simples
    • O mercado de editores de vídeo com IA está competindo em uma camada superficial sobre um índice que não existe, pulando justamente a pré-condição

Próximos passos e limitações

  • O próximo trabalho é criar um editor usando o Claude Code como orquestrador, o DaVinci Resolve MCP para montar cortes e o ElevenLabs para adicionar voiceover em clipes informativos
  • Há limites claros para clonagem de voz
    • Ela será usada apenas em conteúdo utilitário, como orientações, descrição de quartos, versões multilíngues e informações factuais que a pessoa realmente diria
    • Não será usada em avaliações nem em mensagens do fundador
    • Em 2026, regras de divulgação obrigatória já são uma realidade plausível, e a confiança em uma marca de hospitalidade pode se perder facilmente
  • Com o índice, dá para evitar scrub manual em 47GB de vídeos da DJI Pocket só para encontrar um plano aberto do nascer do sol
  • Agora, no notebook de 5 anos, um ano inteiro de vídeos da Mara Hilltop já pode ser consultado em inglês, ao custo de um fim de semana e 50GB de swap
  • Os anos restantes, ainda espalhados por SSDs antigos, são o próximo alvo de processamento
  • Os canais sociais da Mara Hilltop ainda não voltaram à ativa
    • O indexador resolve apenas o problema de encontrar os clipes certos
    • A outra metade é o editor que transforme isso em reels prontos; se der certo, haverá um texto de continuação, e se falhar, o motivo do fracasso será abordado
  • A resposta correta talvez seja contratar uma pessoa
    • Encontrar um editor com o olhar caloroso e observador que combine com a Mara Hilltop pode ser mais difícil do que escrever mais uma skill
    • Reels no estilo MTV, cortados em excesso, não são o que se quer
  • O código foi publicado em github.com/Simbastack-hq/framedex e está aberto a PRs e issues

1 comentários

 
GN⁺ 1 시간 전
Comentários do Hacker News
  • Parece que o Claude escolheu a URL errada para compartilhar o post. A menos que a pasta home tenha sido exposta publicamente, não dá para acessar ~/.claude/skills/video-index/, então fiquei curioso se você poderia compartilhar os arquivos de Skill

    • É como ver uma versão moderna daquela situação clássica em que um amigo que acabou de começar a programar manda: “fiz meu app web, quer ver? Está aqui: http://localhost:8080”
    • Ops, foi erro meu. Já estou corrigindo isso e também posso compartilhar os arquivos de Skill. Me dá 5 minutos
  • Atualização: criei este repositório às pressas - https://github.com/Simbastack-hq/framedex
    A licença é MIT, e ainda não consegui testar tudo direito depois de generalizar o projeto. Vou revisar com calma em breve e adicionar mais atualizações
    Os dois grandes itens do TODO são: 1) usar essa indexação com a ajuda do Claude para editar vídeo mais rápido no DaVinci Resolve, 2) por enquanto ele só processa vídeo, mas quero expandir para também entender os milhares de imagens estáticas da câmera

  • Não entendi bem por que tanto swap é necessário. Considerando a largura de banda de memória exigida, isso pode desgastar o SSD bem rápido
    O modelo quantizado em 4 bits do Gemma 4 31B deveria ter algo em torno de 19GiB, não 28.4GiB [1]. Não costumo passar imagens com frequência, então não sei quanta memória extra isso exige no contexto, mas imagino que não passe de 10GiB
    Pelo Monitor de Atividade, além do Handy e da máquina virtual do Claude Code que aparentemente carregaram o modelo, também havia vários apps Electron abertos, então parece que a causa real está mais aí. Quando o notebook começa a acessar o disco pesadamente, esses apps acabam travando e ficando inúteis
    [1] https://huggingface.co/mlx-community/gemma-4-31b-it-4bit

    • Verdade. Eu estava fazendo outras coisas no notebook quando tirei a captura de tela, então dava para ter organizado melhor
      Mesmo assim, achei impressionante que, embora tenha ficado um pouco engasgado, eu ainda conseguia continuar trabalhando com outras coisas mesmo com várias abas abertas no Brave
  • Fiquei curioso se você sabia que isso já existe, funciona bem e não consome 50GB de swap
    https://github.com/iliashad/edit-mind

  • Muito legal. Queria ter RAM suficiente para rodar um modelo local. Nas últimas semanas fiz algo bem parecido, mas como um app local em Electron usando Whisper e ffmpeg, com busca semântica e embeddings para conversar com o vídeo
    A análise visual, a tagueação e o chat com o vídeo se comunicam com o Claude. Fiquei curioso se este projeto envia só uma imagem. Eu encontro várias imagens diferentes por vídeo com um algoritmo de detecção de cena personalizado e envio tudo para o Claude em uma única requisição junto com as legendas. Sem dúvida essa é a parte mais cara. Usando Sonnet 4.6 para análise e Haiku para tagueação, sai por cerca de 1 dólar para 1 hora de vídeo, e localmente provavelmente seria lento

    • Não é uma imagem só, envio 5 frames por clipe em uma única requisição junto com parte das legendas. Então essa parte de colocar vários frames e legendas de uma vez é igual
      Só que a forma como escolho os frames é um ponto fraco. Detecção de cena certamente ajudaria e é minha prioridade número 1 no roadmap. Fiquei curioso se você poderia compartilhar como escolhe os frames na detecção de cena
      Optei por não incluir busca vetorial e manter tudo simples com arquivos Markdown genéricos e mais portáveis. Se eu mover o SSD, o conhecimento vai junto com os arquivos, não há índice para sincronizar, e texto puro genérico tende a sobreviver mais do que ferramentas. Ainda assim, vale explorar a outra direção que você mencionou
    • Se quiser reduzir custos, vale testar os modelos do OpenRouter. O Gemma 4 31B custa 0,12 dólar por 1 milhão de tokens de entrada e 0,37 dólar por 1 milhão de tokens de saída, enquanto o Haiku custa 1 dólar por 1 milhão de tokens de entrada e 5 dólares por 1 milhão de tokens de saída
      Há outras opções boas também. O Gemini 3.1 Flash Lite é muito bom para esse tipo de tarefa. Só não o Gemini 3.5 Flash. Esse tem um custo-benefício ruim
      https://openrouter.ai/google/gemma-4-31b-it
  • Tenho duas perguntas

    1. Fiquei curioso sobre o que é o índice de busca
    2. No exemplo de description.md há itens como faces -> cluster_id. Isso vem do índice facial do DaVinci Resolve? Em coleções de fotos, informações como rostos+nomes e localização são realmente importantes, e LLMs em geral não lidam bem com isso
      1. É só um arquivo sidecar de texto puro .description.md colocado ao lado do vídeo para cada clipe
        Depois, ao fazer brainstorming com o Claude sobre algo como “quero montar um vídeo dos quartos premium da pousada”, ele pode consultar os arquivos e descobrir quais vídeos seriam úteis
        Também há um arquivo em nível de raiz da pasta reunindo descrições em texto para facilitar a busca. Coloquei uma imagem de exemplo no blog - https://blog.simbastack.com/_media/gvcycx2n.png
      2. Não veio do DaVinci Resolve. O Framedex é um pipeline independente e o Resolve não participa
        Os rostos vêm do insightface. Eu detecto com RetinaFace do pacote open source buffalo_l e rodo tudo localmente na CPU. Depois detecto e gero embeddings dos rostos a partir de frames de amostra de cada clipe e gravo linhas em ~/.framedex/faces.db
        Sinceramente, essa parte eu ainda não testei direito; sei que está sendo acumulada num banco local, mas ainda não validei quão bem funciona. Vou verificar isso em breve
        De forma mais ampla, é justamente por isso que o framedex intencionalmente não delega rostos nem localização ao LLM. Rostos são tratados com embeddings do insightface / ArcFace, o que permite comparação determinística entre clipes. O modelo visual só fornece uma contagem aproximada de pessoas, sem tentar identificar quem são
        A localização é tratada com EXIF GPS via exiftool e geocodificação reversa com Nominatim/OpenStreetMap. Não é chute, é metadado sólido
        O LLM faz só o que ele faz bem: descrição de cena, clima, tipo de tomada, palavras-chave e notas de arquivar/revisar/descartar. Essa parte final das notas é discutível
  • Tentei rodar o Gemma num ThinkPad de 2015 para fazer algo parecido. Felizmente consegui fazer upgrade de memória; sem isso teria sido bem sofrido
    Não vou mentir: rodando llama.cpp, a ventoinha ficou no máximo. Mesmo assim funcionou e concluí o trabalho

    • Essa expressão “a ventoinha ficou no máximo” sempre me confunde. Se a ideia é terminar o cálculo o mais rápido possível, não é inevitável gerar e dissipar mais calor?
      Às vezes parece ser só uma metáfora para “está usando 100% dos recursos”, e provavelmente é isso aqui, mas em outros contextos também já vi gente falando disso como uma reclamação literal
  • Acho que a maioria dos anfitriões do Airbnb não concordaria com a frase “vídeo gerado por IA não tem lugar para uma marca de viagem de verdade”
    E essa expressão “crucificação no TripAdvisor” também me faz pensar como anfitriões do Airbnb com anúncios falsos conseguem sobreviver

    • Sinceramente, eu também penso bastante nisso. Eu administro um safari lodge, mas não quero seguir pelo caminho de vídeo de IA de baixa qualidade
      Por outro lado, vídeo real leva tempo e desacelera todo o processo
  • Vejo uma limitação estrutural em aplicações B2C de IA: é difícil criar contexto personalizado
    Se modelos locais competentes conseguirem fazer coleta de contexto, pesquisa, tagueação etc. do zero em grande escala, isso pode ser um grande avanço

    • Criei um app B2C de IA totalmente local para renomeação contextual de arquivos, e ele é gratuito
      Você pode jogar várias capturas de tela nele, e ele tenta dar nomes inteligentes com base no conteúdo. O mesmo vale para vídeos, PDFs etc.
      Mas, como você disse, nem tentei cobrar por isso porque parece o tipo de coisa que a Apple pode simplesmente adicionar como recurso
      https://finalfinalreallyfinaluntitleddocumentv3.com/
    • Concordo completamente. Aqui, eu e o Claude fizemos juntos esse trabalho de pesquisa e tentativa e erro durante o brainstorming
      Mas acho que é só uma questão de tempo até os agentes ficarem inteligentes o bastante para que amigos não técnicos possam apenas dizer “organize os vídeos desta pasta para que eu consiga entendê-los”, e isso aconteça automaticamente
    • Fico me perguntando se modelos locais são mesmo o que resolve isso. APIs de modelos sem armazenamento de estado não oferecem a mesma vantagem? Entendo que local pode ser “mais barato” dependendo do uso, mas já faz muito tempo que pagamos um prêmio para alugar armazenamento e computação na nuvem