feat: criada a aba Análises no painel CEP para ler do banco (anali
- criada a aba Análises no painel CEP para ler do banco (analises.db) e copiar/abrir o J-SOM de som (transcrição por cena) e o de imagem (evidências visuais), com novo módulo engine/gerar_relatorio_de_analises.py e testes - criado o módulo engine/editor (leitura do plano de edição em JSON, tradução de tempos de origem para a timeline ativa e aplicação de cortes/zooms/marcadores no Premiere via MCP) e o ponto de entrada engine/aplicar_plano_de_edicao.py, com testes; corrigido engine/integracoes/premiere/cliente_mcp.py para levantar os erros específicos já declarados em erros_mcp.py em vez de RuntimeError genérico Resumo: - 15 arquivos alterados - 8 novos - 5 modificados - 2 removidos 7 files changed, 172 insertions(+), 8 deletions(-) Arquivos: - .jhonny/analises.db - .jhonny/analises.db-shm - .jhonny/analises.db-wal - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - code/engine/integracoes/premiere/cliente_mcp.py - code/engine/aplicar_plano_de_edicao.py - code/engine/editor/ - code/engine/gerar_relatorio_de_analises.py - code/engine/testes/duplos_de_premiere.py - code/engine/testes/test_aplicador_de_plano_de_edicao.py - code/engine/testes/test_gerar_relatorio_de_analises.py - code/engine/testes/test_leitor_de_plano_de_edicao.py - code/engine/testes/test_mapeador_de_tempo.py
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
"""Escrita de mutações na sequência ativa do Premiere."""
|
||||
|
||||
from .escrita_no_editor import EscritaNoEditor
|
||||
|
||||
__all__ = ["EscritaNoEditor"]
|
||||
@@ -0,0 +1,91 @@
|
||||
"""Escrita de mutações na sequência ativa do Premiere via MCP.
|
||||
|
||||
Isola o nome das ferramentas MCP e o formato de argumentos externos
|
||||
(``split_clip``, ``remove_from_timeline``, ``set_clip_properties``,
|
||||
``add_marker``) do resto do domínio. Quem chama esta classe fala só em
|
||||
segundos de timeline, identificador de clipe e fator de escala — nunca em
|
||||
nomes de ferramenta ou ticks do Premiere.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ...integracoes.premiere.cliente_mcp import ClienteMCP
|
||||
from ...integracoes.premiere.erros_mcp import ErroDeFerramentaMCP
|
||||
from ..erros import ErroDeEscritaNoEditor
|
||||
|
||||
_CORES_POR_NOME = {
|
||||
"revisar": 3, # laranja: chama atenção sem parecer um erro (vermelho)
|
||||
"informar": 5, # branco: marcador neutro
|
||||
}
|
||||
|
||||
|
||||
class EscritaNoEditor:
|
||||
"""Aplica, uma de cada vez, as mutações que o aplicador de plano decide fazer."""
|
||||
|
||||
def __init__(self, cliente_mcp: ClienteMCP) -> None:
|
||||
self.cliente_mcp = cliente_mcp
|
||||
|
||||
def dividir_clipe_se_necessario(self, instante_da_timeline: float, indice_da_faixa: int, tipo_da_faixa: str) -> bool:
|
||||
"""Corta, na timeline, o clipe que cobrir ``instante_da_timeline``.
|
||||
|
||||
Devolve ``True`` se um corte novo foi criado e ``False`` quando o
|
||||
instante já era uma borda de clipe (o Premiere recusa dividir onde
|
||||
não há clipe atravessando o ponto) — esse segundo caso não é um erro,
|
||||
é o resultado esperado quando o corte pedido coincide com um corte já
|
||||
existente da análise de cenas.
|
||||
"""
|
||||
try:
|
||||
self.cliente_mcp.chamar(
|
||||
"split_clip",
|
||||
{"time_seconds": instante_da_timeline, "track_index": indice_da_faixa, "track_type": tipo_da_faixa},
|
||||
)
|
||||
return True
|
||||
except ErroDeFerramentaMCP:
|
||||
return False
|
||||
|
||||
def remover_trecho(self, identificador_do_clipe: str) -> None:
|
||||
"""Remove o clipe da timeline, fechando o espaço deixado (ripple).
|
||||
|
||||
Levanta :class:`ErroDeEscritaNoEditor` se o Premiere recusar a
|
||||
remoção.
|
||||
"""
|
||||
try:
|
||||
self.cliente_mcp.chamar("remove_from_timeline", {"node_id": identificador_do_clipe, "ripple": True})
|
||||
except ErroDeFerramentaMCP as erro:
|
||||
raise ErroDeEscritaNoEditor(f"Não foi possível remover o clipe {identificador_do_clipe!r}: {erro}") from erro
|
||||
|
||||
def aplicar_zoom(self, identificador_do_clipe: str, fator_de_escala: float) -> None:
|
||||
"""Aplica um punch-in no clipe, escalando-o por ``fator_de_escala`` (1.0 = tamanho original).
|
||||
|
||||
Levanta :class:`ErroDeEscritaNoEditor` se o Premiere recusar a
|
||||
alteração.
|
||||
"""
|
||||
try:
|
||||
self.cliente_mcp.chamar(
|
||||
"set_clip_properties", {"node_id": identificador_do_clipe, "scale": fator_de_escala * 100}
|
||||
)
|
||||
except ErroDeFerramentaMCP as erro:
|
||||
raise ErroDeEscritaNoEditor(
|
||||
f"Não foi possível aplicar zoom no clipe {identificador_do_clipe!r}: {erro}"
|
||||
) from erro
|
||||
|
||||
def adicionar_marcador(self, instante_da_timeline: float, nome: str, comentario: str) -> None:
|
||||
"""Cria um marcador de sequência em ``instante_da_timeline``.
|
||||
|
||||
Levanta :class:`ErroDeEscritaNoEditor` se o Premiere recusar a
|
||||
criação do marcador.
|
||||
"""
|
||||
try:
|
||||
self.cliente_mcp.chamar(
|
||||
"add_marker",
|
||||
{
|
||||
"time_seconds": instante_da_timeline,
|
||||
"name": nome,
|
||||
"comments": comentario,
|
||||
"color": _CORES_POR_NOME["revisar"],
|
||||
},
|
||||
)
|
||||
except ErroDeFerramentaMCP as erro:
|
||||
raise ErroDeEscritaNoEditor(
|
||||
f"Não foi possível adicionar o marcador em {instante_da_timeline}s: {erro}"
|
||||
) from erro
|
||||
Reference in New Issue
Block a user