- 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
70 lines
3.4 KiB
Python
70 lines
3.4 KiB
Python
"""Testes do mapeamento de tempos de origem para a timeline (engine.editor.mapeamento)."""
|
|
|
|
import unittest
|
|
|
|
from engine.dominio import Clipe, Faixa, IntervaloDeTempo
|
|
from engine.editor.erros import ErroDeMapeamentoDeTempo
|
|
from engine.editor.mapeamento import MapeadorDeTempoDeOrigemParaTimeline
|
|
|
|
|
|
def _clipe(identificador, tl_inicio, tl_fim, origem_inicio, origem_fim, nome="0E6A8290.MP4"):
|
|
"""Monta um Clipe de teste com intervalo na timeline e na origem."""
|
|
return Clipe(
|
|
identificador=identificador,
|
|
nome=nome,
|
|
intervalo_na_timeline=IntervaloDeTempo(tl_inicio, tl_fim),
|
|
intervalo_na_origem=IntervaloDeTempo(origem_inicio, origem_fim),
|
|
)
|
|
|
|
|
|
class TesteMapeadorDeTempoDeOrigemParaTimeline(unittest.TestCase):
|
|
"""Cobre a tradução de tempos de origem, reproduzindo o caso real do projeto:
|
|
a timeline reindexada pelo detector de cena não bate com o tempo do arquivo."""
|
|
|
|
def setUp(self):
|
|
self.mapeador = MapeadorDeTempoDeOrigemParaTimeline()
|
|
# Reproduz o caso real: clip 000f4775 está em 86.2-114.0s de origem,
|
|
# mas em 58.1-86.0s na timeline reindexada pelo scanner.
|
|
self.faixa = Faixa("video_0", "Vídeo 1", "video", 0, clipes=[
|
|
_clipe("000f4763", 0.0, 38.3, 2.3, 40.6),
|
|
_clipe("000f4775", 58.1, 86.0, 86.2, 114.0),
|
|
_clipe("outro_arquivo", 86.0, 90.0, 0.0, 4.0, nome="outro.mp4"),
|
|
])
|
|
|
|
def test_clipes_do_arquivo_filtra_por_nome_ignorando_caixa(self):
|
|
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0e6a8290.mp4")
|
|
self.assertEqual([c.identificador for c in clipes], ["000f4763", "000f4775"])
|
|
|
|
def test_localizar_clipe_no_instante_encontra_o_clipe_certo(self):
|
|
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0E6A8290.MP4")
|
|
clipe = self.mapeador.localizar_clipe_no_instante(clipes, 90.0)
|
|
self.assertEqual(clipe.identificador, "000f4775")
|
|
|
|
def test_localizar_clipe_no_instante_fora_de_qualquer_clipe_devolve_none(self):
|
|
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0E6A8290.MP4")
|
|
self.assertIsNone(self.mapeador.localizar_clipe_no_instante(clipes, 500.0))
|
|
|
|
def test_instante_na_timeline_traduz_usando_o_deslocamento_do_clipe(self):
|
|
clipe = _clipe("000f4775", 58.1, 86.0, 86.2, 114.0)
|
|
# 86.42s de origem (início real da fala) cai 0.22s depois do início
|
|
# do clipe (86.2s) e deve mapear para 58.1 + 0.22 = 58.32s na timeline.
|
|
self.assertAlmostEqual(self.mapeador.instante_na_timeline(clipe, 86.42), 58.32, places=6)
|
|
|
|
def test_instante_na_timeline_sem_intervalo_de_origem_levanta_erro(self):
|
|
clipe = Clipe("x", "n", IntervaloDeTempo(0, 1), intervalo_na_origem=None)
|
|
with self.assertRaises(ErroDeMapeamentoDeTempo):
|
|
self.mapeador.instante_na_timeline(clipe, 0.5)
|
|
|
|
def test_instante_na_timeline_por_arquivo_encontra_e_traduz(self):
|
|
timeline = None # não é usado pelo atalho; mantido para deixar a chamada explícita
|
|
instante = self.mapeador.instante_na_timeline_por_arquivo(timeline, self.faixa, "0E6A8290.MP4", 90.0)
|
|
self.assertAlmostEqual(instante, 58.1 + (90.0 - 86.2), places=6)
|
|
|
|
def test_instante_na_timeline_por_arquivo_sem_clipe_levanta_erro(self):
|
|
with self.assertRaises(ErroDeMapeamentoDeTempo):
|
|
self.mapeador.instante_na_timeline_por_arquivo(None, self.faixa, "0E6A8290.MP4", 500.0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|