feat: criada a guia Trilhas com processamento em lote e progresso

- criada a guia Trilhas com processamento em lote e progresso por música
- simplificada a guia Trilhas para ocultar a configuração interna dos modelos

Resumo:
- 12 arquivos alterados
- 1 novos
- 11 modificados
- 0 removidos

 11 files changed, 173 insertions(+), 41 deletions(-)

Arquivos:
  - .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/carregar_plano_de_edicao.py
  - code/engine/executar_scanner.py
  - code/engine/persistencia/__init__.py
  - code/engine/persistencia/repositorio_de_trilhas.py
  - code/engine/testes/test_carregar_plano_de_edicao.py
  - code/engine/testes/test_executar_scanner.py
  - code/engine/testes/test_repositorio_de_trilhas.py
This commit is contained in:
João Henrique
2026-09-10 13:59:25 -04:00
parent b1272a5e6e
commit 4c04365934
12 changed files with 236 additions and 41 deletions
+20 -3
View File
@@ -40,6 +40,7 @@ if CAMINHO_DA_MIDIA:
from engine.integracoes.premiere.conversores import ConversorDeTimeline
from engine.integracoes.midia import ExtracaoDeAudio
from engine.dominio import Clipe
from engine.scanner import ConfiguracaoVisualDoScanner, criar_detector_apple_vision, gerar_relatorio_visual
from engine.scanner.transcricao_da_timeline import TranscricaoDaTimeline
from engine.persistencia import RepositorioDeAnalisesSQLite, RepositorioDeTimelineSQLite
@@ -65,6 +66,24 @@ def nome_seguro(nome: str) -> str:
return re.sub(r"[^A-Za-z0-9._-]+", "-", nome.strip()).strip(".-") or "timeline"
def serializar_clipe_para_relatorio(clipe: Clipe) -> dict[str, object]:
"""Preserva no relatório os dados que identificam a mídia e sua origem.
As chaves ``sourceFile``, ``inPoint`` e ``outPoint`` mantêm o contrato
externo usado pelo painel CEP e pelo bridge do Premiere.
"""
intervalo_na_origem = clipe.intervalo_na_origem
return {
"identificador": clipe.identificador,
"nome": clipe.nome,
"inicio": clipe.intervalo_na_timeline.inicio,
"fim": clipe.intervalo_na_timeline.fim,
"sourceFile": clipe.arquivo,
"inPoint": intervalo_na_origem.inicio if intervalo_na_origem else None,
"outPoint": intervalo_na_origem.fim if intervalo_na_origem else None,
}
def executar(entrada: Path, saida: Path) -> Path:
"""Executa uma análise do Scanner conforme o pedido do painel.
@@ -139,9 +158,7 @@ def executar(entrada: Path, saida: Path) -> Path:
if analisar_som and faixa.tipo == "audio"
and faixa.indice in configuracao.faixas_de_audio]
audio = [{"indice": faixa.indice, "nome": faixa.nome,
"clipes": [{"identificador": clipe.identificador, "nome": clipe.nome,
"inicio": clipe.intervalo_na_timeline.inicio, "fim": clipe.intervalo_na_timeline.fim}
for clipe in faixa.clipes]}
"clipes": [serializar_clipe_para_relatorio(clipe) for clipe in faixa.clipes]}
for faixa in faixas_de_audio]
caso = nome_seguro(timeline.nome)
pasta = saida.parent / caso