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:
João Henrique
2026-09-10 14:38:42 -04:00
parent b038d9b2e4
commit 9edde2df37
23 changed files with 873 additions and 216 deletions
+56 -6
View File
@@ -33,8 +33,12 @@ from engine.editor import (
AplicadorDePlanoDeEdicao,
BackupDaSequencia,
EscritaNoEditor,
ErroDePlanoInvalido,
LeitorDePlanoDeEdicao,
MapeadorDeTempoDeOrigemParaTimeline,
PlanoDeEdicao,
TipoDeAcao,
ValidadorSemanticoDePlano,
)
from engine.integracoes.premiere.cliente_mcp import ClienteMCPPorStdio
from engine.integracoes.premiere.cliente_mcp_com_pausa import ClienteMCPComPausa
@@ -48,6 +52,33 @@ CAMINHO_DO_SERVIDOR_MCP = CAMINHO_DO_CODIGO / "dist" / "index.js"
CAMINHO_DO_BANCO = CAMINHO_DO_CODIGO.parent / ".jhonny" / "analises.db"
def _validar_integridade_semantica(
plano: PlanoDeEdicao,
plano_id: int | None,
caminho_do_banco: Path,
exigir_validacao: bool = False,
) -> None:
"""Valida palavras, frases e respiros antes de iniciar a sessão do Premiere."""
if not plano.acoes_do_tipo(TipoDeAcao.CORTE):
return
if plano_id is None:
if exigir_validacao:
raise ErroDePlanoInvalido(
"Salve ou carregue o plano no banco antes de aplicar: sem o identificador "
"não é possível conferir a transcrição palavra por palavra."
)
return
from engine.persistencia.conexao import abrir_banco
from engine.persistencia.leitura_semantica_do_plano import LeitorDeTranscricaoDoPlano
conexao = abrir_banco(caminho_do_banco)
try:
falas = LeitorDeTranscricaoDoPlano(conexao).carregar(plano_id)
finally:
conexao.close()
ValidadorSemanticoDePlano().garantir_valido(plano, falas)
def resolver_caminho_do_node() -> str:
"""Resolve o executável Node mesmo quando o painel CEP possui um PATH reduzido.
@@ -129,6 +160,7 @@ def executar(
caminho_do_plano: Path,
plano_id: int | None = None,
caminho_do_banco: Path = CAMINHO_DO_BANCO,
exigir_validacao_semantica: bool = False,
) -> dict:
"""Lê o plano em ``caminho_do_plano`` e o aplica na sequência ativa do Premiere.
@@ -136,6 +168,12 @@ def executar(
ação — para o painel exibir o que foi aplicado e o que falhou.
"""
plano = LeitorDePlanoDeEdicao().ler(caminho_do_plano)
_validar_integridade_semantica(
plano,
plano_id,
caminho_do_banco,
exigir_validacao_semantica,
)
# A pausa é aplicada no cliente, e não dentro do aplicador, para valer
# igualmente nas leituras da timeline e nas escritas — são todas
@@ -146,11 +184,9 @@ def executar(
acesso_ao_editor = AcessoAoEditor(AcessoATimeline(cliente))
conversor_de_timeline = ConversorDeTimeline()
# Backup antes de qualquer corte, espelhando o painel CEP
# (applyEditorialActions() em cep-plugin/main.js): sem undo por
# script nesta versão do Premiere, é a única forma de recuperar o
# estado anterior se algo sair errado. Uma falha aqui não impede a
# aplicação — só fica registrada em stderr, igual ao painel.
# A engine é a única responsável pelo backup. A validação semântica já
# aconteceu antes da conexão, portanto um plano bloqueado não duplica
# a sequência. Uma falha no backup fica registrada em stderr.
sequencia_ativa = conversor_de_timeline.converter(acesso_ao_editor.obter_timeline_ativa())
backup_ok = BackupDaSequencia(cliente).criar_backup(sequencia_ativa.identificador)
print(
@@ -194,8 +230,22 @@ def main() -> None:
argumentos.add_argument("plano", type=Path)
argumentos.add_argument("--plano-id", type=int)
argumentos.add_argument("--banco", type=Path, default=CAMINHO_DO_BANCO)
argumentos.add_argument("--exigir-validacao-semantica", action="store_true")
opcoes = argumentos.parse_args()
resultado = executar(opcoes.plano, opcoes.plano_id, opcoes.banco)
try:
resultado = executar(
opcoes.plano,
opcoes.plano_id,
opcoes.banco,
opcoes.exigir_validacao_semantica,
)
except ErroDePlanoInvalido as erro:
print(json.dumps({
"todas_bem_sucedidas": False,
"erro": str(erro),
"acoes": [],
}, ensure_ascii=False, indent=2))
sys.exit(1)
print(json.dumps(resultado, ensure_ascii=False, indent=2))
if not resultado["todas_bem_sucedidas"]:
sys.exit(1)