feat: destacado no deploy o resumo que será gravado na mensagem do

- destacado no deploy o resumo que será gravado na mensagem do commit

Resumo:
- 8 arquivos alterados
- 1 novos
- 7 modificados
- 0 removidos

 7 files changed, 143 insertions(+), 11 deletions(-)

Arquivos:
  - .jhonny/analises.db
  - admin/deploy.command
  - code/engine/executar_scanner.py
  - code/engine/integracoes/midia/__init__.py
  - code/engine/integracoes/visual/apple_vision.py
  - code/engine/scanner/configuracao_visual.py
  - code/engine/scanner/visual.py
  - code/engine/integracoes/midia/compactador_de_proxy.py
This commit is contained in:
João Henrique
2026-09-08 18:40:52 -04:00
parent 5cc50f00a4
commit 400c3c93dd
8 changed files with 313 additions and 11 deletions
+34 -3
View File
@@ -40,6 +40,7 @@ class DetectorDeCenas:
def detectar(self, clipe: Clipe) -> ResultadoVisualDoClipe:
quadros = self.extrator.extrair(clipe)
self._preparar_analisadores(quadros)
total = len(quadros) * len(self.analisadores_de_frame) + len(self.analisadores_de_sequencia)
progresso = [0]
evidencias = self._analisar_quadros(quadros, progresso, total) + self._analisar_sequencia(quadros, progresso, total)
@@ -51,6 +52,19 @@ class DetectorDeCenas:
) for cena in cenas]
return ResultadoVisualDoClipe(clipe.identificador, evidencias, cenas, cenas_visuais)
def _preparar_analisadores(self, quadros: list[QuadroDeVideo]) -> None:
"""Prepara analisadores que precisam saber a quantidade de frames do clipe.
Caso especial do `AnalisadorAppleVisionNativo`: ele distribui a
interpretação editorial (Apple Intelligence / Foundation Models) em um
subconjunto dos frames para manter a cobertura de cena com custo menor.
"""
quantidade_de_quadros = len(quadros)
for analisador in self.analisadores_de_frame:
preparar = getattr(analisador, "preparar_interpretacao_por_clipe", None)
if callable(preparar):
preparar(quantidade_de_quadros)
def _analisar_quadros(self, quadros: list[QuadroDeVideo], progresso: list[int] | None = None,
total: int = 0) -> list[EvidenciaVisual]:
if not self.analisadores_de_frame or not quadros:
@@ -205,18 +219,35 @@ def criar_detector_apple_vision(
from ..integracoes.visual import (AnalisadorAppleVisionNativo,
AnalisadorSequenciaAppleVisionNativo,
ExtratorDeQuadrosFFmpeg)
from ..integracoes.midia import CompactadorDeProxy, ExtratorDeQuadrosDoProxy
perfil = configuracao or ConfiguracaoVisualDoScanner(intervalo_em_segundos=intervalo_em_segundos)
# Quantidade fixa de trabalhadores para extração e análise de frames.
# Em volumes externos (ex.: /Volumes/Merongo), mais threads do que isso
# satura a E/S e trava os processos de mídia a ~0% de CPU.
QUANTIDADE_DE_TRABALHADORES = 4
extrator = ExtratorDeQuadrosFFmpeg(intervalo_em_segundos=perfil.intervalo_em_segundos,
diretorio_de_cache=diretorio_de_cache or ".frames",
resolucao_maxima=perfil.resolucao_maxima,
trabalhadores_em_paralelo=QUANTIDADE_DE_TRABALHADORES)
# Leitura via proxy compactado: para arquivos pesados, evita buscar frame
# por frame no arquivo original (um -ss por frame num MOV de vários GB).
if perfil.usar_proxy:
extrator = ExtratorDeQuadrosDoProxy(
extrator, CompactadorDeProxy(), largura_maxima=perfil.resolucao_do_proxy
)
return DetectorDeCenas(
ExtratorDeQuadrosFFmpeg(intervalo_em_segundos=perfil.intervalo_em_segundos,
diretorio_de_cache=diretorio_de_cache or ".frames",
resolucao_maxima=perfil.resolucao_maxima),
extrator,
analisadores_de_frame=[AnalisadorAppleVisionNativo(
recursos=tuple(sorted(perfil.recursos_vision)),
interpretar_com_apple_intelligence=perfil.interpretar_cena,
maximo_de_frames_interpretados=perfil.maximo_de_frames_interpretados,
)],
analisadores_de_sequencia=[AnalisadorSequenciaAppleVisionNativo()]
if perfil.analisar_continuidade else [],
detectores_de_intervalo=_detectores_de_cena_do_perfil(perfil),
trabalhadores_em_paralelo=QUANTIDADE_DE_TRABALHADORES,
)