Files
João HenriqueandClaude Sonnet 5 7b5aed79ee feat(voz): legenda por ênfase, forced align, IA local e correções de zoom/revisão
Trabalho da branch feat/revisao-enfases: pipeline de edição por voz ganha
alinhamento forçado (whisperx), roteirização por LLM local (Ollama), e a
etapa 5 (revisão de frases) passa a refletir de verdade o que é aplicado.

- generate_subtitles_by_emphasis: legenda comum cobre o clipe inteiro,
  legenda dinâmica só nas frases de ênfase, e a comum é desativada
  (enabled="0") onde a dinâmica cobre, em vez de nunca ser gerada ali.
- validate_subtitle_layout ignora títulos com enabled="0" — corrige falso
  positivo de colisão contra o que está desativado no lugar dele.
- Corrige zoom/marcador sendo descartado quando a borda encosta exatamente
  no início de um corte.
- Etapa 5 do Assistente: recarrega quando as decisões da IA mudam (com
  fresh=true, ignorando a revisão salva antiga) — resolve a dessincronia
  entre "ativa" na tela e o que já foi cortado no FCPXML.
- Etapa "Processar" reaplica as decisões da revisão (_phrase_actions.json)
  antes da cadeia de remoção de silêncio/legendas — antes, desativar uma
  frase na etapa 5 não tinha efeito nenhum no vídeo final.
- Etapa "Concluído" fundida em "Processar" — abrir no Final Cut/Finder
  aparece assim que termina, sem slide extra.
- Palavra clicável na etapa 5 agora funciona como toggle (clique de novo
  desfaz) e mostra a própria ênfase (sublinhado colorido + peso da fonte).
- fcpxml/forced_align.py, fcpxml/llm_local.py, ai_edit.py: alinhamento
  fonético via whisperx e roteirização local via Ollama/Gemma.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 18:26:04 -04:00

5.6 KiB

name, description
name description
editar-por-voz Edita um vídeo a partir da análise de voz — lê a timeline de voz (JSON) de uma gravação, separa o roteiro da conversa de bastidor, escolhe a melhor tomada de cada frase, decide cortes/zooms/textos e devolve a lista de decisões em JSON. Use quando o usuário pedir para editar por voz, montar um corte automático, limpar tomadas repetidas, escolher as melhores tomadas, ou marcar os momentos de ênfase de uma fala.

Editar por voz

Você recebe um JSON com o que foi dito, por quem e como; devolve um JSON com o que fazer. Quem aplica é o programa — você nunca escreve XML.

Princípio

O sistema já mede como a pessoa falou, de forma reprodutível. Não recalcule nada disso nem reestime tempos "no olho".

Seu trabalho é o que nenhum limiar resolve: o que aquilo significa. O índice diz que uma palavra foi dita com força; só você sabe se ela é o argumento central ou uma piada com o câmera.

Entrada e saída

Entrada: <mídia>_voice_timeline.json (de build_voice_timeline). Se não existir, rode a ferramenta; se existir, leia direto — a análise leva minutos.

Saída: JSON com a lista de ações → criterios/08-formato-de-saida.md

apply_voice_actions aplica direto, mas é para teste. O produto do seu trabalho é a lista de decisões.

Caminho automatizado (sem wizard, sem copiar-e-colar): a tool generate_voice_script (MCP) / comando generate_voice_script (ponte do app) corre o fluxo fechado: transcreve → build_voice_timeline → entrega a timeline a um modelo local Ollama (Gemma 3 / Llama) que age exatamente como este skill descreve (separa roteiro de bastidor, escolhe tomadas, decide zoom/corte) → devolve o roteiro legível e o JSON de ações, e opcionalmente aplica no FCPXML. O cliente fica em code/fcpxml/llm_local.py; o prompt que embute este contrato está em _SYSTEM_PROMPT. Use essa tool quando o usuário pedir para "rodar tudo internamente" ou "gerar o roteiro por IA local".

Para onde ela vai (modo manual): o usuário cola o seu JSON no app, e ele abre na etapa 5 do Assistente — uma tela onde cada frase do roteiro aparece com a sua decisão já marcada, para ser revisada antes de gerar. Você é o ponto de partida da edição, não a palavra final; escreva decisões defensáveis e motivos legíveis. Como o app traduz cada ação sua: criterios/10-revisao-humana.md.

Ordem de trabalho

Siga nesta ordem. Pular a Fase 2 ou a 3 leva a decisões erradas.

Fase O que fazer Critérios
0 Ler layers — saber o que rodou criterios/09-analise-incompleta.md
1 Ler o JSON em camadas criterios/01-leitura-do-json.md
2 Separar roteiro de conversa de bastidor criterios/02-triagem-roteiro-vs-conversa.md
3 Escolher a melhor tomada de cada frase criterios/03-escolha-da-melhor-tomada.md
4 Reanalisar o material que sobrou criterios/04-reanalise-do-material-restante.md
5 Decidir zooms criterios/05-zoom.md
6 Decidir textos, cortes e marcadores criterios/06-texto-corte-marcador.md
7 Cortar a lista pelo ritmo criterios/07-ritmo.md
8 Montar o JSON de saída criterios/08-formato-de-saida.md

Antes da Fase 5, leia criterios/10-revisao-humana.md. Ele descreve o que o app faz com o seu JSON — e muda como escrever cortes e zooms, não só quais.

As três armadilhas

Cada uma já causou erro silencioso em material real:

  1. A conversa de bastidor tem a maior ênfase do vídeo. O índice acústico favorece a fala solta sobre o texto decorado. Separar é tarefa de texto, nunca de limiar — e nem de diarização, já que costuma ser a mesma pessoa.

  2. Ênfase é relativa ao conjunto analisado. Depois de cortar, os números da análise bruta apontam para as palavras erradas. Sempre reanalise (Fase 4) antes de escolher zooms.

  3. Tempos sempre na mídia original. Nunca compense para "depois do corte" — o programa faz isso sozinho, e compensar por conta própria joga todo destaque no frame errado, sem erro visível.

Ordem no sistema

Sua edição roda primeiro, na timeline intacta. Os posicionamentos (zoom, texto, marcador) são deslocados a partir da sua lista de cortes; se outra ferramenta já tiver rippado a timeline antes, esse deslocamento não sabe disso e o efeito cai no frame errado — sem erro visível.

build_voice_timeline → [você decide] → refine_voice_timeline → [você corta
pelo ritmo] → [revisão humana na etapa 5 do app] → apply_voice_actions →
remove_media_silence → generate_dynamic_subtitles

A revisão humana entra entre a sua decisão e a aplicação. É por isso que o reason importa tanto: ele é lido ali, na hora de decidir se a sua escolha fica.

Vícios de linguagem e lacunas longas entram na sua lista, num ripple só (06-texto-corte-marcador.md). Silêncio fino e legendas vêm depois.

generate_dynamic_subtitles nunca é o passo final por si só — sempre seguido de validate_subtitle_layout antes de dar a legenda como pronta. Detalhe do porquê e das regras específicas dessa etapa: code/Engine/docs/03_SERVER_TOOLS.md, seção "Legendas dinâmicas".

Ao relatar

Sempre em português, com o raciocínio e não só o resultado:

  • quantas tomadas encontrou de cada frase e qual escolheu, com o motivo;
  • o que descartou como bastidor;
  • por que cada zoom caiu onde caiu (palavra + ênfase);
  • o que foi descartado ou rejeitado — nunca relate só os acertos;
  • o que você não conseguiu decidir. Em dúvida entre duas tomadas, marque as duas e deixe para o editor.