feat: criado repositório jhonny-editor no Gitea
criado repositório jhonny-editor no Gitea adicionado script admin/deploy.command com commit automático atualizado admin/DEV-NOTES.md com template limpo Resumo: - 48 arquivos alterados - 26 novos - 19 modificados - 3 removidos 22 files changed, 658 insertions(+), 568 deletions(-) Arquivos: - AGENTS.md - admin/DEV-NOTES.md - admin/OpenCut.command - admin/commit.command - admin/deploy.command - admin/update.command - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - code/engine/ARQUITETURA.md - code/engine/arquitetura/README.md - code/engine/gerar_relatorio_timeline.py - code/engine/integracoes/apple_speech/apple_speech_transcriber.swift - code/engine/integracoes/apple_speech/provider_de_transcricao_apple.py - code/engine/integracoes/midia/__init__.py - code/engine/integracoes/whisper/provider_de_transcricao_local.py - code/engine/scanner/__init__.py - code/engine/scanner/coordenacao/__init__.py - code/engine/scanner/descoberta/__init__.py - code/engine/scanner/modelos.py - code/engine/scanner/transcricao_da_timeline.py - code/src/tools/discovery.ts - :memory:.ses - admin/Jhonny.command - admin/inativos/OpenCut.command - admin/inativos/update.command - code/docs/glossario-analise-emocional.md - code/docs/levantamento-apple-vision-e-apple-intelligence.md - code/docs/levantamento-ferramentas-analise-visual-local.md - code/engine/arquitetura/biblioteca-inteligente-de-videos.md - code/engine/executar_scanner.py - code/engine/integracoes/huggingface/ - code/engine/integracoes/midia/extracao_de_metadados.py - code/engine/integracoes/visual/ - code/engine/requirements-visual.txt - code/engine/scanner/configuracao_visual.py - code/engine/scanner/descoberta/descoberta_de_arquivos.py - code/engine/scanner/metadados.py - code/engine/scanner/relatorio_visual.py - code/engine/scanner/retakes/ - code/engine/scanner/visual.py - code/engine/testes/test_analise_visual_local.py - code/engine/testes/test_arquivos_e_metadados.py - code/engine/testes/test_provider_de_transcricao_apple.py - code/relatorios/analise-brools/ - code/relatorios/analise-visual/ - code/relatorios/audio/arquivos/ - code/relatorios/transcricao-timeline.md
This commit is contained in:
@@ -26,6 +26,7 @@ Cada módulo principal deverá possuir um documento próprio nesta pasta.
|
||||
arquitetura/
|
||||
├── README.md
|
||||
├── scanner.md
|
||||
├── biblioteca-inteligente-de-videos.md
|
||||
├── integracao-com-premiere.md
|
||||
├── leitura-da-timeline-via-mcp.md
|
||||
├── plano-primeira-etapa-scanner-e-mcp.md
|
||||
|
||||
@@ -0,0 +1,466 @@
|
||||
# Biblioteca Inteligente de Vídeos
|
||||
|
||||
## Objetivo
|
||||
|
||||
Transformar uma pasta selecionada pelo usuário em uma biblioteca audiovisual documentada e pesquisável. O sistema deve responder não apenas quais arquivos existem, mas quais evidências de conteúdo aparecem em cada arquivo e em que intervalo temporal.
|
||||
|
||||
Exemplos de consultas:
|
||||
|
||||
- “Encontre vídeos em que uma pessoa caminha na rua.”
|
||||
- “Mostre cenas em que alguém fala diante de uma câmera.”
|
||||
- “Encontre momentos em que aparece um carro vermelho.”
|
||||
|
||||
O módulo é de descoberta, análise e recuperação. Ele não decide cortes, não altera a timeline e não deve ser confundido com o índice de Media Intelligence do Premiere. Será um índice local próprio, alimentado pelos adapters disponíveis no projeto.
|
||||
|
||||
## Decisões arquiteturais
|
||||
|
||||
### 1. Nova unidade de domínio: biblioteca, ativo e evidência
|
||||
|
||||
O scanner atual é orientado a uma `Timeline`; este requisito é orientado a uma `BibliotecaDeVideos`. Os dois fluxos podem compartilhar adapters de mídia, mas não devem compartilhar o mesmo contexto de execução.
|
||||
|
||||
```text
|
||||
BibliotecaDeVideos
|
||||
└── AtivoDeVideo
|
||||
├── MetadadosDoArquivo
|
||||
├── SegmentoDeConteudo
|
||||
│ ├── EvidenciaVisual
|
||||
│ ├── SegmentoDeTranscricao
|
||||
│ └── EvidenciaDeAudio
|
||||
└── RepresentacoesDeBusca
|
||||
```
|
||||
|
||||
Um `AtivoDeVideo` é identificado por uma identidade estável do conteúdo, não apenas pelo nome do arquivo. A identidade inicial deve combinar caminho normalizado, tamanho, data de modificação e uma impressão digital do arquivo. Quando houver colisão ou suspeita de alteração, o hash completo deve confirmar a identidade.
|
||||
|
||||
Uma `Evidencia` é um fato observado por um provider, com tipo, valor, intervalo no arquivo de origem, confiança, provider e versão do modelo. Descrições geradas por IA são evidências com proveniência; não são fatos absolutos nem instruções executáveis.
|
||||
|
||||
### 2. O módulo externo deve ser profundo
|
||||
|
||||
O chamador não deve conhecer FFmpeg, OpenCV, Vision, Whisper, filas, SQLite ou o mecanismo vetorial. A seam pública deve oferecer poucas operações orientadas a intenção:
|
||||
|
||||
```python
|
||||
class BibliotecaDeVideos:
|
||||
def indexar_pasta(self, pasta: str | Path, configuracao: ConfiguracaoDaBiblioteca) -> IdDaExecucao: ...
|
||||
def obter_status(self, execucao: IdDaExecucao) -> StatusDaIndexacao: ...
|
||||
def buscar(self, consulta: str, opcoes: OpcoesDeBusca | None = None) -> list[ResultadoDeBusca]: ...
|
||||
def obter_ativo(self, identificador: str) -> AtivoDeVideo | None: ...
|
||||
```
|
||||
|
||||
`indexar_pasta` inicia ou agenda uma execução idempotente e retorna imediatamente. O progresso é consultado pelo identificador da execução. `buscar` retorna resultados agrupados por ativo, com trechos temporais e evidências que justificam cada resultado.
|
||||
|
||||
O módulo esconde a coordenação entre descoberta incremental, análise, persistência e indexação de busca. Adapters internos podem variar sem alterar essa interface.
|
||||
|
||||
### 3. Indexação incremental é regra do domínio
|
||||
|
||||
Cada ativo deve registrar:
|
||||
|
||||
- impressão digital observada;
|
||||
- versão do contrato de análise;
|
||||
- versão de cada provider/modelo usado;
|
||||
- etapas concluídas;
|
||||
- etapas com erro ou aviso;
|
||||
- último status e última execução.
|
||||
|
||||
Um arquivo inalterado e já concluído não deve ser analisado novamente. Um arquivo novo entra na fila. Um arquivo cuja impressão digital mudou invalida apenas as etapas derivadas daquele conteúdo. Se somente um provider ou sua versão mudou, a política pode invalidar apenas a etapa correspondente.
|
||||
|
||||
Arquivos removidos da pasta não devem ser apagados imediatamente do índice: passam a `ausente_na_origem`, preservando resultados históricos e permitindo recuperação caso retornem. A remoção definitiva deve ser uma operação explícita futura.
|
||||
|
||||
## Módulos e responsabilidades
|
||||
|
||||
### `biblioteca`
|
||||
|
||||
Módulo profundo e seam principal. Recebe a intenção do usuário, cria uma execução, delega o trabalho ao coordenador e expõe status, resultados e erros normalizados.
|
||||
|
||||
Não conhece detalhes de providers nem executa chamadas de sistema diretamente.
|
||||
|
||||
### `descoberta_da_pasta`
|
||||
|
||||
Percorre a pasta autorizada, respeitando configuração de recursão, extensões suportadas, exclusões e links simbólicos. Produz candidatos de arquivos de vídeo e reconcilia o snapshot atual com o último snapshot persistido.
|
||||
|
||||
Não extrai metadados, não abre frames e não chama IA.
|
||||
|
||||
### `identidade_do_ativo`
|
||||
|
||||
Calcula e compara a impressão digital do arquivo. Encapsula a política de “novo”, “inalterado”, “alterado” e “ausente”. Deve ser determinística e testável com um filesystem falso.
|
||||
|
||||
### `coordenacao_da_indexacao`
|
||||
|
||||
Transforma candidatos em trabalhos por ativo e etapa, respeita dependências, atualiza progresso, trata cancelamento, permite retomada e aplica a política de erro por ativo.
|
||||
|
||||
Dependências sugeridas:
|
||||
|
||||
```text
|
||||
descoberta
|
||||
└── metadados
|
||||
├── amostragem_de_frames ── análise_visual ── segmentos_visuais
|
||||
└── extração_de_audio ── transcrição ── segmentos_de_fala
|
||||
└── análise_de_audio
|
||||
|
||||
segmentos + evidências ── consolidação_temporal ── indexação_de_busca
|
||||
```
|
||||
|
||||
Metadados devem ser pré-requisito para calcular duração e amostragem. O ramo visual e o ramo de áudio podem executar em paralelo. A consolidação e a indexação só ocorrem depois dos ramos habilitados, sem exigir que todos tenham sucesso.
|
||||
|
||||
### `analise_de_conteudo_audiovisual`
|
||||
|
||||
Orquestra os adapters já existentes no projeto:
|
||||
|
||||
- `ExtracaoDeMetadados` para dados técnicos;
|
||||
- `ExtratorDeQuadros` e `DetectorDeCenas` para amostragem e intervalos;
|
||||
- analisadores OpenCV, Apple Vision, ONNX ou MediaPipe para evidências visuais;
|
||||
- adapters Whisper, Apple Speech ou Groq para transcrição;
|
||||
- diarização e emoção local quando habilitadas.
|
||||
|
||||
O resultado deve usar modelos do domínio, especialmente `EvidenciaVisual`, `CenaVisual` e `SegmentoDeTranscricao`. Um provider indisponível gera aviso de capacidade e não deve apagar evidências produzidas por outros providers.
|
||||
|
||||
O módulo não deve pedir que um modelo de linguagem “assista” ao arquivo inteiro. A análise deve trabalhar com amostras temporais, cenas e agregação de evidências. Uma descrição de cena pode ser criada a partir de um conjunto limitado de frames, sempre mantendo os timestamps que a sustentam.
|
||||
|
||||
### `consolidacao_temporal`
|
||||
|
||||
Converte observações pontuais em intervalos úteis para busca. Observações do mesmo tipo e valor semelhante podem ser agrupadas quando estão próximas, com uma margem configurável. O resultado precisa conservar as observações originais, pois elas são a evidência auditável do intervalo consolidado.
|
||||
|
||||
Esse módulo é o lugar correto para responder “em que momento” e para evitar que a busca retorne apenas o arquivo inteiro.
|
||||
|
||||
### `persistencia_do_indice`
|
||||
|
||||
Adapter responsável por salvar e ler o estado durável. A primeira implementação deve ser local e transacional, preferencialmente SQLite, com arquivos de frames/áudio tratados como cache reconstruível fora do banco.
|
||||
|
||||
Interface mínima:
|
||||
|
||||
```python
|
||||
class RepositorioDaBiblioteca(Protocol):
|
||||
def reconciliar_snapshot(self, snapshot: SnapshotDaPasta) -> ResultadoDaReconciliacao: ...
|
||||
def salvar_resultado(self, resultado: ResultadoDoAtivo) -> None: ...
|
||||
def obter_trabalho_pendente(self, limite: int) -> list[TrabalhoDeIndexacao]: ...
|
||||
def atualizar_status(self, status: StatusDaIndexacao) -> None: ...
|
||||
def buscar_evidencias(self, consulta: ConsultaNormalizada) -> list[ResultadoDeBusca]: ...
|
||||
```
|
||||
|
||||
O contrato deve permitir um adapter em memória para testes. Nenhum provider deve escrever diretamente no banco.
|
||||
|
||||
### `busca_semantica`
|
||||
|
||||
Recebe texto livre, normaliza a consulta e combina três fontes:
|
||||
|
||||
1. busca lexical em nomes, transcrições, rótulos e descrições;
|
||||
2. busca vetorial em descrições de cenas, transcrições e evidências;
|
||||
3. filtros estruturados por ativo, intervalo, tipo de evidência, confiança e status.
|
||||
|
||||
O MVP deve priorizar busca híbrida com ranking explicável. Cada resultado deve informar score, trecho, arquivo e evidências correspondentes. Busca vetorial sem evidência temporal não atende ao requisito.
|
||||
|
||||
Um adapter vetorial pode ser adicionado depois. A persistência deve permitir começar com SQLite FTS e embeddings opcionais, sem acoplar o domínio a um banco vetorial específico.
|
||||
|
||||
### `integracao_com_timeline_e_editor`
|
||||
|
||||
Traduz um `ResultadoDeBusca` para ações de revisão: abrir o arquivo, posicionar o playhead, criar marcador ou propor um clipe para o fluxo editorial. A integração deve ser somente leitura/proposição na primeira versão.
|
||||
|
||||
Não deve alterar a timeline automaticamente nem tratar um resultado sem revisão como autorização de edição.
|
||||
|
||||
## Modelo de dados lógico
|
||||
|
||||
```text
|
||||
bibliotecas
|
||||
id, raiz, configuracao_json, criada_em, atualizada_em
|
||||
|
||||
ativos
|
||||
id, biblioteca_id, caminho, nome, extensao, status_origem,
|
||||
tamanho, modificado_em, fingerprint, criado_em, atualizado_em
|
||||
|
||||
metadados_dos_ativos
|
||||
ativo_id, duracao, largura, altura, fps, codecs, formato, json_extra
|
||||
|
||||
execucoes_de_indexacao
|
||||
id, biblioteca_id, status, motivo, iniciada_em, finalizada_em,
|
||||
total_trabalhos, concluidos, falhos, cancelada_em
|
||||
|
||||
trabalhos_de_indexacao
|
||||
id, execucao_id, ativo_id, etapa, versao, status, tentativas,
|
||||
erro, iniciada_em, finalizada_em
|
||||
|
||||
segmentos_de_conteudo
|
||||
id, ativo_id, inicio, fim, tipo, resumo, confianca, origem
|
||||
|
||||
evidencias
|
||||
id, segmento_id, tipo, valor_json, inicio, fim, confianca,
|
||||
provider, modelo, versao
|
||||
|
||||
transcricoes
|
||||
id, ativo_id, inicio, fim, texto, falante, confianca, provider, versao
|
||||
|
||||
representacoes_de_busca
|
||||
id, alvo_tipo, alvo_id, texto, embedding, indice_lexical
|
||||
```
|
||||
|
||||
Os intervalos são sempre relativos ao arquivo de origem. Quando houver uso numa timeline, a tradução para o intervalo da timeline pertence à integração com o editor, usando o `intervalo_na_origem` do domínio existente.
|
||||
|
||||
## Fluxo completo
|
||||
|
||||
```text
|
||||
Usuário seleciona pasta
|
||||
↓
|
||||
BibliotecaDeVideos.indexar_pasta()
|
||||
↓
|
||||
Execução persistida + trabalhos pendentes
|
||||
↓
|
||||
Snapshot da pasta e reconciliação por fingerprint
|
||||
↓
|
||||
Metadados por ativo novo/alterado
|
||||
↓
|
||||
Ramos visual e áudio em segundo plano
|
||||
↓
|
||||
Consolidação de cenas, evidências e falas
|
||||
↓
|
||||
Atualização transacional do índice lexical/vetorial
|
||||
↓
|
||||
Status consultável e busca com timestamps
|
||||
```
|
||||
|
||||
Cada trabalho deve ser retomável. A gravação de uma etapa deve ser atômica: o índice não pode anunciar uma etapa concluída antes de seus dados e sua versão estarem persistidos.
|
||||
|
||||
## Contrato de status e falhas
|
||||
|
||||
Status da biblioteca: `nao_indexada`, `indexando`, `parcial`, `concluida`, `falhou` ou `ausente_na_origem`.
|
||||
|
||||
Status da etapa: `pendente`, `em_execucao`, `concluida`, `concluida_com_avisos`, `falhou`, `cancelada`.
|
||||
|
||||
Falha de um arquivo não deve interromper toda a biblioteca. Falha de descoberta ou persistência deve interromper a execução, pois torna o resultado inconsistente. Falha de um provider deve marcar a capacidade correspondente como indisponível e preservar as demais etapas.
|
||||
|
||||
O status deve conter progresso por contagem de trabalhos e por ativo; percentual baseado apenas em duração de vídeo pode ficar enganoso quando há arquivos muito diferentes.
|
||||
|
||||
## Escopo recomendado do MVP
|
||||
|
||||
1. Seleção e persistência de uma biblioteca local.
|
||||
2. Descoberta recursiva de extensões configuradas.
|
||||
3. Fingerprint e reconciliação incremental.
|
||||
4. Metadados via FFprobe.
|
||||
5. Amostragem de frames e análise visual já disponível localmente.
|
||||
6. Transcrição por um adapter configurado, com timestamps.
|
||||
7. Segmentos temporais e evidências persistidos em SQLite.
|
||||
8. Busca lexical por nome, transcrição, rótulos e descrições normalizadas.
|
||||
9. Status, retomada e cancelamento do processamento.
|
||||
10. Resultado com caminho, intervalo, confiança e evidência.
|
||||
|
||||
Ficam para uma segunda etapa: embeddings, ranking híbrido, diarização avançada, reconhecimento de identidade, monitoramento contínuo por filesystem watcher, agrupamento de takes semelhantes e criação automática de marcadores no Premiere.
|
||||
|
||||
## Integração com o que já existe
|
||||
|
||||
O novo módulo deve reutilizar os adapters de `code/engine/integracoes/midia`, `code/engine/integracoes/visual` e `code/engine/integracoes/whisper`. A implementação atual de `scanner` pode continuar atendendo análises de timeline; o novo coordenador transforma `AtivoDeVideo` em uma entrada compatível com os adapters, sem fazer o domínio da biblioteca depender de `Timeline`.
|
||||
|
||||
O `DescobertaDeArquivos` existente contém parte da política de validação local e pode fornecer um adapter compartilhado, desde que sua interface não passe a conhecer biblioteca, fila ou persistência. A análise visual local já produz evidências temporais adequadas, mas a etapa de consolidação deve ficar fora do detector de cenas para manter a separação entre observação e indexação.
|
||||
|
||||
As limitações documentadas em `advanced-feature-support.ts` permanecem válidas: o sistema não deve alegar acesso ao índice nativo do Premiere nem iniciar/monitorar operações não expostas por API pública. A biblioteca local é uma capacidade independente.
|
||||
|
||||
## Testabilidade e seams
|
||||
|
||||
O domínio deve ser testável sem FFmpeg, GPU, macOS Vision, rede ou arquivos reais. Adapters necessários para testes:
|
||||
|
||||
- filesystem que retorna snapshots controlados;
|
||||
- calculador de fingerprint determinístico;
|
||||
- provider de metadados falso;
|
||||
- extrator de frames falso;
|
||||
- providers visual e de transcrição falsos;
|
||||
- relógio injetável;
|
||||
- repositório em memória;
|
||||
- fila síncrona ou executor controlado;
|
||||
- ranking lexical/vetorial falso.
|
||||
|
||||
Testes prioritários:
|
||||
|
||||
- arquivo inalterado não gera trabalho novamente;
|
||||
- novo arquivo gera apenas as etapas necessárias;
|
||||
- arquivo alterado invalida resultados derivados;
|
||||
- mudança de versão de provider invalida somente sua etapa;
|
||||
- falha visual não apaga transcrição;
|
||||
- timestamps nunca ultrapassam a duração conhecida;
|
||||
- resultados de busca preservam evidências e intervalo;
|
||||
- retomada continua do último trabalho persistido;
|
||||
- cancelamento não deixa etapa marcada como concluída;
|
||||
- arquivo removido vira ausente sem perder histórico.
|
||||
|
||||
## Decisões em aberto
|
||||
|
||||
Antes da implementação, ainda precisamos escolher:
|
||||
|
||||
1. banco local definitivo: SQLite puro, SQLite com FTS5 e embeddings em arquivo, ou outro adapter;
|
||||
2. executor em segundo plano: processo Python separado, thread controlada ou integração com o host;
|
||||
3. provider visual padrão do MVP: OpenCV, Apple Vision ou configuração por perfil;
|
||||
4. provider de transcrição padrão e política de privacidade para enviar áudio a serviços externos;
|
||||
5. extensões, exclusões e limite de profundidade da pasta;
|
||||
6. política de retenção do cache de frames e áudio;
|
||||
7. formato do contrato de descrição semântica produzido pelo modelo de IA.
|
||||
|
||||
Essas escolhas não devem alterar a interface de `BibliotecaDeVideos`; devem apenas selecionar adapters e configuração.
|
||||
|
||||
## Catálogo SQLite e processamento contínuo
|
||||
|
||||
### SQLite como catálogo, não como depósito de mídia
|
||||
|
||||
SQLite é adequado para o catálogo local porque oferece transações, consultas relacionais, FTS5 para busca textual e baixo custo operacional. O banco não deve armazenar vídeos, áudio extraído ou imagens em escala. Esses dados ficam na pasta original ou em um cache controlado; no banco ficam referências, metadados, resultados compactos e estado de processamento.
|
||||
|
||||
O arquivo do catálogo deve ficar fora da pasta indexada, em um diretório de dados do aplicativo. Assim, uma pasta pode ser removida, movida ou compartilhada sem levar o estado interno do agente junto com ela. A configuração deve permitir uma biblioteca por pasta e várias bibliotecas no mesmo catálogo.
|
||||
|
||||
Para lidar com nomes repetidos, a chave do ativo não será `nome`. O cadastro deve usar um identificador interno e único, por exemplo:
|
||||
|
||||
```text
|
||||
identificador_do_ativo = UUID interno
|
||||
identidade_do_conteudo = hash do conteúdo + tamanho
|
||||
localizacao = biblioteca + caminho relativo normalizado
|
||||
```
|
||||
|
||||
O caminho relativo distingue duas cópias iguais em locais diferentes; a identidade do conteúdo permite reconhecer um arquivo renomeado ou movido dentro da mesma biblioteca. O cálculo deve ser progressivo: primeiro comparar tamanho e data de modificação, depois calcular uma impressão digital parcial; o hash completo fica reservado para arquivos suspeitos, duplicatas ou confirmação de identidade.
|
||||
|
||||
### Estado persistido por etapa
|
||||
|
||||
O catálogo deve tratar a análise como um conjunto de trabalhos independentes, não como uma operação monolítica por vídeo. Cada trabalho tem `ativo_id`, `etapa`, `versao_da_etapa`, `status`, `progresso`, `checkpoint`, `tentativas`, `erro` e timestamps.
|
||||
|
||||
Checkpoints possíveis:
|
||||
|
||||
- último timestamp de frame processado;
|
||||
- último intervalo de áudio transcrito;
|
||||
- identificador da janela de cena atual;
|
||||
- lote de evidências já persistido;
|
||||
- versão do modelo e parâmetros efetivos.
|
||||
|
||||
Um checkpoint só é confirmado junto com os resultados daquele lote. Em caso de interrupção, o executor retoma a partir do último checkpoint confirmado, com uma pequena sobreposição temporal para não perder eventos na transição entre lotes. A escrita deve ser idempotente usando uma chave lógica como `ativo + etapa + versão + intervalo + provider`.
|
||||
|
||||
### Worker de baixa prioridade
|
||||
|
||||
O processamento contínuo deve ser implementado como um worker controlado pelo sistema, com uma iteração curta e cooperativa. Ele não deve manter vídeos, frames ou áudios inteiros em memória.
|
||||
|
||||
Política inicial:
|
||||
|
||||
- um ativo por vez por padrão;
|
||||
- um lote pequeno de frames por vez;
|
||||
- áudio extraído em arquivo temporário ou stream, nunca inteiro em memória;
|
||||
- transação SQLite curta por lote;
|
||||
- pausa entre lotes quando a máquina estiver ocupada;
|
||||
- suspensão com bateria, modo de economia de energia, temperatura alta ou pressão de memória;
|
||||
- limite configurável de CPU, memória, espaço de cache e tempo por ciclo;
|
||||
- cancelamento cooperativo verificado entre frames, lotes e etapas;
|
||||
- processos de provider isolados quando uma biblioteca nativa puder bloquear ou consumir memória excessiva.
|
||||
|
||||
O worker deve consultar uma política de recursos antes de iniciar cada lote:
|
||||
|
||||
```python
|
||||
class PoliticaDeRecursos(Protocol):
|
||||
def pode_executar(self, trabalho: TrabalhoDeIndexacao) -> bool: ...
|
||||
def tamanho_do_lote(self, trabalho: TrabalhoDeIndexacao) -> int: ...
|
||||
def deve_pausar(self) -> bool: ...
|
||||
```
|
||||
|
||||
O objetivo não é manter o agente analisando a qualquer custo, mas aproveitar períodos ociosos. Se a máquina estiver ocupada, o worker deve dormir e deixar o sistema responsivo. A prioridade do processo e a afinidade de CPU são detalhes de um adapter do host, não regras espalhadas pelo domínio.
|
||||
|
||||
### Varredura contínua
|
||||
|
||||
O modo contínuo deve combinar duas estratégias:
|
||||
|
||||
1. uma varredura periódica e lenta da pasta, que é a fonte de verdade;
|
||||
2. um watcher opcional para antecipar a descoberta de arquivos novos ou alterados.
|
||||
|
||||
O watcher não deve iniciar análise diretamente. Ele apenas marca a biblioteca como “precisa reconciliar”; a próxima varredura confirma o estado, evitando arquivos ainda sendo copiados. Um arquivo só entra na fila depois de permanecer estável por um intervalo configurável e passar por uma leitura mínima de metadados.
|
||||
|
||||
Ao iniciar, retomar ou acordar após ocioso, o worker deve:
|
||||
|
||||
```text
|
||||
reconciliar pasta → atualizar origem dos ativos → recalcular trabalhos necessários
|
||||
→ escolher próximo trabalho → processar lote → persistir checkpoint → repetir
|
||||
```
|
||||
|
||||
### Frequência de frames
|
||||
|
||||
Não existe uma frequência única ideal. Analisar todos os frames é caro e, para busca semântica, geralmente redundante. A recomendação para o MVP é uma amostragem em camadas:
|
||||
|
||||
| Camada | Frequência inicial | Finalidade |
|
||||
|---|---:|---|
|
||||
| triagem | 1 frame a cada 2–5 s | descobrir duração, atividade e mudanças grosseiras |
|
||||
| cena ativa | 1–2 frames/s | descrever objetos, pessoas e composição |
|
||||
| transição | frequência temporariamente maior | refinar início/fim de uma mudança de cena |
|
||||
| áudio | janelas contínuas | transcrição e detecção de fala/silêncio |
|
||||
|
||||
O valor de `1 frame/s` é um bom ponto de partida para vídeos comuns, mas deve ser uma configuração, não uma regra fixa. Conteúdo com movimento rápido, cortes frequentes, texto na tela ou ações curtas precisa de amostragem adaptativa. Conteúdo estático pode reduzir a frequência quando os frames consecutivos têm baixa diferença visual.
|
||||
|
||||
O detector deve aumentar a frequência localmente quando detectar mudança de cena, movimento relevante, fala, texto novo ou baixa confiança. Deve reduzir a frequência quando houver continuidade visual, silêncio prolongado ou repetição de frames. Cada evidência precisa registrar a amostragem usada, para que a ausência de detecção não seja interpretada como prova de ausência.
|
||||
|
||||
### Transcrição
|
||||
|
||||
O adapter local baseado em `faster-whisper` é a escolha padrão recomendada para o catálogo: mantém o processamento privado, entrega timestamps e já se encaixa nos providers existentes. O tamanho do modelo deve ser configurável por perfil de recurso:
|
||||
|
||||
- perfil econômico: modelo menor, CPU e baixa prioridade;
|
||||
- perfil equilibrado: modelo intermediário, possivelmente aceleração disponível;
|
||||
- perfil qualidade: modelo maior, somente quando solicitado ou quando houver tempo ocioso.
|
||||
|
||||
Apple Speech pode ser um adapter preferencial em macOS quando o requisito for baixo consumo e o idioma suportado for suficiente. Groq ou outro provider remoto deve ser opt-in, com consentimento explícito, indicação de que o áudio sai da máquina e registro do provider usado. A transcrição persistida deve guardar idioma, modelo, provider, confiança e timestamps; trocar o modelo invalida somente a etapa de transcrição, não os metadados nem necessariamente a análise visual.
|
||||
|
||||
### Combinação de fontes
|
||||
|
||||
O cadastro útil para o agente deve manter as fontes separadas e criar uma representação consolidada:
|
||||
|
||||
```text
|
||||
metadados técnicos
|
||||
+ transcrição temporal
|
||||
+ evidências visuais temporais
|
||||
+ evidências de áudio
|
||||
+ mudanças de cena
|
||||
↓
|
||||
segmento de conteúdo
|
||||
↓
|
||||
texto indexável + filtros + evidências
|
||||
```
|
||||
|
||||
Um segmento pode ter o resumo “pessoa entra em uma sala enquanto fala”, mas deve apontar para: o intervalo temporal, os frames que sustentam “pessoa” e “entra”, e o trecho de transcrição que sustenta “fala”. O resumo serve para recuperação; as evidências servem para auditoria, ranking e revisão humana.
|
||||
|
||||
### Estratégia de prioridade
|
||||
|
||||
A prioridade deve ser calculada no momento de escolher o próximo trabalho, sem alterar a identidade nem o resultado do ativo. Uma pontuação inicial pode considerar:
|
||||
|
||||
```text
|
||||
prioridade = intenção explícita
|
||||
+ ativo aberto ou usado recentemente no editor
|
||||
+ arquivo novo ou alterado
|
||||
+ etapa necessária para uma busca pendente
|
||||
+ tamanho/tempo estimado que permita concluir um lote
|
||||
- custo estimado
|
||||
- idade da última tentativa com falha
|
||||
```
|
||||
|
||||
Categorias práticas:
|
||||
|
||||
1. urgente: ativo solicitado numa busca ou aberto para edição;
|
||||
2. alta: arquivo novo, alterado ou associado ao projeto atual;
|
||||
3. normal: arquivos ainda não indexados;
|
||||
4. baixa: reprocessamento por melhoria de modelo ou análise opcional.
|
||||
|
||||
Para evitar starvation, trabalhos de baixa prioridade recebem um aumento gradual de prioridade conforme envelhecem. Um arquivo grande não deve bloquear a fila inteira: o scheduler o divide em lotes e alterna com trabalhos menores.
|
||||
|
||||
## Configuração operacional proposta
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True)
|
||||
class ConfiguracaoDaBiblioteca:
|
||||
extensoes: tuple[str, ...] = (".mp4", ".mov", ".mxf", ".mkv", ".avi")
|
||||
recursiva: bool = True
|
||||
intervalo_da_varredura_em_segundos: int = 900
|
||||
estabilidade_do_arquivo_em_segundos: int = 30
|
||||
frequencia_de_triagem_em_fps: float = 0.25
|
||||
frequencia_de_cena_em_fps: float = 1.0
|
||||
tamanho_do_lote_de_frames: int = 32
|
||||
concorrencia: int = 1
|
||||
limite_de_cache_em_gb: float = 10.0
|
||||
permitir_provider_remoto: bool = False
|
||||
perfil_de_recursos: str = "economico"
|
||||
```
|
||||
|
||||
Os defaults favorecem responsividade e privacidade. A configuração não deve expor detalhes de cada biblioteca de visão; deve selecionar perfis e permitir ajustes apenas onde houver evidência de necessidade.
|
||||
|
||||
## Fases de evolução
|
||||
|
||||
### Fase 1 — catálogo confiável
|
||||
|
||||
SQLite, descoberta periódica, identidade por fingerprint, metadados, fila persistida, checkpoints, análise visual em baixa frequência, transcrição local e busca textual temporal.
|
||||
|
||||
### Fase 2 — recuperação semântica
|
||||
|
||||
Embeddings para segmentos e transcrições, busca híbrida, reranking e consultas por conceitos não presentes literalmente no texto. O embedding deve ser versionado e reconstruível; não deve ser a única representação do conhecimento.
|
||||
|
||||
### Fase 3 — integração editorial
|
||||
|
||||
Busca a partir do contexto da timeline, abertura no trecho encontrado, marcadores de revisão e propostas de stringout. Qualquer mutação na timeline continua exigindo uma etapa explícita de revisão e autorização.
|
||||
Reference in New Issue
Block a user