feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
This commit is contained in:
@@ -0,0 +1,643 @@
|
||||
Para começar, eu não criaria todas as classes de análise imediatamente. O ideal é definir primeiro as **classes básicas e estruturais do módulo `scanner`**. Elas formarão a base sobre a qual as análises específicas serão construídas.
|
||||
|
||||
Eu dividiria em quatro grupos:
|
||||
|
||||
1. Coordenação do processo.
|
||||
2. Representação dos dados.
|
||||
3. Contratos das análises.
|
||||
4. Controle de execução e resultados.
|
||||
|
||||
# Estrutura básica inicial
|
||||
|
||||
```text
|
||||
scanner/
|
||||
├── __init__.py
|
||||
│
|
||||
├── coordenacao/
|
||||
│ ├── __init__.py
|
||||
│ ├── analisador_de_timeline.py
|
||||
│ ├── pipeline_do_scanner.py
|
||||
│ └── contexto_de_analise.py
|
||||
│
|
||||
├── contratos/
|
||||
│ ├── __init__.py
|
||||
│ └── analisador.py
|
||||
│
|
||||
├── modelos/
|
||||
│ ├── __init__.py
|
||||
│ ├── resultado_da_analise.py
|
||||
│ ├── status_da_analise.py
|
||||
│ └── erro_de_analise.py
|
||||
│
|
||||
└── configuracao/
|
||||
├── __init__.py
|
||||
└── configuracao_do_scanner.py
|
||||
```
|
||||
|
||||
A seguir está o papel detalhado de cada classe.
|
||||
|
||||
---
|
||||
|
||||
# 1. `AnalisadorDeTimeline`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/coordenacao/analisador_de_timeline.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
É a **classe de entrada do scanner**.
|
||||
|
||||
Ela representa o processo completo de análise de uma timeline. O restante do sistema deverá utilizar essa classe para iniciar uma análise, sem precisar conhecer todas as etapas internas.
|
||||
|
||||
## O que deve fazer
|
||||
|
||||
* Receber a timeline que será analisada.
|
||||
* Receber as configurações do scanner.
|
||||
* Receber ou montar o pipeline.
|
||||
* Criar o contexto inicial.
|
||||
* Iniciar a execução do pipeline.
|
||||
* Acompanhar o status geral da análise.
|
||||
* Retornar o resultado final.
|
||||
* Permitir informar progresso.
|
||||
* Permitir cancelamento futuro.
|
||||
* Tratar falhas gerais do processo.
|
||||
* Registrar informações gerais da execução.
|
||||
* Identificar se a análise já foi realizada anteriormente.
|
||||
* Permitir retomar uma análise interrompida, quando essa funcionalidade existir.
|
||||
|
||||
## O que não deve fazer
|
||||
|
||||
* Extrair áudio diretamente.
|
||||
* Executar transcrição.
|
||||
* Detectar cenas.
|
||||
* Analisar imagens.
|
||||
* Detectar retakes.
|
||||
* Implementar chamadas para OpenCV, FFmpeg, Whisper ou APIs.
|
||||
* Decidir quais trechos serão cortados.
|
||||
* Alterar a timeline.
|
||||
|
||||
## Exemplo conceitual
|
||||
|
||||
```python
|
||||
class AnalisadorDeTimeline:
|
||||
"""Ponto de entrada para a análise completa de uma timeline."""
|
||||
|
||||
def __init__(self, pipeline, configuracao):
|
||||
self.pipeline = pipeline
|
||||
self.configuracao = configuracao
|
||||
|
||||
def analisar(self, timeline):
|
||||
"""Inicia a análise da timeline e retorna o resultado."""
|
||||
contexto = ContextoDeAnalise(
|
||||
timeline=timeline,
|
||||
configuracao=self.configuracao
|
||||
)
|
||||
|
||||
return self.pipeline.executar(contexto)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. `PipelineDoScanner`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/coordenacao/pipeline_do_scanner.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
É a classe responsável por **controlar a ordem de execução das análises**.
|
||||
|
||||
Ela não sabe como cada análise funciona. Apenas sabe quais análises precisam ser executadas e em qual sequência.
|
||||
|
||||
## O que deve fazer
|
||||
|
||||
* Receber uma lista de análises.
|
||||
* Executar as análises na ordem configurada.
|
||||
* Entregar o contexto para cada análise.
|
||||
* Atualizar o status da execução.
|
||||
* Registrar a análise atualmente em execução.
|
||||
* Registrar análises concluídas.
|
||||
* Identificar falhas.
|
||||
* Permitir interromper o processo.
|
||||
* Permitir executar somente determinadas análises.
|
||||
* Permitir ignorar análises opcionais.
|
||||
* Permitir futuramente executar análises independentes em paralelo.
|
||||
* Garantir que uma análise só seja executada quando suas dependências estiverem disponíveis.
|
||||
* Retornar o contexto atualizado.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
class PipelineDoScanner:
|
||||
"""Executa as análises do scanner em uma ordem definida."""
|
||||
|
||||
def __init__(self, analises):
|
||||
self.analises = analises
|
||||
|
||||
def executar(self, contexto):
|
||||
"""Executa todas as análises configuradas."""
|
||||
for analise in self.analises:
|
||||
contexto = analise.executar(contexto)
|
||||
|
||||
return contexto
|
||||
```
|
||||
|
||||
## O que não deve fazer
|
||||
|
||||
* Conhecer detalhes dos providers.
|
||||
* Saber como o áudio é extraído.
|
||||
* Saber como o Whisper funciona.
|
||||
* Implementar algoritmos de detecção de cenas.
|
||||
* Tomar decisões de edição.
|
||||
* Manipular diretamente a timeline.
|
||||
|
||||
---
|
||||
|
||||
# 3. `ContextoDeAnalise`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/coordenacao/contexto_de_analise.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
É o objeto que **transporta os dados entre as análises**.
|
||||
|
||||
Cada análise recebe o mesmo contexto, lê os dados de que precisa e adiciona seus próprios resultados.
|
||||
|
||||
Ele evita que cada classe precise receber dezenas de parâmetros separados.
|
||||
|
||||
## O que deve armazenar
|
||||
|
||||
### Dados da origem
|
||||
|
||||
* Timeline analisada.
|
||||
* Identificador da análise.
|
||||
* Data e hora de início.
|
||||
* Configuração utilizada.
|
||||
* Versão do scanner.
|
||||
* Identificador do projeto ou sequência.
|
||||
|
||||
### Dados descobertos
|
||||
|
||||
* Sequências.
|
||||
* Faixas de vídeo.
|
||||
* Faixas de áudio.
|
||||
* Clipes.
|
||||
* Arquivos relacionados.
|
||||
* Relações entre áudio e vídeo.
|
||||
* Elementos desativados.
|
||||
* Elementos offline.
|
||||
|
||||
### Dados técnicos
|
||||
|
||||
* Metadados dos arquivos.
|
||||
* Duração.
|
||||
* Resolução.
|
||||
* Taxa de quadros.
|
||||
* Codecs.
|
||||
* Timecodes.
|
||||
* Informações de áudio.
|
||||
|
||||
### Dados processados
|
||||
|
||||
* Áudios extraídos.
|
||||
* Quadros extraídos.
|
||||
* Transcrições.
|
||||
* Características visuais.
|
||||
* Características de áudio.
|
||||
* Cenas detectadas.
|
||||
* Eventos detectados.
|
||||
* Possíveis retakes.
|
||||
|
||||
### Controle da execução
|
||||
|
||||
* Status atual.
|
||||
* Análise em execução.
|
||||
* Análises concluídas.
|
||||
* Erros.
|
||||
* Avisos.
|
||||
* Percentual de progresso.
|
||||
* Tempo de execução.
|
||||
|
||||
## O que não deve fazer
|
||||
|
||||
* Executar análises.
|
||||
* Chamar providers.
|
||||
* Implementar algoritmos.
|
||||
* Decidir cortes.
|
||||
* Alterar a timeline.
|
||||
* Fazer persistência diretamente.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
class ContextoDeAnalise:
|
||||
"""Armazena os dados compartilhados durante a análise."""
|
||||
|
||||
def __init__(self, timeline, configuracao):
|
||||
self.timeline = timeline
|
||||
self.configuracao = configuracao
|
||||
|
||||
self.clipes = []
|
||||
self.arquivos = []
|
||||
self.metadados = {}
|
||||
self.audios = {}
|
||||
self.quadros = {}
|
||||
self.transcricoes = {}
|
||||
self.cenas = []
|
||||
self.eventos = []
|
||||
self.retakes = []
|
||||
|
||||
self.status = "nao_iniciada"
|
||||
self.analise_atual = None
|
||||
self.analises_concluidas = []
|
||||
self.erros = []
|
||||
self.avisos = []
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 4. `Analisador`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/contratos/analisador.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
É o **contrato comum das classes de análise**.
|
||||
|
||||
Ele define que toda análise precisa possuir um método padronizado, como `executar()`.
|
||||
|
||||
Não é uma análise concreta. É uma classe-base ou interface.
|
||||
|
||||
## O que deve definir
|
||||
|
||||
* Método `executar(contexto)`.
|
||||
* Identificação da análise.
|
||||
* Nome amigável.
|
||||
* Dependências, quando necessário.
|
||||
* Indicação se a análise é obrigatória ou opcional.
|
||||
* Validação básica do contexto.
|
||||
* Possibilidade de informar progresso.
|
||||
* Possibilidade de verificar cancelamento.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class Analisador(ABC):
|
||||
"""Define o contrato comum das análises do scanner."""
|
||||
|
||||
nome = "analisador"
|
||||
|
||||
@abstractmethod
|
||||
def executar(self, contexto):
|
||||
"""Executa a análise sobre o contexto."""
|
||||
raise NotImplementedError
|
||||
|
||||
def validar_contexto(self, contexto):
|
||||
"""Valida se o contexto possui os dados necessários."""
|
||||
return True
|
||||
```
|
||||
|
||||
As classes específicas poderão seguir esse contrato:
|
||||
|
||||
```python
|
||||
class DeteccaoDeCenas(Analisador):
|
||||
"""Detecta cenas utilizando um provider especializado."""
|
||||
|
||||
nome = "deteccao_de_cenas"
|
||||
|
||||
def executar(self, contexto):
|
||||
"""Executa a detecção de cenas."""
|
||||
return contexto
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 5. `ResultadoDaAnalise`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/modelos/resultado_da_analise.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
Representa o **resultado produzido por uma análise individual**.
|
||||
|
||||
Ele será útil para que o pipeline saiba se uma análise terminou corretamente, quais dados produziu e se houve problemas.
|
||||
|
||||
## O que deve armazenar
|
||||
|
||||
* Nome da análise.
|
||||
* Status.
|
||||
* Data e hora de início.
|
||||
* Data e hora de término.
|
||||
* Duração.
|
||||
* Quantidade de itens processados.
|
||||
* Quantidade de resultados produzidos.
|
||||
* Avisos.
|
||||
* Erros.
|
||||
* Dados resumidos.
|
||||
* Identificador da execução.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
class ResultadoDaAnalise:
|
||||
"""Representa o resultado de uma análise individual."""
|
||||
|
||||
def __init__(self, nome, status="concluida"):
|
||||
self.nome = nome
|
||||
self.status = status
|
||||
self.inicio = None
|
||||
self.fim = None
|
||||
self.duracao = None
|
||||
self.itens_processados = 0
|
||||
self.resultados_produzidos = 0
|
||||
self.avisos = []
|
||||
self.erros = []
|
||||
self.dados = {}
|
||||
```
|
||||
|
||||
## Exemplo de resultado
|
||||
|
||||
```json
|
||||
{
|
||||
"nome": "deteccao_de_cenas",
|
||||
"status": "concluida",
|
||||
"itens_processados": 48,
|
||||
"resultados_produzidos": 17,
|
||||
"duracao": 12.4,
|
||||
"avisos": [],
|
||||
"erros": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 6. `StatusDaAnalise`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/modelos/status_da_analise.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
Centraliza os estados possíveis de uma análise.
|
||||
|
||||
Isso evita que cada classe utilize textos diferentes para representar o mesmo estado.
|
||||
|
||||
## Estados possíveis
|
||||
|
||||
```text
|
||||
NAO_INICIADA
|
||||
AGUARDANDO
|
||||
EM_EXECUCAO
|
||||
CONCLUIDA
|
||||
CONCLUIDA_COM_AVISOS
|
||||
FALHOU
|
||||
CANCELADA
|
||||
IGNORADA
|
||||
```
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class StatusDaAnalise(Enum):
|
||||
"""Define os estados possíveis de uma análise."""
|
||||
|
||||
NAO_INICIADA = "nao_iniciada"
|
||||
AGUARDANDO = "aguardando"
|
||||
EM_EXECUCAO = "em_execucao"
|
||||
CONCLUIDA = "concluida"
|
||||
CONCLUIDA_COM_AVISOS = "concluida_com_avisos"
|
||||
FALHOU = "falhou"
|
||||
CANCELADA = "cancelada"
|
||||
IGNORADA = "ignorada"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. `ErroDeAnalise`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/modelos/erro_de_analise.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
Representa erros ocorridos durante o processo de análise de maneira estruturada.
|
||||
|
||||
Em vez de armazenar apenas uma mensagem solta, o sistema poderá saber exatamente onde e por que o erro aconteceu.
|
||||
|
||||
## O que deve armazenar
|
||||
|
||||
* Nome da análise.
|
||||
* Código do erro.
|
||||
* Mensagem.
|
||||
* Detalhes técnicos.
|
||||
* Arquivo relacionado.
|
||||
* Clipe relacionado.
|
||||
* Provider envolvido.
|
||||
* Data e hora.
|
||||
* Indicação se o erro interrompe o pipeline.
|
||||
* Sugestão de recuperação, quando possível.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
class ErroDeAnalise:
|
||||
"""Representa um erro ocorrido durante uma análise."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mensagem,
|
||||
codigo=None,
|
||||
nome_da_analise=None,
|
||||
arquivo=None,
|
||||
interrompe_pipeline=False
|
||||
):
|
||||
self.mensagem = mensagem
|
||||
self.codigo = codigo
|
||||
self.nome_da_analise = nome_da_analise
|
||||
self.arquivo = arquivo
|
||||
self.interrompe_pipeline = interrompe_pipeline
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 8. `ConfiguracaoDoScanner`
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
scanner/configuracao/configuracao_do_scanner.py
|
||||
```
|
||||
|
||||
## Papel principal
|
||||
|
||||
Armazena as configurações que controlam como o scanner deverá funcionar.
|
||||
|
||||
Ela não deve conter regras específicas de um provider. As configurações dos providers podem ficar em seus próprios módulos.
|
||||
|
||||
## O que deve controlar
|
||||
|
||||
* Quais análises serão executadas.
|
||||
* Ordem das análises.
|
||||
* Análises obrigatórias.
|
||||
* Análises opcionais.
|
||||
* Uso de cache.
|
||||
* Uso de arquivos temporários.
|
||||
* Diretório de trabalho.
|
||||
* Nível de detalhamento.
|
||||
* Quantidade de quadros extraídos.
|
||||
* Intervalo de amostragem.
|
||||
* Limite de duração.
|
||||
* Execução paralela.
|
||||
* Comportamento diante de erros.
|
||||
* Persistência automática.
|
||||
* Retomada de análise.
|
||||
* Nível de logging.
|
||||
|
||||
## Exemplo
|
||||
|
||||
```python
|
||||
class ConfiguracaoDoScanner:
|
||||
"""Define as configurações gerais do scanner."""
|
||||
|
||||
def __init__(self):
|
||||
self.executar_transcricao = True
|
||||
self.executar_analise_visual = True
|
||||
self.executar_deteccao_de_cenas = True
|
||||
self.executar_deteccao_de_retakes = True
|
||||
self.usar_cache = True
|
||||
self.continuar_em_caso_de_erro = True
|
||||
self.salvar_resultados_automaticamente = True
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Como essas classes se relacionam
|
||||
|
||||
```text
|
||||
AnalisadorDeTimeline
|
||||
↓
|
||||
PipelineDoScanner
|
||||
↓
|
||||
Analisador
|
||||
↓
|
||||
Classes específicas de análise
|
||||
↓
|
||||
ContextoDeAnalise
|
||||
↓
|
||||
ResultadoDaAnalise
|
||||
```
|
||||
|
||||
A configuração controla o comportamento:
|
||||
|
||||
```text
|
||||
ConfiguracaoDoScanner
|
||||
↓
|
||||
AnalisadorDeTimeline
|
||||
↓
|
||||
PipelineDoScanner
|
||||
```
|
||||
|
||||
E os erros são registrados durante a execução:
|
||||
|
||||
```text
|
||||
Classe de análise
|
||||
↓
|
||||
ErroDeAnalise
|
||||
↓
|
||||
ContextoDeAnalise
|
||||
↓
|
||||
ResultadoDaAnalise
|
||||
```
|
||||
|
||||
# Fluxo de execução
|
||||
|
||||
```text
|
||||
1. AnalisadorDeTimeline recebe a timeline.
|
||||
2. Cria o ContextoDeAnalise.
|
||||
3. Carrega a ConfiguracaoDoScanner.
|
||||
4. Monta o PipelineDoScanner.
|
||||
5. O pipeline executa cada Analisador.
|
||||
6. Cada análise lê e atualiza o contexto.
|
||||
7. Cada análise produz um ResultadoDaAnalise.
|
||||
8. Erros e avisos são registrados.
|
||||
9. O contexto final é retornado.
|
||||
10. O resultado poderá ser salvo pelo módulo de persistência.
|
||||
```
|
||||
|
||||
# Classes que eu criaria primeiro
|
||||
|
||||
Para a primeira implementação, começaria somente com estas:
|
||||
|
||||
```text
|
||||
scanner/
|
||||
├── coordenacao/
|
||||
│ ├── analisador_de_timeline.py
|
||||
│ ├── pipeline_do_scanner.py
|
||||
│ └── contexto_de_analise.py
|
||||
│
|
||||
├── contratos/
|
||||
│ └── analisador.py
|
||||
│
|
||||
└── modelos/
|
||||
├── resultado_da_analise.py
|
||||
└── status_da_analise.py
|
||||
```
|
||||
|
||||
Depois acrescentaria:
|
||||
|
||||
```text
|
||||
ErroDeAnalise
|
||||
ConfiguracaoDoScanner
|
||||
```
|
||||
|
||||
E somente então começaria a implementar as análises concretas:
|
||||
|
||||
```text
|
||||
DescobertaDaTimeline
|
||||
DescobertaDeClipes
|
||||
DescobertaDeArquivos
|
||||
ExtracaoDeMetadados
|
||||
ExtracaoDeAudio
|
||||
TranscricaoDeAudio
|
||||
ExtracaoDeQuadros
|
||||
AnaliseVisual
|
||||
AnaliseDeAudio
|
||||
DeteccaoDeCenas
|
||||
DeteccaoDeEventos
|
||||
DeteccaoDeRetakes
|
||||
PersistenciaDaAnalise
|
||||
```
|
||||
|
||||
A ideia central é:
|
||||
|
||||
> **As classes básicas não analisam o vídeo diretamente. Elas criam a estrutura que permite que todas as análises funcionem de forma organizada, substituível, testável e independente dos providers.**
|
||||
Reference in New Issue
Block a user