- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
38 KiB
A seguir está um documento-base completo para orientar o desenvolvimento do primeiro módulo funcional do sistema: leitura da timeline do Premiere por meio do MCP.
Ele foi estruturado para servir como especificação técnica, guia de implementação e referência para os próximos módulos.
Módulo de leitura da timeline do Premiere via MCP
1. Objetivo do módulo
O objetivo deste primeiro módulo é permitir que o sistema consiga:
- Conectar-se ao MCP responsável pela integração com o Premiere;
- Identificar se o Premiere está acessível;
- Consultar a sequência ativa;
- Ler as faixas de vídeo e áudio;
- Ler os clipes presentes na timeline;
- Obter as propriedades relevantes de cada clipe;
- Converter a resposta bruta do MCP para objetos internos do sistema;
- Validar os dados recebidos;
- Armazenar o resultado em um modelo de domínio;
- Disponibilizar essa informação para os próximos módulos do scanner.
Este módulo não deverá realizar cortes, mover clipes, excluir elementos ou tomar decisões de edição.
Ele terá somente a responsabilidade de ler e representar a timeline atual.
2. Princípio arquitetural
O módulo deverá seguir esta separação:
Premiere Pro
↓
MCP do Premiere
↓
ClienteMCP
↓
AcessoAoEditor
↓
ConversorDeTimeline
↓
Modelos do domínio
↓
DescobertaDaTimeline
↓
ContextoDeAnalise
Cada camada possui uma responsabilidade específica.
| Camada | Responsabilidade |
|---|---|
| MCP | Disponibilizar ferramentas para comunicação com o Premiere |
ClienteMCP |
Executar chamadas técnicas ao MCP |
AcessoAoEditor |
Expor operações compreensíveis de leitura |
ConversorDeTimeline |
Converter respostas externas em objetos internos |
| Domínio | Representar projeto, sequência, faixas e clipes |
DescobertaDaTimeline |
Orquestrar a descoberta da timeline |
ContextoDeAnalise |
Armazenar os dados obtidos pelo scanner |
A regra fundamental é:
Nenhuma classe do scanner deverá chamar diretamente uma ferramenta MCP pelo nome técnico.
Por exemplo, o scanner não deve fazer isto:
cliente_mcp.chamar(
"get_active_sequence",
{}
)
Ele deve fazer isto:
timeline = acesso_ao_editor.obter_timeline_ativa()
Assim, o scanner não fica dependente da implementação específica do MCP.
3. Escopo da primeira versão
A primeira versão deverá implementar somente a leitura.
Incluído
- Conexão com o MCP;
- Teste de conectividade;
- Leitura da sequência ativa;
- Leitura das faixas;
- Leitura dos clipes;
- Leitura dos dados básicos dos clipes;
- Conversão dos dados;
- Validação;
- Registro de erros;
- Retorno estruturado;
- Testes com dados simulados.
Não incluído inicialmente
- Corte de clipes;
- Exclusão de clipes;
- Movimentação de clipes;
- Aplicação de plano de edição;
- Transcrição;
- Análise visual;
- Detecção de cenas;
- Detecção de retakes;
- Análise de áudio;
- Decisão automática;
- Alteração da timeline;
- Execução de comandos destrutivos.
Essas funcionalidades serão adicionadas posteriormente.
4. Estrutura inicial de pastas
A estrutura inicial recomendada é:
projeto/
│
├── integracoes/
│ └── premiere/
│ ├── __init__.py
│ │
│ ├── cliente_mcp.py
│ ├── sessao_mcp.py
│ ├── erros_mcp.py
│ │
│ ├── leitura/
│ │ ├── __init__.py
│ │ ├── acesso_ao_editor.py
│ │ ├── acesso_a_timeline.py
│ │ └── acesso_a_clipes.py
│ │
│ ├── conversores/
│ │ ├── __init__.py
│ │ ├── conversor_de_timeline.py
│ │ ├── conversor_de_faixas.py
│ │ └── conversor_de_clipes.py
│ │
│ └── contratos/
│ ├── __init__.py
│ └── contrato_de_acesso_ao_editor.py
│
├── dominio/
│ ├── __init__.py
│ │
│ ├── entidades/
│ │ ├── projeto.py
│ │ ├── sequencia.py
│ │ ├── timeline.py
│ │ ├── faixa.py
│ │ └── clipe.py
│ │
│ └── objetos_de_valor/
│ ├── intervalo_de_tempo.py
│ ├── tipo_de_midia.py
│ └── identificador_de_midia.py
│
├── scanner/
│ ├── __init__.py
│ │
│ ├── coordenacao/
│ │ ├── analisador_de_timeline.py
│ │ ├── pipeline_do_scanner.py
│ │ └── contexto_de_analise.py
│ │
│ └── descoberta/
│ └── descoberta_da_timeline.py
│
├── configuracao/
│ └── configuracao_do_scanner.py
│
└── testes/
├── integracoes/
├── dominio/
└── scanner/
Essa é uma estrutura inicial. Ela poderá ser expandida quando o projeto crescer.
5. Classe ClienteMCP
Arquivo:
integracoes/premiere/cliente_mcp.py
Responsabilidade
A classe ClienteMCP será responsável exclusivamente pela comunicação técnica com o servidor MCP.
Ela deverá:
- Estabelecer conexão;
- Encerrar conexão;
- Executar chamadas;
- Enviar argumentos;
- Receber respostas;
- Controlar timeout;
- Detectar erros de comunicação;
- Registrar informações técnicas;
- Retornar respostas brutas.
Ela não deverá:
- Interpretar clipes;
- Criar objetos de domínio;
- Saber o que é uma cena;
- Saber o que é um retake;
- Decidir qual ferramenta deve ser usada para descobrir a timeline;
- Executar regras de negócio.
Interface conceitual
class ClienteMCP:
"""Responsável pela comunicação técnica com o servidor MCP."""
def conectar(self) -> None:
"""Estabelece conexão com o servidor MCP."""
def desconectar(self) -> None:
"""Encerra a conexão com o servidor MCP."""
def esta_conectado(self) -> bool:
"""Informa se existe uma conexão ativa."""
def chamar(
self,
nome_da_ferramenta: str,
argumentos: dict | None = None,
) -> dict:
"""Executa uma ferramenta MCP e retorna a resposta bruta."""
Exemplo de comportamento
cliente = ClienteMCP()
cliente.conectar()
resposta = cliente.chamar(
nome_da_ferramenta="get_active_sequence",
argumentos={},
)
cliente.desconectar()
O nome get_active_sequence é apenas ilustrativo. O nome real deverá ser descoberto a partir das ferramentas efetivamente disponíveis no MCP utilizado.
Regras
- Não colocar lógica de conversão nessa classe.
- Não colocar lógica de domínio nessa classe.
- Não colocar lógica de scanner nessa classe.
- Não criar métodos como
detectar_retake()ouobter_cenas(). - Não misturar leitura e escrita nessa primeira versão.
- Centralizar aqui o tratamento técnico de erros MCP.
6. Classe SessaoMCP
Arquivo:
integracoes/premiere/sessao_mcp.py
Responsabilidade
A classe SessaoMCP representará o estado da integração com o Premiere.
Ela poderá armazenar:
- Estado da conexão;
- Data da última conexão;
- Projeto identificado;
- Sequência ativa;
- Ferramentas disponíveis;
- Última chamada executada;
- Último erro ocorrido.
Interface conceitual
class SessaoMCP:
"""Representa o estado atual da comunicação com o Premiere."""
def __init__(self):
self.conectado = False
self.projeto_atual = None
self.sequencia_ativa = None
self.ultima_ferramenta_executada = None
self.ultimo_erro = None
Observação
Na primeira implementação, essa classe pode ser simples. Ela não precisa controlar toda a conexão sozinha.
Sua função é evitar que informações de estado fiquem espalhadas em várias classes.
7. Classe ErrosMCP
Arquivo:
integracoes/premiere/erros_mcp.py
Responsabilidade
Centralizar os erros relacionados à integração com o MCP.
Classes sugeridas
class ErroMCP(Exception):
"""Erro genérico relacionado à comunicação com o MCP."""
class ErroDeConexaoMCP(ErroMCP):
"""Erro ao conectar ou manter conexão com o MCP."""
class ErroDeFerramentaMCP(ErroMCP):
"""Erro ao executar uma ferramenta MCP."""
class ErroDeRespostaMCP(ErroMCP):
"""Erro quando a resposta do MCP é inválida ou incompleta."""
class FerramentaMCPNaoEncontrada(ErroMCP):
"""Erro quando a ferramenta solicitada não está disponível."""
Por que isso é importante?
Sem erros específicos, o sistema teria apenas:
raise Exception("Erro")
Com erros específicos, podemos distinguir:
- MCP indisponível;
- Ferramenta inexistente;
- Resposta inválida;
- Falta de sequência ativa;
- Permissão insuficiente;
- Timeout;
- Erro interno do Premiere.
Isso será importante para o scanner decidir se deve:
- Interromper a execução;
- Tentar novamente;
- Ignorar uma etapa;
- Registrar um aviso.
8. Classe AcessoAoEditor
Arquivo:
integracoes/premiere/leitura/acesso_ao_editor.py
Responsabilidade
A classe AcessoAoEditor será a principal porta de entrada para as operações de leitura do Premiere.
Ela deverá esconder os detalhes do MCP.
O restante do sistema deverá trabalhar com métodos de alto nível, como:
obter_timeline_ativa()
obter_sequencia_ativa()
obter_faixas()
obter_clipes()
obter_detalhes_do_clipe()
Interface conceitual
class AcessoAoEditor:
"""Fornece operações estruturadas de leitura do editor."""
def obter_timeline_ativa(self):
"""Obtém os dados da timeline ativa."""
def obter_sequencia_ativa(self):
"""Obtém os dados da sequência ativa."""
def obter_faixas(self):
"""Obtém as faixas da sequência ativa."""
def obter_clipes(self):
"""Obtém os clipes presentes na timeline."""
def obter_detalhes_do_clipe(
self,
identificador_do_clipe: str,
):
"""Obtém detalhes de um clipe específico."""
O que essa classe não deve fazer
Ela não deve:
- Converter diretamente para todos os objetos de domínio;
- Fazer transcrição;
- Detectar cenas;
- Executar cortes;
- Gerar plano de edição;
- Tomar decisões sobre retakes.
Sua responsabilidade é fornecer dados de leitura de maneira organizada.
9. Classe AcessoATimeline
Arquivo:
integracoes/premiere/leitura/acesso_a_timeline.py
Responsabilidade
Especializar o acesso à estrutura da timeline.
Ela poderá:
- Obter a sequência ativa;
- Obter informações gerais da timeline;
- Obter duração;
- Obter taxa de quadros;
- Obter resolução;
- Obter faixas;
- Obter elementos posicionados na timeline.
Interface conceitual
class AcessoATimeline:
"""Realiza operações de leitura relacionadas à timeline."""
def __init__(self, cliente_mcp):
self.cliente_mcp = cliente_mcp
def obter_timeline_ativa(self):
"""Consulta a timeline ativa no Premiere."""
def obter_sequencia_ativa(self):
"""Consulta a sequência ativa."""
def obter_faixas(self):
"""Consulta as faixas da sequência ativa."""
Exemplo conceitual
class AcessoATimeline:
"""Realiza consultas estruturadas da timeline."""
def __init__(self, cliente_mcp):
self.cliente_mcp = cliente_mcp
def obter_sequencia_ativa(self):
"""Obtém a sequência ativa por meio do MCP."""
resposta = self.cliente_mcp.chamar(
nome_da_ferramenta="get_active_sequence",
argumentos={},
)
return resposta
O nome da ferramenta deverá ser substituído pelo nome real fornecido pelo MCP.
10. Classe AcessoAClipes
Arquivo:
integracoes/premiere/leitura/acesso_a_clipes.py
Responsabilidade
Ler os clipes presentes na timeline.
Ela deverá obter informações como:
- Identificador;
- Nome;
- Nome do arquivo;
- Caminho do arquivo;
- Faixa;
- Início na timeline;
- Fim na timeline;
- Duração;
- Início utilizado no arquivo original;
- Fim utilizado no arquivo original;
- Tipo de mídia;
- Estado offline;
- Velocidade;
- Opacidade;
- Volume;
- Informações de vínculo;
- Informações de origem.
Interface conceitual
class AcessoAClipes:
"""Realiza operações de leitura dos clipes da timeline."""
def __init__(self, cliente_mcp):
self.cliente_mcp = cliente_mcp
def obter_clipes(self):
"""Obtém todos os clipes da timeline ativa."""
def obter_detalhes_do_clipe(
self,
identificador_do_clipe: str,
):
"""Obtém os detalhes de um clipe específico."""
Regra importante
A classe deverá retornar dados brutos ou estruturas intermediárias.
A conversão para objetos como Clipe deverá ser feita pelo conversor.
11. Classe ConversorDeTimeline
Arquivo:
integracoes/premiere/conversores/conversor_de_timeline.py
Responsabilidade
Converter a resposta do MCP para o modelo interno de Timeline.
O MCP pode retornar nomes e estruturas específicas. O sistema não deve depender diretamente delas.
Interface conceitual
class ConversorDeTimeline:
"""Converte dados brutos do Premiere em uma timeline do domínio."""
def converter(self, dados_brutos):
"""Converte os dados externos em uma entidade Timeline."""
Exemplo
class ConversorDeTimeline:
"""Converte uma resposta externa em uma Timeline interna."""
def converter(self, dados_brutos):
"""Cria uma Timeline a partir dos dados recebidos."""
timeline = Timeline(
identificador=dados_brutos["id"],
nome=dados_brutos["name"],
)
return timeline
Responsabilidades adicionais
- Normalizar nomes de campos;
- Converter tempos;
- Converter identificadores;
- Garantir tipos corretos;
- Aplicar valores padrão;
- Validar campos obrigatórios;
- Ignorar campos desconhecidos;
- Registrar campos ausentes.
12. Classe ConversorDeFaixas
Arquivo:
integracoes/premiere/conversores/conversor_de_faixas.py
Responsabilidade
Converter as faixas retornadas pelo MCP em objetos Faixa.
Informações esperadas
- Identificador;
- Nome;
- Tipo da faixa;
- Índice;
- Ordem;
- Clipes pertencentes;
- Estado de bloqueio;
- Estado de visibilidade;
- Estado de ativação.
Interface conceitual
class ConversorDeFaixas:
"""Converte faixas externas em entidades do domínio."""
def converter(self, dados_brutos):
"""Converte os dados de uma faixa."""
Tipos de faixa
O domínio deverá distinguir, pelo menos:
class TipoDeFaixa(Enum):
VIDEO = "video"
AUDIO = "audio"
DESCONHECIDA = "desconhecida"
O tipo real deverá ser ajustado conforme os dados retornados pelo MCP.
13. Classe ConversorDeClipes
Arquivo:
integracoes/premiere/conversores/conversor_de_clipes.py
Responsabilidade
Converter cada clipe externo em uma entidade Clipe.
Interface conceitual
class ConversorDeClipes:
"""Converte dados externos de clipes em entidades do domínio."""
def converter(self, dados_brutos):
"""Converte um clipe externo em um Clipe."""
Exemplo de campos normalizados
clipe = Clipe(
identificador="clip_001",
nome="Camera A",
arquivo="video_001.mov",
intervalo_na_timeline=IntervaloDeTempo(
inicio=10.0,
fim=25.0,
),
intervalo_na_origem=IntervaloDeTempo(
inicio=120.0,
fim=135.0,
),
identificador_da_faixa="video_1",
)
O modelo real deverá ser definido depois de observar uma resposta verdadeira do MCP.
14. Classe Projeto
Arquivo:
dominio/entidades/projeto.py
Responsabilidade
Representar o projeto de edição.
Campos iniciais
- Identificador;
- Nome;
- Caminho;
- Sequências;
- Data de leitura;
- Metadados adicionais.
Exemplo
class Projeto:
"""Representa um projeto de edição."""
def __init__(
self,
identificador,
nome,
caminho=None,
):
self.identificador = identificador
self.nome = nome
self.caminho = caminho
self.sequencias = []
15. Classe Sequencia
Arquivo:
dominio/entidades/sequencia.py
Responsabilidade
Representar uma sequência de edição.
Campos iniciais
- Identificador;
- Nome;
- Duração;
- Taxa de quadros;
- Resolução;
- Áudio;
- Faixas;
- Marcadores;
- Metadados.
Exemplo
class Sequencia:
"""Representa uma sequência de edição."""
def __init__(
self,
identificador,
nome,
duracao=None,
taxa_de_quadros=None,
):
self.identificador = identificador
self.nome = nome
self.duracao = duracao
self.taxa_de_quadros = taxa_de_quadros
self.faixas = []
16. Classe Timeline
Arquivo:
dominio/entidades/timeline.py
Responsabilidade
Representar a estrutura completa da timeline que será analisada.
Campos iniciais
- Identificador;
- Nome;
- Sequência;
- Faixas;
- Clipes;
- Duração;
- Taxa de quadros;
- Resolução;
- Metadados;
- Data da leitura;
- Origem dos dados.
Exemplo
class Timeline:
"""Representa uma timeline de edição."""
def __init__(
self,
identificador,
nome,
):
self.identificador = identificador
self.nome = nome
self.faixas = []
self.clipes = []
self.metadados = {}
Regras
A Timeline não deve:
- Consultar o MCP;
- Ler arquivos;
- Executar comandos;
- Fazer análise de áudio;
- Detectar retakes.
Ela apenas representa os dados.
17. Classe Faixa
Arquivo:
dominio/entidades/faixa.py
Responsabilidade
Representar uma faixa de vídeo ou áudio.
Campos iniciais
- Identificador;
- Nome;
- Tipo;
- Índice;
- Clipes;
- Estado de bloqueio;
- Estado de visibilidade;
- Estado de ativação.
Exemplo
class Faixa:
"""Representa uma faixa de vídeo ou áudio."""
def __init__(
self,
identificador,
nome,
tipo,
indice,
):
self.identificador = identificador
self.nome = nome
self.tipo = tipo
self.indice = indice
self.clipes = []
18. Classe Clipe
Arquivo:
dominio/entidades/clipe.py
Responsabilidade
Representar um clipe de mídia presente na timeline.
Campos iniciais
- Identificador;
- Nome;
- Arquivo de origem;
- Caminho do arquivo;
- Tipo de mídia;
- Faixa;
- Intervalo na timeline;
- Intervalo na origem;
- Duração;
- Estado offline;
- Velocidade;
- Opacidade;
- Volume;
- Dados de vínculo;
- Metadados;
- Informações de origem.
Exemplo
class Clipe:
"""Representa um clipe de mídia na timeline."""
def __init__(
self,
identificador,
nome,
intervalo_na_timeline,
intervalo_na_origem=None,
arquivo=None,
identificador_da_faixa=None,
):
self.identificador = identificador
self.nome = nome
self.intervalo_na_timeline = intervalo_na_timeline
self.intervalo_na_origem = intervalo_na_origem
self.arquivo = arquivo
self.identificador_da_faixa = identificador_da_faixa
self.metadados = {}
19. Classe IntervaloDeTempo
Arquivo:
dominio/objetos_de_valor/intervalo_de_tempo.py
Responsabilidade
Representar um intervalo temporal válido.
Ele será utilizado para:
- Posição de clipes;
- Duração;
- Trechos de áudio;
- Segmentos de transcrição;
- Cenas;
- Retakes;
- Operações de corte.
Exemplo
class IntervaloDeTempo:
"""Representa um intervalo temporal."""
def __init__(self, inicio, fim):
if inicio < 0:
raise ValueError(
"O início não pode ser negativo."
)
if fim < inicio:
raise ValueError(
"O fim não pode ser anterior ao início."
)
self.inicio = inicio
self.fim = fim
@property
def duracao(self):
"""Retorna a duração do intervalo."""
return self.fim - self.inicio
Métodos futuros
def contem(self, instante):
"""Verifica se um instante está dentro do intervalo."""
def sobrepoe(self, outro):
"""Verifica se dois intervalos se sobrepõem."""
def intersecao(self, outro):
"""Retorna a interseção entre dois intervalos."""
20. Contrato ContratoDeAcessoAoEditor
Arquivo:
integracoes/premiere/contratos/contrato_de_acesso_ao_editor.py
Responsabilidade
Definir o contrato que qualquer integração de editor deverá cumprir.
Isso permitirá futuramente utilizar:
- Premiere;
- OpenCut;
- DaVinci Resolve;
- Outro editor;
- Simulador para testes.
Exemplo
from abc import ABC, abstractmethod
class ContratoDeAcessoAoEditor(ABC):
"""Define operações mínimas de leitura de um editor."""
@abstractmethod
def obter_timeline_ativa(self):
"""Obtém a timeline ativa."""
raise NotImplementedError
@abstractmethod
def obter_clipes(self):
"""Obtém os clipes da timeline."""
raise NotImplementedError
@abstractmethod
def obter_faixas(self):
"""Obtém as faixas da timeline."""
raise NotImplementedError
Benefício
A classe DescobertaDaTimeline poderá depender desse contrato:
class DescobertaDaTimeline:
"""Descobre a timeline por meio de uma integração de editor."""
def __init__(self, acesso_ao_editor):
self.acesso_ao_editor = acesso_ao_editor
Assim, ela não saberá se os dados vieram do Premiere ou de um simulador.
21. Classe DescobertaDaTimeline
Arquivo:
scanner/descoberta/descoberta_da_timeline.py
Responsabilidade
Orquestrar a descoberta da timeline.
Ela deverá:
- Solicitar a timeline ao acesso do editor;
- Receber os dados externos;
- Converter os dados;
- Validar o resultado;
- Armazenar a timeline no contexto;
- Retornar o contexto atualizado.
Ela não deverá
- Chamar diretamente o MCP;
- Saber o nome das ferramentas MCP;
- Fazer transcrição;
- Fazer análise visual;
- Detectar retakes;
- Aplicar cortes;
- Gerar plano de edição.
Exemplo
class DescobertaDaTimeline:
"""Descobre a estrutura da timeline do editor."""
def __init__(
self,
acesso_ao_editor,
conversor_de_timeline,
):
self.acesso_ao_editor = acesso_ao_editor
self.conversor_de_timeline = conversor_de_timeline
def executar(self, contexto):
"""Obtém, converte e armazena a timeline."""
dados_brutos = (
self.acesso_ao_editor.obter_timeline_ativa()
)
timeline = (
self.conversor_de_timeline.converter(
dados_brutos
)
)
contexto.timeline = timeline
return contexto
22. Classe ContextoDeAnalise
Arquivo:
scanner/coordenacao/contexto_de_analise.py
Responsabilidade
Transportar os dados durante o processo de análise.
Ele deverá armazenar:
- Timeline;
- Projeto;
- Sequência;
- Clipes;
- Faixas;
- Arquivos;
- Metadados;
- Áudios;
- Transcrições;
- Cenas;
- Eventos;
- Retakes;
- Avisos;
- Erros;
- Status;
- Informações de execução.
Exemplo
class ContextoDeAnalise:
"""Armazena os dados produzidos durante a análise."""
def __init__(self):
self.projeto = None
self.timeline = None
self.clipes = []
self.faixas = []
self.metadados = {}
self.avisos = []
self.erros = []
Regra
O contexto não deve executar análises.
Ele apenas transporta e armazena informações.
23. Classe PipelineDoScanner
Arquivo:
scanner/coordenacao/pipeline_do_scanner.py
Responsabilidade
Executar as etapas de análise na ordem definida.
Na primeira versão, o pipeline poderá conter apenas:
DescobertaDaTimeline
Posteriormente, serão adicionadas:
DescobertaDeClipes
DescobertaDeArquivos
ExtracaoDeMetadados
ExtracaoDeAudio
TranscricaoDeAudio
AnaliseVisual
DeteccaoDeCenas
DeteccaoDeRetakes
Exemplo
class PipelineDoScanner:
"""Coordena a execução das etapas do scanner."""
def __init__(self, etapas):
self.etapas = etapas
def executar(self, contexto):
"""Executa todas as etapas na ordem definida."""
for etapa in self.etapas:
contexto = etapa.executar(contexto)
return contexto
Regra
O pipeline não deve:
- Conhecer detalhes do MCP;
- Conhecer nomes de ferramentas externas;
- Implementar transcrição;
- Implementar análise visual;
- Tomar decisões de edição.
Ele apenas coordena as etapas.
24. Classe AnalisadorDeTimeline
Arquivo:
scanner/coordenacao/analisador_de_timeline.py
Responsabilidade
Ser o ponto de entrada do processo de análise.
Ela deverá:
- Receber a configuração;
- Criar o contexto;
- Iniciar o pipeline;
- Retornar o resultado.
Exemplo
class AnalisadorDeTimeline:
"""Coordena o processo completo de análise da timeline."""
def __init__(self, pipeline):
self.pipeline = pipeline
def analisar(self):
"""Executa o processo de análise."""
contexto = ContextoDeAnalise()
return self.pipeline.executar(contexto)
Regra
Essa classe não deverá implementar as análises diretamente.
Ela apenas inicia o processo.
25. Fluxo completo da primeira versão
O fluxo deverá ser:
AnalisadorDeTimeline
↓
Cria ContextoDeAnalise
↓
PipelineDoScanner
↓
DescobertaDaTimeline
↓
AcessoAoEditor
↓
AcessoATimeline
↓
ClienteMCP
↓
MCP do Premiere
↓
Resposta bruta
↓
ConversorDeTimeline
↓
Timeline do domínio
↓
ContextoDeAnalise
↓
Resultado final
26. Exemplo de montagem dos componentes
A composição inicial poderá ser semelhante a:
cliente_mcp = ClienteMCP()
acesso_a_timeline = AcessoATimeline(
cliente_mcp=cliente_mcp,
)
acesso_ao_editor = AcessoAoEditor(
acesso_a_timeline=acesso_a_timeline,
)
conversor_de_timeline = ConversorDeTimeline()
descoberta_da_timeline = DescobertaDaTimeline(
acesso_ao_editor=acesso_ao_editor,
conversor_de_timeline=conversor_de_timeline,
)
pipeline = PipelineDoScanner(
etapas=[
descoberta_da_timeline,
],
)
analisador = AnalisadorDeTimeline(
pipeline=pipeline,
)
resultado = analisador.analisar()
A forma exata dependerá da implementação real do cliente MCP.
27. Primeira etapa prática: descobrir as ferramentas do MCP
Antes de escrever a integração definitiva, será necessário identificar exatamente:
- Como o MCP é iniciado;
- Como o cliente se conecta;
- Quais ferramentas estão disponíveis;
- Como consultar a sequência ativa;
- Como consultar as faixas;
- Como consultar os clipes;
- Como obter detalhes de um clipe;
- Qual é o formato de resposta;
- Como os tempos são representados;
- Como os identificadores são representados;
- Como erros são retornados;
- Se o MCP permite chamadas encadeadas;
- Se existe necessidade de manter sessão;
- Se as respostas são síncronas ou assíncronas.
Não se deve inventar os nomes das ferramentas.
Os nomes usados no código deverão ser baseados na implementação real do MCP disponível no ambiente.
28. Estratégia para descobrir a API real
O desenvolvimento deverá seguir esta ordem:
Passo 1 — Verificar conexão
Criar um teste mínimo que confirme:
O cliente consegue se conectar?
Passo 2 — Listar ferramentas
Obter a lista de ferramentas disponíveis no MCP.
Registrar:
- Nome;
- Descrição;
- Argumentos;
- Tipos;
- Retorno;
- Erros possíveis.
Passo 3 — Executar uma consulta simples
Por exemplo:
Obter informações do projeto atual
Passo 4 — Consultar a sequência ativa
Identificar:
- Nome;
- ID;
- Duração;
- FPS;
- Resolução;
- Número de faixas.
Passo 5 — Consultar as faixas
Identificar:
- Faixas de vídeo;
- Faixas de áudio;
- Ordem;
- Índices;
- IDs.
Passo 6 — Consultar os clipes
Identificar todos os campos retornados.
Passo 7 — Salvar uma resposta real
As respostas reais deverão ser armazenadas em arquivos de teste, por exemplo:
testes/fixtures/
├── projeto.json
├── sequencia.json
├── faixas.json
└── clipes.json
Esses arquivos serão usados para testar os conversores sem precisar abrir o Premiere em todos os testes.
29. Modelo de resposta bruta
O formato abaixo é apenas um exemplo conceitual:
{
"id": "sequence_001",
"name": "Sequência principal",
"duration": 120.5,
"frame_rate": 29.97,
"width": 1920,
"height": 1080,
"video_tracks": [
{
"id": "video_1",
"name": "V1",
"index": 1,
"clips": [
{
"id": "clip_001",
"name": "Camera A",
"source_file": "/videos/camera_a.mov",
"timeline_start": 0.0,
"timeline_end": 12.5,
"source_start": 35.2,
"source_end": 47.7
}
]
}
],
"audio_tracks": []
}
Esse formato não deve ser considerado definitivo.
O formato definitivo deverá ser obtido diretamente do MCP real.
30. Validação dos dados recebidos
Antes de converter os dados, o sistema deverá verificar:
Timeline
- Existe identificador?
- Existe nome?
- A duração é válida?
- A taxa de quadros é válida?
- A resolução é válida?
Faixas
- Existe identificador?
- Existe tipo?
- Existe índice?
- A lista de clipes é válida?
Clipes
- Existe identificador?
- Existe posição inicial?
- Existe posição final?
- O fim é maior que o início?
- O arquivo de origem foi informado?
- O clipe está offline?
- A faixa existe?
Erros de validação
A validação não deve simplesmente gerar um erro genérico.
Deverá registrar informações como:
Campo ausente: timeline.id
Clipe inválido: clip_004
Intervalo inválido: início maior que fim
Faixa desconhecida: audio_99
Arquivo de origem não encontrado
31. Tratamento de timeline vazia
O sistema deverá tratar corretamente situações como:
- Nenhuma sequência ativa;
- Sequência sem clipes;
- Sequência sem faixas;
- Timeline vazia;
- Projeto recém-criado;
- Projeto com mídia offline.
Essas situações não devem necessariamente ser consideradas falhas técnicas.
Por exemplo:
Sequência encontrada, mas sem clipes.
Isso pode ser um resultado válido.
O sistema deverá diferenciar:
Falha de comunicação
de:
Timeline válida, porém vazia
32. Tratamento de mídia offline
Um clipe offline não deve impedir a leitura completa da timeline.
O objeto Clipe deverá conter algo como:
clipe.offline = True
O sistema deverá manter:
- ID do clipe;
- Nome;
- Posição na timeline;
- Duração;
- Faixa;
- Caminho informado;
- Estado offline.
A análise do arquivo físico poderá ser realizada posteriormente pelo módulo de descoberta de arquivos.
33. Separação entre posição na timeline e posição na origem
Esse é um ponto fundamental.
Um clipe possui pelo menos dois intervalos:
Intervalo na timeline
Onde o clipe está colocado na sequência.
Início: 30 segundos
Fim: 45 segundos
Intervalo na mídia original
Qual trecho do arquivo de origem está sendo utilizado.
Início: 120 segundos
Fim: 135 segundos
Esses intervalos não devem ser misturados.
O modelo deverá representar ambos:
clipe.intervalo_na_timeline
clipe.intervalo_na_origem
Essa distinção será essencial para:
- Detectar retakes;
- Encontrar repetições;
- Comparar trechos;
- Reconstruir a origem;
- Criar cortes;
- Validar operações;
- Relacionar clipes com arquivos originais.
34. Identificadores
O sistema deverá preservar os identificadores externos, mas também poderá criar identificadores internos.
Exemplo:
clipe.identificador_externo
clipe.identificador_interno
O identificador externo será usado para conversar novamente com o Premiere.
O identificador interno será usado pelo domínio e pelos módulos internos.
Não se deve presumir que o nome do clipe seja único.
O nome:
Camera A
pode aparecer várias vezes.
A identificação deverá utilizar IDs sempre que possível.
35. Registro de logs
O módulo deverá registrar logs em pontos importantes:
Conexão
Conectando ao MCP do Premiere
Conexão estabelecida
Conexão encerrada
Leitura
Consultando sequência ativa
Consultando faixas
Consultando clipes
Conversão
Convertendo timeline
Convertendo faixa video_1
Convertendo clipe clip_001
Erros
Falha ao consultar clipes
Resposta MCP inválida
Campo obrigatório ausente
Os logs não devem registrar informações sensíveis desnecessárias.
36. Testes necessários
Testes do ClienteMCP
- Conecta corretamente;
- Desconecta corretamente;
- Executa uma chamada;
- Trata timeout;
- Trata ferramenta inexistente;
- Trata resposta inválida;
- Trata conexão indisponível.
Testes do AcessoATimeline
- Obtém sequência ativa;
- Obtém faixas;
- Obtém timeline vazia;
- Trata ausência de sequência;
- Encaminha corretamente a chamada ao cliente MCP.
Testes dos conversores
- Converte timeline válida;
- Converte faixa válida;
- Converte clipe válido;
- Trata campo ausente;
- Trata intervalo inválido;
- Trata tipo desconhecido;
- Trata lista vazia;
- Trata campos adicionais.
Testes do domínio
- Cria intervalo válido;
- Rejeita intervalo inválido;
- Calcula duração;
- Cria clipe;
- Cria faixa;
- Cria timeline.
Testes do scanner
- Executa a descoberta;
- Armazena a timeline no contexto;
- Propaga erros;
- Retorna contexto atualizado;
- Funciona com integração simulada.
37. Integração simulada para testes
Deverá existir uma implementação simulada do acesso ao editor.
Arquivo sugerido:
testes/fakes/acesso_ao_editor_simulado.py
Exemplo:
class AcessoAoEditorSimulado:
"""Fornece dados fictícios de uma timeline para testes."""
def __init__(self, dados_da_timeline):
self.dados_da_timeline = dados_da_timeline
def obter_timeline_ativa(self):
"""Retorna uma timeline simulada."""
return self.dados_da_timeline
Isso permite testar:
Scanner
↓
Acesso simulado
↓
Dados JSON
sem depender do Premiere.
38. Critérios de conclusão da primeira versão
O módulo será considerado concluído quando conseguir:
- Conectar ao MCP real;
- Identificar as ferramentas disponíveis;
- Consultar a sequência ativa;
- Consultar as faixas;
- Consultar os clipes;
- Retornar dados sem depender do formato bruto do MCP;
- Converter os dados para objetos de domínio;
- Identificar clipes offline;
- Diferenciar intervalo da timeline e intervalo da origem;
- Tratar timeline vazia;
- Tratar erros de conexão;
- Tratar respostas incompletas;
- Executar testes automatizados;
- Produzir logs;
- Ser utilizado pelo
Scanner; - Não executar nenhuma alteração na timeline.
39. Ordem recomendada de implementação
A implementação deverá ocorrer nesta ordem:
Fase 1 — Estrutura
Criar:
integracoes/premiere/
dominio/
scanner/
testes/
Fase 2 — Cliente MCP
Implementar:
ClienteMCP
SessaoMCP
ErrosMCP
Fase 3 — Descoberta da API
- Listar ferramentas;
- Identificar nomes;
- Identificar argumentos;
- Capturar respostas reais.
Fase 4 — Leitura técnica
Implementar:
AcessoATimeline
AcessoAClipes
AcessoAoEditor
Fase 5 — Modelos de domínio
Implementar:
Projeto
Sequencia
Timeline
Faixa
Clipe
IntervaloDeTempo
Fase 6 — Conversores
Implementar:
ConversorDeTimeline
ConversorDeFaixas
ConversorDeClipes
Fase 7 — Scanner
Implementar:
ContextoDeAnalise
DescobertaDaTimeline
PipelineDoScanner
AnalisadorDeTimeline
Fase 8 — Testes
Criar fixtures com respostas reais e testes simulados.
Fase 9 — Integração
Executar o fluxo completo:
Premiere
↓
MCP
↓
ClienteMCP
↓
AcessoAoEditor
↓
Conversores
↓
Domínio
↓
Scanner
40. Resultado esperado
Ao final da primeira versão, deverá ser possível executar algo conceitualmente semelhante a:
resultado = analisador_de_timeline.analisar()
E obter uma estrutura como:
resultado.timeline
resultado.timeline.nome
resultado.timeline.duracao
resultado.timeline.faixas
resultado.timeline.clipes
Por exemplo:
for faixa in resultado.timeline.faixas:
print(faixa.nome)
for clipe in faixa.clipes:
print(
clipe.nome,
clipe.intervalo_na_timeline.inicio,
clipe.intervalo_na_timeline.fim,
)
O resultado não será ainda um plano de edição.
Será a representação estruturada e confiável da timeline atual.
Essa representação será a base para todos os próximos módulos:
Leitura da timeline
↓
Descoberta de arquivos
↓
Metadados
↓
Áudio
↓
Transcrição
↓
Análise visual
↓
Detecção de cenas
↓
Detecção de retakes
↓
Motor de decisão
↓
Plano JSON
↓
Aplicação no Premiere
41. Regra final de arquitetura
O primeiro módulo deverá respeitar esta regra:
O MCP não é o scanner. O MCP é apenas o mecanismo de comunicação com o editor.
A divisão correta é:
ClienteMCP
comunica
AcessoAoEditor
organiza as consultas
Conversores
transformam respostas
Domínio
representa os dados
DescobertaDaTimeline
executa a descoberta
PipelineDoScanner
coordena as etapas
AnalisadorDeTimeline
inicia o processo
Essa separação permitirá que o sistema cresça sem transformar o código em uma única classe gigante e difícil de manter.
A próxima etapa prática deve ser inspecionar as ferramentas reais disponíveis no MCP do Premiere, porque os nomes das chamadas, os argumentos e o formato das respostas precisam ser confirmados antes de implementar definitivamente o ClienteMCP e os conversores.