feat: aprimorada a edição por voz com validação de frases, margens
- aprimorada a edição por voz com validação de frases, margens seguras e backup único antes da timeline. - adicionada consulta expansível dos detalhes de cada trilha diretamente do banco Resumo: - 23 arquivos alterados - 5 novos - 18 modificados - 0 removidos 18 files changed, 321 insertions(+), 216 deletions(-) Arquivos: - .gitignore - .jhonny/analises.db - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - code/engine/analisar_trilhas.py - code/engine/aplicar_plano_de_edicao.py - code/engine/editor/__init__.py - code/engine/editor/backup_de_sequencia.py - code/engine/persistencia/__init__.py - code/engine/testes/test_aplicar_plano_de_edicao.py - code/plugins/premiere-pro/skills/edit-video-by-voice/SKILL.md - code/plugins/premiere-pro/skills/editar-por-voz/SKILL.md - code/plugins/premiere-pro/skills/editar-por-voz/criterios/05-zoom.md - code/plugins/premiere-pro/skills/editar-por-voz/criterios/06-texto-corte-marcador.md - code/plugins/premiere-pro/skills/editar-por-voz/criterios/08-formato-de-saida.md - code/plugins/premiere-pro/skills/editar-por-voz/criterios/10-revisao-humana.md - code/plugins/premiere-pro/skills/transcript-to-edit-actions/SKILL.md - code/engine/consultar_detalhes_de_trilha.py - code/engine/editor/validacao_semantica.py - code/engine/persistencia/leitura_semantica_do_plano.py - code/engine/testes/test_leitura_semantica_do_plano.py - code/engine/testes/test_validador_semantico_de_plano.py
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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.
|
||||
description: Skill canônica para editar por voz dentro do projeto Jhonny e do painel MCP for Adobe Premiere Pro, usando a transcrição e a configuração editorial do SQLite. Use neste projeto para escolher tomadas, limpar repetições ou montar o corte automático. Não use as skills portáteis edit-video-by-voice ou transcript-to-edit-actions neste fluxo persistido.
|
||||
---
|
||||
|
||||
# Editar por voz
|
||||
@@ -78,15 +78,22 @@ ou evidência obrigatória estiver ausente, pare e relate exatamente o que falta
|
||||
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
|
||||
7. Antes de salvar, reconstrua o texto que sobreviverá a cada emenda. Um
|
||||
segmento do Whisper não equivale a uma frase: una segmentos adjacentes
|
||||
sempre que a gramática continuar. Exija frase completa e ao menos 0,30s de
|
||||
respiro junto a cada palavra mantida. Se uma borda interceptar palavra,
|
||||
deixar a fala sem fechamento ou retomar em continuação minúscula, corrija
|
||||
o plano; nunca delegue esse defeito à aplicação.
|
||||
8. 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
|
||||
9. Faça preview do texto sobrevivente, lendo em sequência a última frase antes
|
||||
e a primeira frase depois de cada corte. Apresente decisões e incertezas
|
||||
para revisão humana. Uma alteração no plano exige novo preview.
|
||||
10. 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
|
||||
11. 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
|
||||
@@ -126,6 +133,8 @@ Leia, conforme a etapa, [criterios/02-triagem-roteiro-vs-conversa.md](criterios/
|
||||
- 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.
|
||||
- Nunca use o começo ou o fim de um segmento de transcrição como borda só
|
||||
porque o timestamp já existe. A unidade editorial é a frase completa.
|
||||
- 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.
|
||||
|
||||
@@ -49,23 +49,17 @@ 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** |
|
||||
| Valor | Uso |
|
||||
|---|---|
|
||||
| 1,15 | sutil |
|
||||
| 1,18 – 1,3 | padrão |
|
||||
| 1,5 | 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`.
|
||||
Não espalhe zoom "por segurança". Cada ação é aplicada diretamente ao clipe e
|
||||
excesso de escala vira trabalho de correção manual. Zoom não ativa legenda nem
|
||||
muda o texto por efeito colateral no fluxo atual.
|
||||
|
||||
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
|
||||
|
||||
+31
-3
@@ -63,11 +63,12 @@ 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:
|
||||
puro), recue **no mínimo 0,30s** para dentro do próprio corte, nos dois lados.
|
||||
Essa margem cobre a imprecisão observada entre transcrição e frame de corte:
|
||||
|
||||
- o `start` do corte fica ~0,2s **depois** do fim real da última palavra
|
||||
- o `start` do corte fica ≥0,30s **depois** do fim real da última palavra
|
||||
mantida;
|
||||
- o `end` do corte fica ~0,2s **antes** do início real da próxima palavra
|
||||
- o `end` do corte fica ≥0,30s **antes** do início real da próxima palavra
|
||||
mantida.
|
||||
|
||||
Caso real (projeto Mastopexia): um corte escrito rente (`10.77 → 95.50`,
|
||||
@@ -81,6 +82,33 @@ 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.
|
||||
|
||||
### Segmento de transcrição não é frase
|
||||
|
||||
O Whisper pode terminar um segmento no meio de uma oração e continuar o
|
||||
segmento seguinte em minúscula. Portanto, **nunca** transforme automaticamente
|
||||
`segment.end` ou `next_segment.start` em borda de corte.
|
||||
|
||||
Antes de aceitar cada emenda, leia em voz contínua:
|
||||
|
||||
1. a última oração que ficará antes do `start`;
|
||||
2. a primeira oração que ficará depois do `end`;
|
||||
3. a junção formada por essas duas partes.
|
||||
|
||||
Bloqueie o plano se a última palavra mantida não fechar a oração, se a próxima
|
||||
fala começar como continuação gramatical, ou se qualquer borda cair dentro de
|
||||
uma palavra. Caso real bloqueante: remover até `934.65s` faria a fala sobreviver
|
||||
em `"conseguir achar um profissional..."`, continuação da frase anterior; cortar
|
||||
em `962.60s`, exatamente após `"segurança."`, pode produzir
|
||||
`"trazer uma seguran..."` por falta de cauda acústica.
|
||||
|
||||
Checklist obrigatório antes de salvar qualquer plano com `cut`:
|
||||
|
||||
- zero palavras interceptadas;
|
||||
- zero trechos mantidos começando no meio de frase;
|
||||
- zero frases mantidas sem fechamento antes do corte;
|
||||
- ao menos 0,30s de margem junto às palavras mantidas;
|
||||
- leitura do texto sobrevivente completa, na ordem final.
|
||||
|
||||
### O que continua NÃO sendo seu trabalho
|
||||
|
||||
| Tarefa | Ferramenta | Por quê |
|
||||
|
||||
@@ -57,18 +57,18 @@ 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.
|
||||
Não é campo de log: o texto permanece no JSON e no histórico persistido para
|
||||
o editor conferir por que a ação foi proposta.
|
||||
|
||||
### 6. Corte: alinhe à intenção
|
||||
A tela lê cada `cut` contra as frases da transcrição:
|
||||
### 6. Corte: preserve a integridade da fala
|
||||
|
||||
- cobre **≥ 60%** de uma frase → aquela frase é **removida**;
|
||||
- toca só o **começo** ou só o **fim** → vira **trim** (a frase fica, aparada).
|
||||
O aplicador executa literalmente o intervalo informado: ele não converte o
|
||||
corte em decisão por frase nem encaixa a borda na palavra mais próxima.
|
||||
|
||||
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`.
|
||||
Portanto, reconstrua o texto sobrevivente, preserve frases completas e deixe
|
||||
ao menos 0,30s de respiro junto às palavras mantidas. A engine bloqueia borda
|
||||
dentro de palavra, continuação gramatical e margem insuficiente. Detalhes em
|
||||
`06-texto-corte-marcador.md` e `10-revisao-humana.md`.
|
||||
|
||||
## Persistência
|
||||
|
||||
@@ -79,8 +79,10 @@ confirmada.
|
||||
|
||||
## Como o programa trata erros
|
||||
|
||||
- **Ação inválida** → rejeitada e reportada **individualmente**. Uma linha
|
||||
malformada nunca derruba as outras.
|
||||
- **Plano ou ação inválida** → o plano inteiro é bloqueado antes de alterar a
|
||||
timeline.
|
||||
- **Borda de corte semanticamente insegura** → o plano inteiro é bloqueado
|
||||
antes da conexão com o Premiere e antes do backup.
|
||||
- **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.
|
||||
|
||||
@@ -1,122 +1,45 @@
|
||||
# 10 — A revisão humana: o que acontece com o seu JSON
|
||||
# 10 — Revisão humana no fluxo atual
|
||||
|
||||
> **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`.
|
||||
> **Escopo:** O que o painel realmente permite revisar antes da aplicação.
|
||||
> **Quando:** ler antes de gerar e aprovar o plano.
|
||||
|
||||
> Leia antes de decidir cortes e zooms. Muda **como** escrever as ações, não
|
||||
> apenas quais.
|
||||
O painel atual exibe o JSON do plano e o aplica pela engine Python depois da
|
||||
confirmação. Ele **não possui ainda** uma tela frase a frase, não encaixa trims
|
||||
automaticamente em palavras e não gera `_phrase_review.json`. Por isso, não
|
||||
presuma que uma etapa posterior corrigirá bordas editoriais imprecisas.
|
||||
|
||||
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.
|
||||
## Preview obrigatório
|
||||
|
||||
Isso tem duas consequências práticas:
|
||||
Antes de pedir aprovação, apresente para cada corte:
|
||||
|
||||
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.
|
||||
- intervalo removido e motivo;
|
||||
- última frase completa que ficará antes;
|
||||
- primeira frase completa que ficará depois;
|
||||
- texto da emenda resultante;
|
||||
- margem acústica em cada lado;
|
||||
- qualquer incerteza que exija escuta humana.
|
||||
|
||||
---
|
||||
O editor deve aprovar o conteúdo sobrevivente, não apenas a quantidade de
|
||||
ações. Se o preview mostrar palavra truncada, oração incompleta ou continuação
|
||||
sem contexto, o plano volta para edição e recebe novos limites.
|
||||
|
||||
## Como cada ação sua é lida
|
||||
## Defesa automática
|
||||
|
||||
O app quebra a gravação em **frases** (os segmentos do voice timeline) e
|
||||
projeta suas ações sobre elas.
|
||||
Ao clicar em **Aplicar plano na timeline**, a engine revalida os cortes antes
|
||||
de se conectar ao Premiere e antes de criar o backup. A aplicação é bloqueada
|
||||
quando encontra:
|
||||
|
||||
### `cut`
|
||||
- uma borda dentro de palavra;
|
||||
- menos de 0,30s entre a borda e a palavra mantida;
|
||||
- fala mantida interrompida antes do corte;
|
||||
- retomada no meio de frase depois do corte.
|
||||
|
||||
| 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% |
|
||||
Essa validação é uma rede de segurança, não substitui o preview. Depois que o
|
||||
plano passa, a engine cria uma única cópia de segurança, aplica as ações e
|
||||
registra o resultado. O painel não cria uma segunda cópia.
|
||||
|
||||
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.
|
||||
## `reason` continua obrigatório
|
||||
|
||||
**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.
|
||||
Escreva um motivo curto e verificável, com a fala ou comparação que sustentou
|
||||
a decisão. Evite motivos genéricos como `"corte necessário"`: eles não ajudam o
|
||||
editor a conferir o plano nem permitem melhorar os critérios depois.
|
||||
|
||||
Reference in New Issue
Block a user