Files
gart/.claude/skills/editar-por-voz/SKILL.md
T
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

117 lines
5.6 KiB
Markdown

---
name: editar-por-voz
description: 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.