feat: copiada a skill editar-por-voz e seus critérios para as skil
- copiada a skill editar-por-voz e seus critérios para as skills do projeto - adaptada a skill editar-por-voz para usar o banco SQLite como fonte oficial - corrigida a cópia do JSON do tipo de vídeo para priorizar clipboard Unicode - criado carregador único do contexto de edição por voz a partir do SQLite - criada entrada para registrar planos no SQLite e reaproveitar o mesmo plano na aplicação - habilitado carregamento do plano editorial diretamente do SQLite na interface - corrigido o bloqueio visual da etapa de carregamento do plano salvo - configurado carregamento automático do plano salvo após selecionar a sequência - documentada a sequência como raiz de retomada do fluxo de edição - criada a estrutura local para análise de músicas instrumentais com Essentia Resumo: - 22 arquivos alterados - 11 novos - 11 modificados - 0 removidos 11 files changed, 270 insertions(+), 34 deletions(-) Arquivos: - .jhonny/analises.db - CONTEXT.md - code/cep-plugin/index.html - code/cep-plugin/main.js - code/engine/README.md - code/engine/aplicar_plano_de_edicao.py - code/engine/integracoes/audio/__init__.py - code/engine/persistencia/consultas.py - code/engine/requirements-audio.txt - code/engine/testes/test_consultas_de_persistencia.py - code/tests/cep-tipos-video-encoding.test.ts - code/.jhonny/ - code/engine/carregar_plano_de_edicao.py - code/engine/integracoes/audio/contratos.py - code/engine/integracoes/audio/modelos_de_analise_musical.py - code/engine/integracoes/audio/provider_de_analise_musical_essentia.py - code/engine/preparar_edicao_por_voz.py - code/engine/registrar_plano_de_edicao.py - code/engine/testes/test_analisador_de_musica_essentia.py - code/engine/testes/test_carregar_plano_de_edicao.py - code/engine/testes/test_registrar_plano_de_edicao.py - code/plugins/premiere-pro/skills/editar-por-voz/
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
---
|
||||
name: editar-por-voz
|
||||
description: Edita um vídeo a partir das evidências de voz, transcrição e configuração editorial mantidas no banco SQLite do projeto. Use quando o usuário pedir para editar vídeo, editar por voz, escolher tomadas, limpar repetições ou montar um corte automático.
|
||||
---
|
||||
|
||||
# Editar por voz
|
||||
|
||||
Transforma uma edição concluída no banco em um plano editorial revisável e, após aprovação, em uma alteração verificável no Premiere Pro.
|
||||
|
||||
## Fonte de verdade
|
||||
|
||||
O banco de análises é a fonte oficial. Não procure nem exija um arquivo
|
||||
`*_voice_timeline.json` e não trate JSON temporário, cache ou estado do painel
|
||||
como fonte independente.
|
||||
|
||||
Para carregar o contexto sem escrever SQL, execute:
|
||||
|
||||
```text
|
||||
python3 code/engine/preparar_edicao_por_voz.py --banco .jhonny/analises.db
|
||||
```
|
||||
|
||||
Depois de gerar o JSON de ações, registre-o no banco e use o identificador
|
||||
retornado para aplicar exatamente esse plano:
|
||||
|
||||
```bash
|
||||
python3 code/engine/registrar_plano_de_edicao.py plano.json \
|
||||
--banco .jhonny/analises.db --tipo-de-video depoimento
|
||||
python3 code/engine/aplicar_plano_de_edicao.py plano.json \
|
||||
--banco .jhonny/analises.db --plano-id ID_RETORNADO
|
||||
```
|
||||
|
||||
Use `--video-id` quando o usuário indicar um vídeo específico e
|
||||
`--sem-palavras` somente quando os limites palavra a palavra não forem
|
||||
necessários. A resposta válida vem em `contexto`; trate `ok: false` como
|
||||
bloqueio do fluxo.
|
||||
|
||||
Use a edição concluída mais recente em `edicoes_de_video` como raiz do trabalho.
|
||||
Recupere o restante pelo mesmo `video_id`:
|
||||
|
||||
- `videos`, `faixas` e `clipes`: mídia, sequência e estrutura;
|
||||
- `analises_versao`: versão da análise usada;
|
||||
- `segmentos_de_transcricao` e `palavras_de_transcricao`: falas e tempos;
|
||||
- `evidencias_visuais`: contexto visual, quando disponível;
|
||||
- `planos_de_edicao` e `acoes_do_plano`: decisões já geradas;
|
||||
- `aplicacoes_do_plano`: histórico de execução.
|
||||
|
||||
Leia [criterios/00-fonte-de-dados.md](criterios/00-fonte-de-dados.md) antes de
|
||||
consultar o banco ou quando houver dúvida sobre qual registro usar.
|
||||
|
||||
## Estados obrigatórios
|
||||
|
||||
Trate o trabalho como uma sequência de estados:
|
||||
|
||||
```text
|
||||
edicao_concluida
|
||||
→ contexto_validado
|
||||
→ plano_gerado
|
||||
→ preview_aprovado
|
||||
→ aplicado
|
||||
→ verificado
|
||||
```
|
||||
|
||||
Não aplique um plano sem contexto validado e preview aprovado. Se algum estado
|
||||
ou evidência obrigatória estiver ausente, pare e relate exatamente o que falta.
|
||||
|
||||
## Fluxo
|
||||
|
||||
1. Localize a edição concluída mais recente e confirme vídeo, sequência, tipo,
|
||||
origem, transcrição e versão da análise.
|
||||
2. Reúna do banco a transcrição completa, palavras, falantes, tomadas,
|
||||
métricas e evidências disponíveis. Preserve os tempos da mídia original.
|
||||
3. Leia a configuração editorial salva em `edicoes_de_video.configuracao` e
|
||||
extraia objetivo, narrativa, duração, tom, regras de corte e restrições.
|
||||
4. Separe roteiro de conversa de bastidor pelo conteúdo. Depois agrupe frases
|
||||
repetidas e escolha a tomada completa, clara, natural e coerente.
|
||||
5. Reanalise as ênfases apenas depois de definir o material sobrevivente. Se o
|
||||
banco não tiver métricas ou a camada correspondente estiver incompleta,
|
||||
decida pelo texto e registre a limitação.
|
||||
6. Decida cortes, zooms, textos e marcadores somente quando o contrato de
|
||||
aplicação suportar a ação. Cada ação deve ter motivo verificável.
|
||||
7. Gere um plano com tempos na mídia original. Salve o plano em
|
||||
`planos_de_edicao` e suas ações ordenadas em `acoes_do_plano`, associado ao
|
||||
`video_id`, ao tipo de vídeo e ao contexto editorial carregado.
|
||||
8. Faça preview do plano e apresente as decisões e incertezas para revisão
|
||||
humana. Uma alteração no plano exige novo preview.
|
||||
9. Após aprovação explícita, confirme a sequência atual, crie backup ou
|
||||
duplicata, aplique o plano pelo fluxo suportado do Premiere e registre o
|
||||
resultado em `aplicacoes_do_plano`.
|
||||
10. Reconsulte a timeline, compare com o plano e registre a verificação. Separe
|
||||
o que foi comprovado automaticamente do que exige avaliação visual.
|
||||
|
||||
## Contrato da decisão
|
||||
|
||||
O JSON abaixo é uma representação de trabalho, não a fonte principal:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "0E6A8829.MP4",
|
||||
"actions": [
|
||||
{
|
||||
"kind": "cut",
|
||||
"start": 12.4,
|
||||
"end": 16.8,
|
||||
"reason": "Repetição da frase anterior."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`cut` remove um intervalo. Todos os tempos referem-se à mídia original. A
|
||||
ação precisa ter `start < end`, estar dentro da duração e não sobrepor outra
|
||||
ação incompatível. Use `reason` para registrar a fala, comparação ou evidência
|
||||
que fundamentou a decisão.
|
||||
|
||||
Leia, conforme a etapa, [criterios/02-triagem-roteiro-vs-conversa.md](criterios/02-triagem-roteiro-vs-conversa.md),
|
||||
[criterios/03-escolha-da-melhor-tomada.md](criterios/03-escolha-da-melhor-tomada.md),
|
||||
[criterios/04-reanalise-do-material-restante.md](criterios/04-reanalise-do-material-restante.md),
|
||||
[criterios/05-zoom.md](criterios/05-zoom.md),
|
||||
[criterios/06-texto-corte-marcador.md](criterios/06-texto-corte-marcador.md),
|
||||
[criterios/07-ritmo.md](criterios/07-ritmo.md) e
|
||||
[criterios/10-revisao-humana.md](criterios/10-revisao-humana.md).
|
||||
|
||||
## Limites
|
||||
|
||||
- A skill decide a edição; o Premiere executa.
|
||||
- Nunca invente falas, identidades, timecodes ou evidências.
|
||||
- Não altere o áudio original, a transcrição ou a análise para forçar uma
|
||||
decisão.
|
||||
- Não declare uma edição concluída com base apenas em um JSON, preview ou
|
||||
retorno de ferramenta; exija aplicação e verificação.
|
||||
- Não execute cortes destrutivos sem aprovação e backup/duplicata.
|
||||
|
||||
## Relato
|
||||
|
||||
Relate sempre em português:
|
||||
|
||||
- edição, vídeo e versão da análise usados;
|
||||
- tomadas encontradas e escolhidas, com motivo;
|
||||
- falas descartadas como bastidor ou repetição;
|
||||
- cortes, zooms, textos e marcadores propostos;
|
||||
- decisões rejeitadas ou ambíguas;
|
||||
- plano salvo, aplicação realizada e verificação pendente.
|
||||
@@ -0,0 +1,35 @@
|
||||
# 00 — Fonte de dados: banco de análises
|
||||
|
||||
O banco SQLite do projeto é a fonte oficial da edição por voz. Arquivos JSON
|
||||
podem existir como origem, cache ou exportação, mas não substituem os registros
|
||||
persistidos.
|
||||
|
||||
## Raiz do trabalho
|
||||
|
||||
1. Localize a edição mais recente em `edicoes_de_video`.
|
||||
2. Use seu `video_id` para consultar a análise, a transcrição, os clipes e as
|
||||
evidências.
|
||||
3. Use `edicoes_de_video.configuracao` como briefing editorial salvo.
|
||||
4. Considere a edição duplicada ou antiga somente se o usuário escolher uma
|
||||
edição diferente.
|
||||
|
||||
## Validações mínimas
|
||||
|
||||
Antes de decidir cortes, confirme que existem:
|
||||
|
||||
- vídeo e sequência identificáveis;
|
||||
- pelo menos um clipe com mídia e duração;
|
||||
- segmentos de transcrição com início, fim e texto;
|
||||
- configuração editorial com tipo e objetivo;
|
||||
- versão ou data que permita identificar a análise usada.
|
||||
|
||||
Falantes, palavras, métricas e evidências visuais são camadas adicionais. Se
|
||||
uma camada não existir, reduza a confiança da decisão e registre a limitação;
|
||||
não fabrique valores.
|
||||
|
||||
## Persistência do plano
|
||||
|
||||
O plano deve ser criado em `planos_de_edicao`, e cada ação em
|
||||
`acoes_do_plano`. A aplicação deve ser registrada em `aplicacoes_do_plano`.
|
||||
O JSON pode ser usado durante a revisão, mas o banco deve conservar a decisão
|
||||
que será executada.
|
||||
@@ -0,0 +1,78 @@
|
||||
# 01 — Leitura das evidências do banco
|
||||
|
||||
> **Escopo:** Como ler as evidências persistidas no banco, sem recalcular o que já foi medido.
|
||||
> **Quando:** Fase 1 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
O registro da edição e as tabelas relacionadas no banco são a entrada de todo o
|
||||
trabalho. Um JSON exportado pode ser usado como visão de trabalho, mas deve ser
|
||||
reconciliado com o `video_id` e a versão da análise antes de qualquer decisão.
|
||||
Leia em camadas, de cima para baixo, e só desça quando precisar.
|
||||
|
||||
## Camadas
|
||||
|
||||
| Camada | O que traz | Para quê |
|
||||
|---|---|---|
|
||||
| `analises_versao` | o que de fato rodou e qual versão está válida | **leia primeiro** — ver `09-analise-incompleta.md` |
|
||||
| `summary` | forma da peça, `peak_moments`, contagens | visão geral em poucos números |
|
||||
| `segmentos_de_transcricao` | cada fala com seus agregados | **onde você mais trabalha** |
|
||||
| `palavras_de_transcricao` | detalhe por palavra | achar o instante exato de um destaque |
|
||||
| `evidencias_visuais` | observações visuais por intervalo | apoiar a decisão quando disponível |
|
||||
| `edicoes_de_video.configuracao` | objetivo e regras do vídeo | calibrar a seleção editorial |
|
||||
|
||||
## Campos que decidem quase tudo
|
||||
|
||||
**`gap_before`** — silêncio antes da fala, em segundos. É o mapa estrutural
|
||||
da gravação: acima de ~3s (`take_boundary: true`) a câmera parou ou a
|
||||
tomada recomeçou. Num material real de 3min17s isso identificou 6
|
||||
fronteiras, todas exatamente onde a pessoa recomeçava o roteiro.
|
||||
|
||||
**`take_boundary`** — booleano derivado do `gap_before`. Use para agrupar
|
||||
tomadas.
|
||||
|
||||
**`emphasis`** (0–1) — índice combinado de energia, variação de tom,
|
||||
variação de ritmo, pausa anterior e duração. **É relativo ao material
|
||||
analisado**, nunca uma medida absoluta. Ver `02-enfase-e-reanalise.md`.
|
||||
|
||||
**`energy`** (0–1) — intensidade relativa ao trecho mais alto da gravação.
|
||||
|
||||
**`pitch_delta`** (0–1) — quanto o tom se afasta da média do falante.
|
||||
|
||||
**`peak_emphasis`** e **`avg_energy`** (por segmento) — permitem julgar uma
|
||||
frase inteira sem ler palavra por palavra. É por aqui que você avalia o
|
||||
arco narrativo.
|
||||
|
||||
**`energy_raw`** e **`pitch_hz`** — valores brutos, sem normalização. Não
|
||||
use para decidir; existem para permitir a reanálise da Fase 2.
|
||||
|
||||
## O que NÃO fazer
|
||||
|
||||
- **Não recalcule** energia, tom ou ênfase. O sistema mede melhor e de
|
||||
forma reprodutível.
|
||||
- **Não reestime tempos "no olho".** Use os timestamps do JSON.
|
||||
- **Não trate `emphasis` como valor absoluto.** Um 0,35 pode ser o pico de
|
||||
uma gravação e ruído em outra.
|
||||
|
||||
## O timestamp por palavra tem um viés conhecido
|
||||
|
||||
O início de cada palavra vem sistematicamente **adiantado em ~0,3-0,5s** em
|
||||
relação ao ataque real da fala — medido em material real com ffmpeg (`astats`),
|
||||
consistente em 6 pontos do mesmo vídeo. O fim da palavra não tem esse problema
|
||||
(erro de poucos centésimos). Causa: `word_timestamps` do faster-whisper deriva
|
||||
por atenção cruzada, sem alinhamento forçado — ver `05_EXPERIENCIAS.md`, entrada
|
||||
de 2026-08-19.
|
||||
|
||||
**Quando o pipeline já corrigiu isso:** se `layers.alignment` for `true`
|
||||
(transcript gerado com alinhamento forçado fonético via whisperx, implementado
|
||||
depois desse aviso), o viés foi removido na origem — **não aplique o offset
|
||||
manual** abaixo. O aviso vale só para transcripts antigos sem `layers.alignment`.
|
||||
|
||||
Isso não é "reestimar no olho" — é um bug de medição na fonte, não um
|
||||
julgamento seu. Na prática (somente sem `layers.alignment`):
|
||||
|
||||
- Ao posicionar um `zoom` cujo `start` precisa cair exatamente na palavra
|
||||
(não uma frase inteira), some **+0,3 a +0,4s** ao timestamp do JSON antes
|
||||
de decidir, ou confira com `ffmpeg -af astats` se a precisão importar
|
||||
para o frame.
|
||||
- **Não aplique essa correção a `gap_before` para decidir corte** — a régua
|
||||
de silêncio (`06-texto-corte-marcador.md`) já é conservadora o bastante
|
||||
para absorver esse erro; corrigir os dois ao mesmo tempo é redundante.
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
# 02 — Triagem: roteiro vs. conversa de bastidor
|
||||
|
||||
> **Escopo:** Separar o texto do roteiro da conversa de bastidor — tarefa de texto, nunca de limiar.
|
||||
> **Quando:** Fase 2 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
**Primeira coisa a fazer, antes de qualquer decisão de efeito.**
|
||||
|
||||
Material bruto de gravação quase nunca é uma tomada só. A pessoa lê o
|
||||
roteiro, erra, conversa com a equipe e recomeça.
|
||||
|
||||
## Por que isso é tarefa sua, e não do sistema
|
||||
|
||||
No áudio essa separação é **invisível** — e pior: o índice de ênfase
|
||||
*favorece* a conversa, que é mais solta e mais alta que o texto decorado.
|
||||
|
||||
Caso real: a fala mais enfática de um vídeo inteiro (energia **1,00**, o
|
||||
topo absoluto da gravação) era *"Amor, eu tô intacto!"*, dita para o marido
|
||||
fora de quadro. Três das sete palavras de maior ênfase do vídeo vinham
|
||||
dessa única frase de bastidor.
|
||||
|
||||
Nenhum limiar acústico separa isso. O **texto** separa sem erro.
|
||||
|
||||
> Atenção: isso também **não é diarização**. Num caso real, a pessoa da
|
||||
> equipe estava fora do microfone — a diarização a ouvia, mas o Whisper não
|
||||
> a transcrevia. As falas a descartar eram da **própria protagonista**:
|
||||
> mesma voz, contexto diferente. "Quem fala" e "isso é tomada válida" são
|
||||
> perguntas diferentes.
|
||||
|
||||
## Descartar — conversa com a equipe
|
||||
|
||||
Reconhece-se pelo **conteúdo**:
|
||||
|
||||
- **vocativo para alguém da sala** — *"Amor, eu tô intacto!"*
|
||||
- **pergunta operacional** — *"Posso começar da mastopexia?"*,
|
||||
*"E aí, continua?"*, *"Mas eu vou ter que falar tudo de novo?"*
|
||||
- **instrução técnica** — *"Só clica aí agora na tela."*, *"Aumenta."*
|
||||
- **comentário sobre a própria gravação** — *"Vou falar só a última frase,
|
||||
só um pouquinho, não pegou?"*
|
||||
|
||||
## Descartar — frases interrompidas
|
||||
|
||||
Texto que morre no meio, tipicamente em reticências ou emendando numa
|
||||
pergunta:
|
||||
|
||||
- *"E tudo isso associado à medida..."*
|
||||
- *"Aquela mama com um formato mais estruturado, com o colo que..."*
|
||||
- *"de pele..."*
|
||||
|
||||
## Sinais estruturais que ajudam
|
||||
|
||||
Use `take_boundary` para achar onde cada tomada recomeça. Num material
|
||||
real, as fronteiras (gaps de 3,6s a 19,8s) caíam exatamente nos pontos onde
|
||||
a médica reiniciava o roteiro — inclusive nas duas retomadas da frase de
|
||||
abertura.
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
# 03 — Escolha da melhor tomada
|
||||
|
||||
> **Escopo:** Qual tomada de cada frase sobrevive, e o que fazer em caso de empate.
|
||||
> **Quando:** Fase 3 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
A mesma frase costuma aparecer 2, 3, 4 vezes. Seu trabalho é ficar com
|
||||
**uma**.
|
||||
|
||||
## Como agrupar
|
||||
|
||||
1. Use `take_boundary` para localizar onde cada tomada recomeça.
|
||||
2. Agrupe as repetições **pelo texto**, não pelo tempo — a mesma frase
|
||||
reaparece em pontos distantes da gravação. Num caso real, a abertura
|
||||
*"Aquela mama com um formato mais estruturado"* apareceu aos 2,0s, 64,9s
|
||||
e 86,4s.
|
||||
|
||||
## Critérios, nesta ordem
|
||||
|
||||
### 1. Completa
|
||||
Não morre no meio, não emenda numa pergunta. Uma tomada incompleta está
|
||||
descartada por definição, mesmo que a dicção seja ótima.
|
||||
|
||||
### 2. Dicção limpa
|
||||
Sem tropeço, sem repetição de palavra, sem vício de linguagem. **Compare os
|
||||
textos lado a lado:**
|
||||
|
||||
| Tomada 1 | Tomada 3 | Escolha |
|
||||
|---|---|---|
|
||||
| *"isso é desejo de muitas mulheres"* | *"**aí** isso é desejo de muitas mulheres"* | Tomada 1 |
|
||||
|
||||
### 3. Formulação melhor
|
||||
Quando as duas estão limpas, prefira a mais direta — normalmente a última,
|
||||
porque é onde a pessoa já se ajustou:
|
||||
|
||||
| Antes | Depois | Escolha |
|
||||
|---|---|---|
|
||||
| *"a gente **faz a inserção de** próteses"* | *"a gente **insere** próteses"* | a segunda |
|
||||
| *"reestrutura a mama"* | *"reestrutura a **sua** mama"* | a segunda |
|
||||
|
||||
### 4. Entrega
|
||||
**Só então** desempate por `avg_energy` / `peak_emphasis`.
|
||||
|
||||
Quando duas tomadas têm texto **idêntico palavra por palavra**, aí a
|
||||
energia decide sozinha — é o único sinal disponível. Caso real: o fecho
|
||||
tinha duas tomadas iguais, energia **0,38** e **0,19**. A de 0,38 é a boa,
|
||||
e o texto sozinho jamais diria isso.
|
||||
|
||||
## Regra de ouro
|
||||
|
||||
A **última** tomada costuma ser a melhor — é onde a pessoa acertou. Mas
|
||||
**confirme lendo o texto**; nunca assuma.
|
||||
|
||||
## Quando estiver em dúvida
|
||||
|
||||
Não decida no escuro. Coloque um `marker` nas duas candidatas, explique a
|
||||
dúvida no `reason`, e deixe a escolha para o editor humano.
|
||||
|
||||
## Continuidade
|
||||
|
||||
Ao montar o corte final você pode misturar blocos de tomadas diferentes —
|
||||
abertura da tomada 1, corpo da tomada 3. Isso é normal. Mas **avise nas
|
||||
emendas**: coloque um `marker` em cada junção para o editor conferir se o
|
||||
enquadramento e a posição da pessoa combinam.
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
# 04 — Reanálise do material que sobrou
|
||||
|
||||
> **Escopo:** Renormalizar a ênfase sobre o que sobrou, antes de escolher zooms.
|
||||
> **Quando:** Fase 4 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
**Não escolha zooms com os números da análise bruta.**
|
||||
|
||||
## O problema
|
||||
|
||||
Ênfase e energia são **relativas ao conjunto analisado**. Energia é
|
||||
normalizada contra o momento mais alto da gravação; ênfase deriva dela.
|
||||
|
||||
Se esse momento mais alto foi cortado — uma piada, um grito, uma conversa
|
||||
de bastidor — tudo que sobrou continua pontuado contra uma referência que o
|
||||
espectador **nunca verá**. As notas do corte final ficam artificialmente
|
||||
comprimidas, e o ranking aponta para as palavras erradas.
|
||||
|
||||
Caso real: o pico do vídeo era *"Amor, eu tô intacto!"* (energia 1,00),
|
||||
descartado na triagem. Todo o material restante estava sendo medido contra
|
||||
ele.
|
||||
|
||||
## A solução
|
||||
|
||||
Depois de definir os cortes, renormalize sobre os sobreviventes. Solicite uma
|
||||
reanálise dos dados persistidos, passando a mídia e a lista de cortes que você
|
||||
já decidiu. Se essa operação não estiver disponível, recalcule somente a
|
||||
normalização necessária por um adaptador controlado e registre a nova versão
|
||||
em `analises_versao`:
|
||||
|
||||
```
|
||||
refinar_linha_de_voz(media_path, cortes=[{start, end}, ...], min_gap=8.0)
|
||||
```
|
||||
|
||||
Ela devolve, numa chamada só, a comparação bruto × sobreviventes, os picos
|
||||
re-ranqueados e os candidatos a zoom. É barata: renormaliza os números já
|
||||
medidos, sem reabrir o áudio.
|
||||
|
||||
Efeito medido no mesmo material:
|
||||
|
||||
| | Bruto | Só o que sobrou |
|
||||
|---|---|---|
|
||||
| Ênfase média | 0,179 | **0,197** |
|
||||
| *"Aquela"* | 0,39 | **0,42** |
|
||||
| *"mastopexia"* | 0,26 | **0,34** |
|
||||
| *"devolver"* | — | **0,35** |
|
||||
|
||||
*"mastopexia"* só virou candidata legítima depois da reanálise.
|
||||
|
||||
## As janelas que ela propõe
|
||||
|
||||
A seção **Zoom Candidates** da resposta já vem com três coisas resolvidas:
|
||||
|
||||
1. **Pega a palavra de conteúdo mais enfática de cada frase.** Artigos e
|
||||
conectivos são filtrados — um *"a"* falado alto continua sendo um artigo.
|
||||
Sem esse filtro, o ranking bruto apontava para "o", "a", "eu": picos de
|
||||
*entrega*, não de *sentido*.
|
||||
2. **Estende a janela até o fim da frase**, não do segmento (ver
|
||||
`05-zoom.md`).
|
||||
3. **Mantém distância mínima** entre zooms.
|
||||
|
||||
São **candidatos, não obrigações.** Corte a lista pelo ritmo
|
||||
(`07-ritmo.md`). Os tempos continuam na mídia original — vão para as ações
|
||||
persistidas no plano e, depois da aprovação, para o adaptador de aplicação do
|
||||
Premiere.
|
||||
|
||||
`max_zooms` limita a lista, mas prefira cortá-la você mesmo: o corte por
|
||||
ritmo é decisão editorial, não um teto numérico.
|
||||
|
||||
## Princípio geral
|
||||
|
||||
> "Qual o momento mais forte da **gravação**?" e "qual o momento mais forte
|
||||
> do **vídeo final**?" são perguntas diferentes sempre que a métrica for
|
||||
> relativa.
|
||||
|
||||
Toda métrica normalizada precisa ser recalculada quando o conjunto muda —
|
||||
senão ela responde a pergunta errada, silenciosamente.
|
||||
@@ -0,0 +1,84 @@
|
||||
# 05 — Zoom (punch-in)
|
||||
|
||||
> **Escopo:** Onde dar punch-in, qual janela e qual escala — e o que a escala significa além do zoom.
|
||||
> **Quando:** Fase 5 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
## Quando usar
|
||||
|
||||
No momento em que o argumento vira. Um pico acústico só merece zoom se for
|
||||
também um pico **de sentido**.
|
||||
|
||||
Palavra gritada sem peso narrativo não ganha nada — e isso inclui os picos
|
||||
que caem em artigos e conectivos, que são picos de entrega, não de conteúdo.
|
||||
|
||||
## A janela
|
||||
|
||||
**`start`** — na palavra de ênfase.
|
||||
|
||||
**`end`** — no **fim da frase**. A frase inteira, não o fim do segmento da
|
||||
transcrição.
|
||||
|
||||
O Whisper corta frases no meio, por respiração e não por gramática:
|
||||
|
||||
> *"Aquela mama com um formato mais estruturado, que valoriza o seu colo,
|
||||
> que dá aquele ar"* **|** *"de elegância, isso é desejo de muitas mulheres,
|
||||
> né?"*
|
||||
|
||||
Soltar o zoom no fim do primeiro segmento libera **no meio do pensamento** —
|
||||
é o que faz um punch-in parecer arbitrário. `suggest_zoom_windows` já
|
||||
estende até a pontuação final (`.` `!` `?` `…`), e nunca atravessa uma
|
||||
fronteira de tomada.
|
||||
|
||||
## A forma — o programa decide sozinho
|
||||
|
||||
Você escolhe `start` e `end`; a forma sai da posição da janela dentro do
|
||||
trecho:
|
||||
|
||||
| Situação | Comportamento | Por quê |
|
||||
|---|---|---|
|
||||
| Começa a **>0,5s** do início do trecho | entrada rápida (~0,25s) | o movimento chega junto com a palavra |
|
||||
| Começa a **≤0,5s** do início | **entra já ampliado, sem transição** | o corte já foi a transição; uma rampa ali lê como a imagem se acomodando |
|
||||
| Frase termina no meio do trecho | **saída seca**, 1 frame | volta ao enquadramento sem chamar atenção |
|
||||
| Frase termina a **≤1s** do corte | **não volta** — segura até o corte | o próximo trecho já abre no enquadramento dele; voltar antes é movimento desperdiçado |
|
||||
|
||||
Os limiares são diferentes de propósito: no fim o corte esconde um retorno
|
||||
inacabado, mas no início a rampa é visível desde o primeiro frame.
|
||||
|
||||
Para forçar manualmente, existem `start_at_peak` e `hold_at_end` — mas o
|
||||
automático acerta na quase totalidade dos casos.
|
||||
|
||||
## Escala
|
||||
|
||||
| Valor | Uso | Vira, na tela de revisão |
|
||||
|---|---|---|
|
||||
| 1,15 | sutil | ênfase **1 — Leve** |
|
||||
| 1,18 – 1,3 | padrão | ênfase **2 — Média** |
|
||||
| 1,5 | forte | ênfase **3 — Forte** |
|
||||
|
||||
Em vídeo institucional, fique na faixa baixa. Acima de 3,0 é rejeitado.
|
||||
|
||||
**A escala tem um segundo efeito, e ele é maior que o zoom.** A frase que
|
||||
recebe um zoom é marcada como **ênfase** na etapa 5, e frase de ênfase recebe
|
||||
**legenda dinâmica**; as demais ficam com legenda comum. Ou seja: escolher onde
|
||||
dar zoom é também escolher onde o texto ganha tratamento tipográfico.
|
||||
|
||||
Consequência prática: **não espalhe zoom "por segurança"**. Cada um promove uma
|
||||
frase a destaque em duas dimensões ao mesmo tempo. Na dúvida, deixe sem — o
|
||||
editor promove numa tecla, e despromover custa mais que promover.
|
||||
Detalhe: `10-revisao-humana.md`.
|
||||
|
||||
O zoom é **relativo ao enquadramento existente**: se o clipe já tem escala
|
||||
1,77 (material gravado de lado e reenquadrado), um zoom 1,18 anima de 1,77
|
||||
para 2,09 e preserva rotação e posição.
|
||||
|
||||
## Dois zooms no mesmo clipe
|
||||
|
||||
Depois do corte, dois picos que você escolheu podem cair no **mesmo**
|
||||
trecho sobrevivente (nenhum corte os separou em clipes distintos) — é
|
||||
comum quando a corrida limpa de uma tomada é longa. O sistema resolve isso
|
||||
sozinho, e a regra é a mesma que rege o resto: janelas **distantes**
|
||||
empilham (os dois zooms convivem, cada um voltando ao enquadramento real
|
||||
entre um e outro); janelas que **se sobrepõem** substituem (é o mesmo
|
||||
evento sendo reajustado, não dois). Você não precisa calcular isso na
|
||||
hora de decidir — só respeitar o `min_gap` de `07-ritmo.md`, que já
|
||||
garante que dois zooms escolhidos por você nunca se sobrepõem.
|
||||
@@ -0,0 +1,127 @@
|
||||
# 06 — Texto, corte e marcador
|
||||
|
||||
> **Escopo:** Texto na tela, o que cortar (inclui muletas e lacunas) e quando marcar.
|
||||
> **Quando:** Fase 6 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
## Texto
|
||||
|
||||
Para fixar um **conceito, número ou nome** que o espectador precisa reter.
|
||||
|
||||
- Use a palavra **dita**, não uma paráfrase.
|
||||
- Curta, em caixa alta. Até 120 caracteres (é truncado além disso).
|
||||
- Uma por frase, no máximo.
|
||||
|
||||
**Não legende a frase inteira.** Para isso existe
|
||||
`generate_dynamic_subtitles`, que é outra ferramenta e outro propósito.
|
||||
|
||||
Boas candidatas são as palavras-chave que sobram depois de filtrar as
|
||||
funcionais — num caso real: *mastopexia*, *flacidez*, *próteses*,
|
||||
*devolver*, *desejo*.
|
||||
|
||||
## Corte
|
||||
|
||||
Digressão, repetição, frase abandonada, conversa de bastidor, tomada pior —
|
||||
e mais duas coisas que **são** seu trabalho, ao contrário do que parece.
|
||||
|
||||
### Vícios de linguagem entram na sua lista
|
||||
|
||||
Não delegue para `remove_filler_words`. Você já está percorrendo palavra por
|
||||
palavra na triagem; marcar as muletas é uma linha a mais, sem custo. E você
|
||||
tem o que a lista fixa não tem: **contexto**.
|
||||
|
||||
Um *"tipo"* em *"tipo assim, sabe"* é muleta. Em *"esse tipo de cirurgia"*
|
||||
é a palavra principal. Um *"não não não"* pode ser gagueira ou ênfase. A
|
||||
lista fixa não distingue; você distingue.
|
||||
|
||||
### Lacunas longas entram na sua lista — curtas, nunca
|
||||
|
||||
**O tamanho da lacuna muda o que ela é.** A régua está medida em material
|
||||
real (`pause_weight()` em `emphasis.py`, `TAKE_BOUNDARY_GAP` em
|
||||
nas regras de análise de voz do projeto):
|
||||
|
||||
| `pause_before` | O que é | O que fazer |
|
||||
|---|---|---|
|
||||
| até ~1,5s | o falante montando a frase — **isso É a ênfase** | **nunca cortar** |
|
||||
| 1,5–3s | zona cinza | julgue pela frase |
|
||||
| acima de 3s | troca de tomada, ar morto, outra pessoa falando | **cortar** |
|
||||
|
||||
Cortar a pausa curta é o erro grave: ela é uma das cinco entradas do índice
|
||||
de ênfase, então você estaria apagando justamente a batida que faz a palavra
|
||||
seguinte pontuar alto. Uma frase fluida não se aperta.
|
||||
|
||||
Acima de 3s a pausa deixa de contar como ênfase por construção — medido em
|
||||
material real, lacunas de 6–9s rankeavam como os momentos mais enfáticos da
|
||||
gravação só porque a escala saturava.
|
||||
|
||||
### Nunca corte rente à palavra — deixe uma folga
|
||||
|
||||
Um `cut` cujo `start`/`end` cai exatamente no timestamp da palavra (fim da
|
||||
última palavra mantida = início do corte) produz um corte seco: a palavra é
|
||||
engolida antes de terminar de soar, e a fala seguinte começa sem nenhum ar.
|
||||
Isso é diferente de cortar a pausa curta (que seria apagar a própria ênfase,
|
||||
proibido acima) — aqui a pausa **já existe** entre o fim de um bloco mantido
|
||||
e o início do próximo, e o corte está comendo justamente essa margem.
|
||||
|
||||
Ao escrever a borda de um `cut` que encosta em fala mantida (não em silêncio
|
||||
puro), recue **~0,15–0,25s** para dentro do próprio corte, nos dois lados:
|
||||
|
||||
- o `start` do corte fica ~0,2s **depois** do fim real da última palavra
|
||||
mantida;
|
||||
- o `end` do corte fica ~0,2s **antes** do início real da próxima palavra
|
||||
mantida.
|
||||
|
||||
Caso real (projeto Mastopexia): um corte escrito rente (`10.77 → 95.50`,
|
||||
exatamente nos timestamps de palavra) soava abrupto nas duas emendas.
|
||||
Recuado para `10.97 → 95.30`, cada lado ganhou ~0,2s de respiro sem alterar
|
||||
o que é dito — e não empurra o próximo zoom/marcador contra a borda do corte
|
||||
(ver `05-zoom.md` sobre janelas encostadas em corte).
|
||||
|
||||
Isso vale também para o **início e o fim do vídeo**: ar morto antes da
|
||||
primeira palavra e depois da última também leva `cut`, com a mesma folga —
|
||||
não é "silêncio dentro da fala" (isso é `remove_media_silence`), é o mesmo
|
||||
corte de tomada/bastidor que você já está decidindo.
|
||||
|
||||
### O que continua NÃO sendo seu trabalho
|
||||
|
||||
| Tarefa | Ferramenta | Por quê |
|
||||
|---|---|---|
|
||||
| Apertar o ar **entre** palavras (sem fala, com ou sem som) | `remove_speech_gaps` | Lê `words[].start/end` da transcrição — sabe onde não tem fala mesmo quando tem som (respiração, ruído) |
|
||||
| Apertar o ar **dentro** da fala | `remove_media_silence` | Lê o áudio real com ffmpeg; só cobre silêncio técnico (dB), que a transcrição não enxerga |
|
||||
|
||||
E cuidado: **ausência de fala não é ausência de som**, e nem sempre é
|
||||
descartável. Respiração, riso, suspiro, a reação depois da frase — nada
|
||||
disso vira palavra, então aparece como lacuna, e às vezes é o melhor frame
|
||||
do vídeo. `remove_speech_gaps` corta **toda** lacuna acima do `min_gap`
|
||||
(0,6s por padrão) sem julgar o que tem nela — é automação de "sem fala",
|
||||
não de "sem conteúdo que vale manter". Se uma reação específica precisa
|
||||
sobreviver, marque-a como `cut` de duração zero antes (para virar um limite
|
||||
de segmento) ou rode com `min_gap` maior nesse trecho; não é a ferramenta
|
||||
que decide o que é bom frame.
|
||||
|
||||
Tanto `remove_speech_gaps` quanto `remove_media_silence` rodam **depois** da
|
||||
aplicação do plano, como acabamento sobre o material que sobrou —
|
||||
`remove_speech_gaps` primeiro (cobre mais, é o corte "grosso" por fala),
|
||||
`remove_media_silence` depois (aperta o que ainda restar dentro da fala).
|
||||
|
||||
**Antes de rodar `remove_media_silence` sobre o corte final, sempre rode a
|
||||
detecção primeiro** (sem aplicar) e leia os spans um a um contra a régua
|
||||
acima. O detector corta por limiar de dB — ele não sabe distinguir "batida
|
||||
de 0,8s entre duas frases", que a régua protege, de "ar morto de emenda",
|
||||
que deveria ser apertado. Aplicar direto, sem essa checagem, é o mesmo erro
|
||||
de cortar pausa curta, só que por outra ferramenta.
|
||||
|
||||
## Marcador
|
||||
|
||||
Quando você quer **sinalizar para o editor humano decidir**, em vez de
|
||||
decidir por ele.
|
||||
|
||||
Use em:
|
||||
|
||||
- **Emendas entre tomadas** — sempre. O editor precisa conferir se o
|
||||
enquadramento e a posição da pessoa combinam na junção.
|
||||
- **Dúvida entre duas tomadas** — marque as duas, explique no `reason`.
|
||||
- **Momentos que talvez mereçam efeito** mas que você não tem confiança
|
||||
para decidir.
|
||||
|
||||
Marcador é um **ponto**, não um trecho: sobrevive mesmo encostado na borda
|
||||
de um corte, o que é justamente o caso das emendas.
|
||||
@@ -0,0 +1,40 @@
|
||||
# 07 — Ritmo
|
||||
|
||||
> **Escopo:** Quantos efeitos cabem: os tetos e como escolher o que fica.
|
||||
> **Quando:** Fase 7 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
**O erro mais comum é efeito demais.** Cansa mais que efeito de menos, e
|
||||
denuncia edição automática.
|
||||
|
||||
## Limites
|
||||
|
||||
| Regra | Valor |
|
||||
|---|---|
|
||||
| Distância mínima entre dois zooms | **8–10 segundos** |
|
||||
| Zooms por minuto de vídeo | **2 a 4** (teto) |
|
||||
| Zoom + texto no mesmo instante | só com motivo claro |
|
||||
|
||||
Se dois picos estiverem colados, **escolha o mais forte e abra mão do
|
||||
outro**. Não tente encaixar os dois.
|
||||
|
||||
## Candidatos ≠ obrigações
|
||||
|
||||
`suggest_zoom_windows` devolve uma lista de candidatos. Normalmente você usa
|
||||
uma **fração** dela.
|
||||
|
||||
Caso real: num corte de 47,6s a ferramenta sugeriu **5** janelas. O certo
|
||||
foram **3** — 5 violaria o teto de 2–4 por minuto. Ficaram a abertura, o
|
||||
termo central e o fecho; as duas descartadas eram frases de apoio.
|
||||
|
||||
O mesmo vale para `peak_moments` no `summary`: é lista de candidatos.
|
||||
|
||||
## Como escolher quais manter
|
||||
|
||||
Quando precisar cortar a lista, priorize por **função narrativa**, não por
|
||||
nota:
|
||||
|
||||
1. **A abertura** — prende o espectador.
|
||||
2. **O conceito central** — o termo que o vídeo existe para explicar.
|
||||
3. **O fecho** — a frase que fica.
|
||||
|
||||
Só depois disso, as frases de apoio, por ordem de ênfase.
|
||||
@@ -0,0 +1,89 @@
|
||||
# 08 — Formato de saída
|
||||
|
||||
> **Escopo:** O JSON de entrega: estrutura, regras e como o programa trata erros.
|
||||
> **Quando:** Fase 8 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
O produto intermediário do seu trabalho é **este JSON**. Ele serve para
|
||||
revisão e transporte entre componentes; a decisão persistida deve ser salva
|
||||
em `planos_de_edicao` e `acoes_do_plano`. Você nunca escreve XML.
|
||||
|
||||
## Estrutura
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "0E6A8290.mp4",
|
||||
"actions": [
|
||||
{"kind": "cut", "start": 21.9, "end": 127.6,
|
||||
"reason": "tomadas descartadas, frases interrompidas e conversa com a equipe"},
|
||||
{"kind": "zoom", "start": 2.0, "end": 10.7,
|
||||
"params": {"scale": 1.15}, "reason": "abertura: \"Aquela mama\" (ênfase 0.42)"},
|
||||
{"kind": "text", "start": 127.7, "end": 129.0,
|
||||
"params": {"content": "MASTOPEXIA"}, "reason": "fixa o termo central"},
|
||||
{"kind": "marker", "start": 21.85, "end": 22.0,
|
||||
"reason": "EMENDA 1 — conferir junção entre tomadas"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Regras
|
||||
|
||||
### 1. Tempos em segundos da mídia ORIGINAL
|
||||
Exatamente como aparecem nos intervalos persistidos da transcrição no banco.
|
||||
|
||||
**Nunca compense para "depois do corte".** O programa faz esse deslocamento
|
||||
sozinho: ele resolve os cortes primeiro e reposiciona todo o resto. Se você
|
||||
compensar por conta própria, **todo destaque cai no frame errado** — e o
|
||||
erro é silencioso.
|
||||
|
||||
### 2. `end` sempre maior que `start`
|
||||
Ambos ≥ 0. Um `end <= start` é rejeitado.
|
||||
|
||||
### 3. Tipos
|
||||
`cut` · `zoom` · `text` · `marker`
|
||||
|
||||
### 4. Parâmetros por tipo
|
||||
|
||||
| Tipo | `params` |
|
||||
|---|---|
|
||||
| `cut` | nenhum |
|
||||
| `zoom` | `scale` entre 1.0 e 3.0 (padrão 1.3 se omitido) |
|
||||
| `text` | `content` **obrigatório**, até 120 caracteres |
|
||||
| `marker` | opcional: `content` vira o nome do marcador |
|
||||
|
||||
### 5. `reason` — sempre preencha
|
||||
É o que o usuário lê para revisar sua decisão, e o que te obriga a **ter**
|
||||
uma. Um `reason` vazio é sinal de decisão sem critério.
|
||||
|
||||
Inclua o dado que embasou: *"abertura: 'Aquela mama' (ênfase 0.42)"* é útil;
|
||||
*"zoom"* não é.
|
||||
|
||||
Não é campo de log: o texto é **exibido na tela de revisão**, ao lado da frase,
|
||||
e é o que o editor lê antes de manter ou desfazer o que você decidiu.
|
||||
|
||||
### 6. Corte: alinhe à intenção
|
||||
A tela lê cada `cut` contra as frases da transcrição:
|
||||
|
||||
- cobre **≥ 60%** de uma frase → aquela frase é **removida**;
|
||||
- toca só o **começo** ou só o **fim** → vira **trim** (a frase fica, aparada).
|
||||
|
||||
Então corte a frase **inteira** quando quiser removê-la, e corte **só da borda
|
||||
até a palavra** quando quiser aparar uma hesitação. Um corte de meia frase é
|
||||
ambíguo — passa de 60% e apaga a linha toda. Detalhe: `10-revisao-humana.md`.
|
||||
|
||||
## Persistência
|
||||
|
||||
Depois de validar o JSON, crie um registro em `planos_de_edicao` ligado ao
|
||||
`video_id` e à edição de origem. Grave cada ação em `acoes_do_plano` mantendo a
|
||||
ordem e os motivos. Não considere o plano entregue até a gravação ser
|
||||
confirmada.
|
||||
|
||||
## Como o programa trata erros
|
||||
|
||||
- **Ação inválida** → rejeitada e reportada **individualmente**. Uma linha
|
||||
malformada nunca derruba as outras.
|
||||
- **Ação apontando para material cortado** → descartada e reportada, nunca
|
||||
deslizada para o conteúdo vizinho.
|
||||
- **Ação fora da mídia** → reportada como não colocada.
|
||||
|
||||
Você recebe o relatório dos três casos. **Repasse ao usuário** — nunca
|
||||
relate só os acertos.
|
||||
@@ -0,0 +1,53 @@
|
||||
# 09 — Quando a análise veio incompleta
|
||||
|
||||
> **Escopo:** O que fazer quando uma camada da análise não rodou.
|
||||
> **Quando:** Fase 0 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
O registro correspondente em `analises_versao` e os campos disponíveis nas
|
||||
tabelas de análise dizem **o que de fato rodou**. Leia isso antes de qualquer
|
||||
outra coisa. Se houver um JSON exportado com `layers`, use-o apenas como
|
||||
informação auxiliar e confira sua versão contra o banco.
|
||||
|
||||
```json
|
||||
"layers": {"transcript": true, "acoustics": false, "speakers": false}
|
||||
```
|
||||
|
||||
## Por que esse bloco existe
|
||||
|
||||
Fala monótona e acústica que não carregou deixam **os mesmos zeros** nos
|
||||
dados. Sem o `layers`, é impossível distinguir "esta pessoa fala de forma
|
||||
uniforme" de "a análise acústica falhou".
|
||||
|
||||
## Os casos
|
||||
|
||||
### `acoustics: false`
|
||||
Todos os valores acústicos são 0. **Você não tem ênfase real.**
|
||||
|
||||
- Decida só pelo texto.
|
||||
- **Avise o usuário** explicitamente.
|
||||
- Prefira `marker` a `zoom` — sinalize em vez de decidir.
|
||||
|
||||
Causa comum: o componente librosa não está instalado, ou o ffmpeg não
|
||||
conseguiu extrair o áudio do container.
|
||||
|
||||
### `speakers: false` num vídeo com várias pessoas
|
||||
A diarização não rodou — falta o token do HuggingFace (aba Modelos do app).
|
||||
|
||||
- Avise antes de tratar tudo como uma voz só.
|
||||
- Lembre que isso **não impede** a triagem roteiro/conversa, que é feita
|
||||
pelo texto (ver `02-triagem-roteiro-vs-conversa.md`).
|
||||
|
||||
### `peak_count: 0`
|
||||
Nada cruzou o piso de ênfase. Duas causas possíveis:
|
||||
|
||||
1. A fala é uniforme mesmo — material sem picos.
|
||||
2. O limiar está alto para esse material.
|
||||
|
||||
Sugira ajustar em **Análise de Voz** no app. **Não force destaques
|
||||
inexistentes** só para entregar alguma coisa.
|
||||
|
||||
## Regra geral
|
||||
|
||||
Não finja precisão que você não tem. Uma edição entregue com a ressalva
|
||||
certa é útil; uma entregue como se estivesse completa, quando metade dos
|
||||
dados faltou, custa a confiança do usuário no sistema inteiro.
|
||||
@@ -0,0 +1,122 @@
|
||||
# 10 — A revisão humana: o que acontece com o seu JSON
|
||||
|
||||
> **Escopo:** O que o app faz com o seu JSON na etapa 5 — muda como escrever as ações.
|
||||
> **Quando:** ler antes da Fase 5 — ver a ordem de trabalho em `../SKILL.md`.
|
||||
|
||||
> Leia antes de decidir cortes e zooms. Muda **como** escrever as ações, não
|
||||
> apenas quais.
|
||||
|
||||
Seu JSON não vai direto para a timeline. Ele é salvo como plano de revisão e
|
||||
abre no fluxo de revisão humana do painel, na **etapa 5 do Assistente**, uma
|
||||
tela onde o editor vê cada frase do roteiro com a sua
|
||||
decisão já aplicada e lapida antes de gerar.
|
||||
|
||||
Isso tem duas consequências práticas:
|
||||
|
||||
1. **Suas decisões são lidas por uma pessoa, frase a frase.** Uma decisão sem
|
||||
motivo explícito parece arbitrária — e será desfeita.
|
||||
2. **A tela traduz suas ações para o vocabulário dela.** Se você não escrever
|
||||
as ações do jeito que essa tradução espera, a intenção se perde no caminho.
|
||||
|
||||
---
|
||||
|
||||
## Como cada ação sua é lida
|
||||
|
||||
O app quebra a gravação em **frases** (os segmentos do voice timeline) e
|
||||
projeta suas ações sobre elas.
|
||||
|
||||
### `cut`
|
||||
|
||||
| O corte cobre… | Vira | Na tela |
|
||||
|---|---|---|
|
||||
| **≥ 60%** da frase | frase **desativada** | apagada, riscada, reativável num clique |
|
||||
| só o **começo** ou só o **fim** | **trim** da frase | a frase fica, aparada nas pontas |
|
||||
| um pedaço no **meio** | nada em si | só conta para a regra dos 60% |
|
||||
|
||||
O trim é **encaixado na fronteira de palavra** mais próxima. Você não precisa
|
||||
acertar o frame: mire na palavra onde a frase deve começar ou terminar.
|
||||
|
||||
**O que isso pede de você:** decida se está removendo *a linha* ou *aparando*
|
||||
uma ponta, e escreva o corte de acordo.
|
||||
|
||||
- Removendo a linha → corte a frase inteira, de ponta a ponta.
|
||||
- Aparando um falso começo → corte só da borda até a palavra onde a fala
|
||||
engata. Um corte que cobre meia frase é ambíguo: passa de 60% e apaga a linha
|
||||
toda, quando você só queria tirar a hesitação.
|
||||
|
||||
### `zoom` e `text`
|
||||
|
||||
Qualquer `zoom` ou `text` que toque uma frase marca aquela frase como
|
||||
**ênfase** — e ênfase, nesta tela, significa **duas coisas**:
|
||||
|
||||
> **A frase de ênfase recebe zoom E legenda dinâmica. As demais recebem
|
||||
> legenda comum.**
|
||||
|
||||
O nível vem da sua `scale`:
|
||||
|
||||
| `scale` | Nível na tela | |
|
||||
|---|---|---|
|
||||
| 1,15 | 1 — Leve | |
|
||||
| 1,3 | 2 — Média | |
|
||||
| 1,5 | 3 — Forte | |
|
||||
| omitida, ou uma ação `text` | 2 — Média | padrão |
|
||||
|
||||
Sem nenhuma ação sua, a tela deriva o nível do `peak_emphasis` da frase
|
||||
(< 0,25 → sem ênfase; < 0,45 → leve; < 0,65 → média; acima → forte). **A sua
|
||||
decisão sempre ganha da derivação automática.**
|
||||
|
||||
**O que isso pede de você:** escolher a escala com intenção. Ela não é só
|
||||
"quanto amplia" — é o peso que aquela frase terá no vídeo inteiro, incluindo o
|
||||
tratamento da legenda. Um zoom leve numa frase de apoio não é neutro: promove
|
||||
aquela frase a destaque tipográfico também.
|
||||
|
||||
### `marker`
|
||||
|
||||
Não altera a frase. Continua sendo o seu recado para o editor conferir uma
|
||||
emenda — e é a ferramenta certa quando você está em dúvida (ver
|
||||
`03-escolha-da-melhor-tomada.md`).
|
||||
|
||||
---
|
||||
|
||||
## `reason` aparece na tela
|
||||
|
||||
Não é campo de log. O texto que você escreve em `reason` é exibido para o
|
||||
editor ao lado da frase selecionada, e é o que ele lê antes de manter ou
|
||||
desfazer a sua decisão.
|
||||
|
||||
Escreva para quem está com pressa e vai decidir na hora:
|
||||
|
||||
- **Bom:** `"fecho, pico em 'devolver' (ênfase 0.34) — escala mais forte por ser o fechamento da peça"`
|
||||
- **Ruim:** `"zoom"` · `"corte necessário"` · `"melhor tomada"`
|
||||
|
||||
A regra prática: se o `reason` não contém **o dado** que embasou (a palavra, o
|
||||
número, a comparação entre tomadas), você provavelmente não tinha critério —
|
||||
tinha impressão.
|
||||
|
||||
---
|
||||
|
||||
## O que a tela NÃO desfaz por você
|
||||
|
||||
- **Tempo errado continua errado.** A tela mostra suas ações no eixo da mídia
|
||||
original; se você compensou para pós-corte, tudo aparece no lugar errado e o
|
||||
editor não tem como adivinhar o que você quis dizer.
|
||||
- **Excesso de zoom continua excesso.** A tela não impõe o teto de 2–4 por
|
||||
minuto (`07-ritmo.md`) — ela mostra o que você mandou. Efeito demais chega
|
||||
ao editor como trabalho de limpeza.
|
||||
- **Frase promovida a ênfase sem querer.** Como zoom e legenda dinâmica andam
|
||||
juntos, espalhar zooms "de segurança" enche o vídeo de legenda dinâmica. Na
|
||||
dúvida, deixe sem — o editor promove; é mais barato que despromover.
|
||||
|
||||
---
|
||||
|
||||
## Depois da revisão
|
||||
|
||||
O editor pode, na tela: mudar o nível de ênfase (0–3), desativar ou reativar
|
||||
frases, corrigir o texto, aparar as pontas por palavra, reclassificar entre
|
||||
roteiro e bastidor e acrescentar zooms manuais em trechos arbitrários.
|
||||
|
||||
O resultado vira um `_phrase_review.json` e o `_phrase_actions.json` derivado —
|
||||
e é esse que a geração usa. **Seu JSON é o ponto de partida da conversa, não a
|
||||
palavra final.** Trabalhe para ser um bom ponto de partida: decisões
|
||||
defensáveis, motivos legíveis e nenhuma escolha que o editor precise desfazer
|
||||
antes de começar.
|
||||
Reference in New Issue
Block a user