Files
jhonny-editor/code/engine/arquitetura/integracao-com-premiere.md
T
João Henrique b541f502ba 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
2026-09-08 09:59:31 -04:00

14 KiB

Sim. O ideal é tratar o MCP como um módulo completo de integração com o Premiere, e não como uma única classe responsável por tudo.

O MCP será utilizado para várias finalidades:

  • Ler a timeline ativa;
  • Ler sequências, faixas e clipes;
  • Obter propriedades dos clipes;
  • Criar, mover, cortar ou excluir elementos;
  • Aplicar alterações na timeline;
  • Executar comandos no Premiere;
  • Consultar o estado atual do projeto;
  • Validar se uma operação foi executada corretamente.

Por isso, uma única classe como ClienteMCP ficaria sobrecarregada rapidamente.

Estrutura recomendada

integracoes/
└── premiere/
    ├── __init__.py
    │
    ├── cliente_mcp.py
    ├── sessao_mcp.py
    ├── erros_mcp.py
    │
    ├── leitura/
    │   ├── acesso_a_timeline.py
    │   ├── acesso_a_sequencia.py
    │   ├── acesso_a_faixas.py
    │   └── acesso_a_clipes.py
    │
    ├── escrita/
    │   ├── executor_de_comandos.py
    │   ├── manipulador_de_clipes.py
    │   ├── manipulador_de_timeline.py
    │   └── aplicador_de_operacoes.py
    │
    ├── conversores/
    │   ├── conversor_de_timeline.py
    │   ├── conversor_de_clipes.py
    │   └── conversor_de_respostas.py
    │
    └── contratos/
        ├── acesso_ao_editor.py
        └── executor_do_editor.py

A ideia principal é separar:

Comunicação com o MCP, leitura do Premiere, execução de comandos e conversão dos dados.


1. ClienteMCP

Arquivo:

integracoes/premiere/cliente_mcp.py

Classe:

class ClienteMCP:
    """Responsável pela comunicação técnica com o servidor MCP do Premiere."""

Essa classe deve cuidar somente da comunicação.

Responsabilidades:

  • Abrir conexão;
  • Encerrar conexão;
  • Enviar uma chamada;
  • Receber a resposta;
  • Controlar timeout;
  • Tratar erros de comunicação;
  • Registrar logs;
  • Identificar falhas de conexão;
  • Possivelmente reconectar.

Exemplo conceitual:

class ClienteMCP:
    """Executa chamadas técnicas contra o servidor MCP."""

    def conectar(self) -> None:
        """Estabelece a conexão com o MCP."""

    def desconectar(self) -> None:
        """Encerra a conexão com o MCP."""

    def chamar(self, nome_da_ferramenta: str, argumentos: dict) -> dict:
        """Executa uma ferramenta MCP e retorna sua resposta."""

Ele não deve saber o que é uma timeline, um clipe ou um retake.

Para ele, existe apenas:

chamar ferramenta → receber resposta

2. SessaoMCP

Arquivo:

integracoes/premiere/sessao_mcp.py

Classe:

class SessaoMCP:
    """Controla o estado de uma sessão de comunicação com o Premiere."""

Pode ser útil para armazenar:

  • Identificação da sessão;
  • Estado da conexão;
  • Projeto atual;
  • Sequência ativa;
  • Última operação executada;
  • Ferramentas disponíveis;
  • Informações de capacidade do MCP.

Exemplo:

class SessaoMCP:
    """Representa o estado atual da integração com o Premiere."""

    def __init__(self):
        self.conectado = False
        self.projeto_atual = None
        self.sequencia_ativa = None

Essa classe não é obrigatória na primeira versão, mas será útil quando a integração crescer.


3. Módulo de leitura

O módulo de leitura seria responsável por transformar comandos técnicos do MCP em operações compreensíveis pelo sistema.

AcessoATimeline

Arquivo:

integracoes/premiere/leitura/acesso_a_timeline.py

Classe:

class AcessoATimeline:
    """Fornece operações de leitura da timeline do Premiere."""

Métodos possíveis:

class AcessoATimeline:
    """Lê a estrutura da timeline ativa."""

    def obter_timeline_ativa(self):
        """Retorna os dados da timeline ativa."""

    def obter_sequencia_ativa(self):
        """Retorna a sequência atualmente selecionada."""

    def obter_faixas(self):
        """Retorna as faixas de vídeo e áudio."""

    def obter_clipes(self):
        """Retorna os clipes presentes na timeline."""

    def obter_detalhes_do_clipe(self, identificador_do_clipe):
        """Retorna os detalhes de um clipe específico."""

O fluxo seria:

AcessoATimeline
       ↓
ClienteMCP
       ↓
MCP do Premiere

O scanner chamaria:

timeline = acesso_a_timeline.obter_timeline_ativa()

E não:

cliente_mcp.chamar("alguma_ferramenta_interna", {...})

Isso é importante porque o restante do sistema não deve conhecer os detalhes do MCP.


Outras classes de leitura

Podemos dividir conforme a complexidade:

leitura/
├── acesso_a_timeline.py
├── acesso_a_sequencia.py
├── acesso_a_faixas.py
├── acesso_a_clipes.py
├── acesso_a_projeto.py
└── acesso_a_itens_de_midia.py

Entretanto, no início, não é necessário criar todas imediatamente.

Podemos começar com:

AcessoAoEditor

e depois dividir quando a classe crescer demais.


4. AcessoAoEditor

Eu recomendaria inicialmente uma classe de fachada chamada AcessoAoEditor.

Arquivo:

integracoes/premiere/acesso_ao_editor.py

Classe:

class AcessoAoEditor:
    """Oferece uma interface simplificada para consultar o Premiere."""

Ela funcionaria como uma porta de entrada para as operações de leitura:

class AcessoAoEditor:
    """Centraliza o acesso estruturado aos dados do Premiere."""

    def __init__(self, acesso_a_timeline, acesso_a_clipes):
        self.acesso_a_timeline = acesso_a_timeline
        self.acesso_a_clipes = acesso_a_clipes

    def obter_timeline_ativa(self):
        """Obtém a timeline ativa."""

        return self.acesso_a_timeline.obter_timeline_ativa()

    def obter_clipes(self):
        """Obtém os clipes da timeline ativa."""

        return self.acesso_a_clipes.obter_clipes()

Assim, o scanner dependeria de:

AcessoAoEditor

e não diretamente de:

ClienteMCP

5. Módulo de escrita

A leitura e a escrita devem ser separadas.

integracoes/premiere/
├── leitura/
└── escrita/

Isso evita misturar:

  • Consultar dados;
  • Alterar dados;
  • Executar comandos destrutivos.

ExecutorDeComandos

Arquivo:

integracoes/premiere/escrita/executor_de_comandos.py

Classe:

class ExecutorDeComandos:
    """Executa comandos de alteração no Premiere por meio do MCP."""

Responsabilidades:

  • Executar uma operação;
  • Enviar parâmetros;
  • Receber resultado;
  • Identificar falhas;
  • Retornar confirmação da operação.

Exemplo:

class ExecutorDeComandos:
    """Executa comandos no editor."""

    def executar(self, nome_do_comando: str, argumentos: dict):
        """Executa um comando no Premiere."""

Mas essa classe não deveria decidir qual comando deve ser executado. Ela apenas executa o comando que recebeu.


AplicadorDeOperacoes

Arquivo:

integracoes/premiere/escrita/aplicador_de_operacoes.py

Classe:

class AplicadorDeOperacoes:
    """Aplica operações de edição estruturadas na timeline."""

Essa classe recebe operações já definidas pelo plano de edição:

class AplicadorDeOperacoes:
    """Aplica operações de edição no Premiere."""

    def aplicar_corte(self, operacao):
        """Aplica uma operação de corte."""

    def mover_clipe(self, operacao):
        """Move um clipe na timeline."""

    def excluir_clipe(self, operacao):
        """Exclui um clipe da timeline."""

    def aplicar_plano(self, plano):
        """Aplica todas as operações de um plano de edição."""

O fluxo seria:

AplicadorDeOperacoes
       ↓
ExecutorDeComandos
       ↓
ClienteMCP
       ↓
MCP do Premiere

6. ConversorDeTimeline

Arquivo:

integracoes/premiere/conversores/conversor_de_timeline.py

Classe:

class ConversorDeTimeline:
    """Converte os dados brutos do Premiere para o modelo interno do sistema."""

Essa classe é muito importante.

O MCP pode retornar dados em um formato específico, por exemplo:

{
  "sequence": {
    "name": "Sequência 01",
    "timebase": 25
  },
  "tracks": [],
  "clips": []
}

Mas o sistema não deveria depender diretamente desse formato.

O conversor transforma isso em objetos próprios:

class ConversorDeTimeline:
    """Converte uma resposta do Premiere para o domínio interno."""

    def converter(self, dados_brutos):
        """Converte os dados brutos em uma timeline do sistema."""

Assim, se futuramente o MCP mudar, somente a integração e os conversores precisarão ser ajustados.

O restante do sistema continua funcionando.


7. Contratos para desacoplar o sistema

O ideal é criar contratos para que o scanner não dependa de uma implementação específica.

AcessoAoEditor

Arquivo:

integracoes/premiere/contratos/acesso_ao_editor.py

Exemplo:

from abc import ABC, abstractmethod


class AcessoAoEditor(ABC):
    """Define as operações de leitura necessárias para acessar um editor."""

    @abstractmethod
    def obter_timeline_ativa(self):
        """Obtém a timeline ativa do editor."""
        raise NotImplementedError

    @abstractmethod
    def obter_clipes(self):
        """Obtém os clipes da timeline."""
        raise NotImplementedError

Depois podemos ter:

AcessoAoEditor
├── AcessoAoPremiere
├── AcessoAoOpenCut
└── AcessoAoEditorSimulado

O último é especialmente útil para testes.

Por exemplo:

class AcessoAoEditorSimulado(AcessoAoEditor):
    """Fornece dados fictícios para testes sem abrir o Premiere."""

8. Como o scanner usaria isso

A classe DescobertaDaTimeline não deveria conhecer MCP.

Ela deveria conhecer apenas uma interface de acesso ao editor.

class DescobertaDaTimeline:
    """Descobre a estrutura da timeline a partir do editor."""

    def __init__(self, acesso_ao_editor):
        self.acesso_ao_editor = acesso_ao_editor

    def executar(self, contexto):
        """Lê a timeline e armazena os dados no contexto."""

        timeline = self.acesso_ao_editor.obter_timeline_ativa()

        contexto.timeline = timeline

        return contexto

O encadeamento seria:

DescobertaDaTimeline
        ↓
AcessoAoPremiere
        ↓
AcessoATimeline
        ↓
ClienteMCP
        ↓
MCP do Premiere

Ou, usando uma fachada:

DescobertaDaTimeline
        ↓
AcessoAoEditor
        ↓
ClienteMCP
        ↓
MCP do Premiere

9. Arquitetura completa recomendada

projeto/
│
├── scanner/
│   ├── coordenacao/
│   │   ├── analisador_de_timeline.py
│   │   ├── pipeline_do_scanner.py
│   │   └── contexto_de_analise.py
│   │
│   ├── descoberta/
│   │   ├── descoberta_da_timeline.py
│   │   ├── descoberta_de_clipes.py
│   │   └── descoberta_de_arquivos.py
│   │
│   ├── metadados/
│   ├── audio/
│   ├── transcricao/
│   ├── visual/
│   ├── cenas/
│   └── retakes/
│
├── providers/
│   ├── transcricao/
│   ├── analise_visual/
│   ├── deteccao_de_cenas/
│   └── analise_de_audio/
│
├── integracoes/
│   └── premiere/
│       ├── cliente_mcp.py
│       ├── sessao_mcp.py
│       ├── erros_mcp.py
│       │
│       ├── leitura/
│       │   ├── acesso_a_timeline.py
│       │   ├── acesso_a_sequencia.py
│       │   ├── acesso_a_faixas.py
│       │   └── acesso_a_clipes.py
│       │
│       ├── escrita/
│       │   ├── executor_de_comandos.py
│       │   ├── aplicador_de_operacoes.py
│       │   └── manipulador_de_timeline.py
│       │
│       ├── conversores/
│       │   ├── conversor_de_timeline.py
│       │   ├── conversor_de_clipes.py
│       │   └── conversor_de_respostas.py
│       │
│       └── contratos/
│           ├── acesso_ao_editor.py
│           └── executor_do_editor.py
│
├── dominio/
├── configuracao/
├── persistencia/
└── testes/

Minha recomendação prática

Para a primeira versão, não criaria todas as classes imediatamente. Começaria assim:

integracoes/
└── premiere/
    ├── cliente_mcp.py
    ├── acesso_ao_editor.py
    ├── executor_de_comandos.py
    ├── conversor_de_timeline.py
    └── erros_mcp.py

Depois, quando as responsabilidades crescerem:

acesso_ao_editor.py

poderá ser dividido em:

leitura/
├── acesso_a_timeline.py
├── acesso_a_clipes.py
└── acesso_a_projeto.py

E:

executor_de_comandos.py

poderá ser dividido em:

escrita/
├── aplicador_de_operacoes.py
├── manipulador_de_clipes.py
└── manipulador_de_timeline.py

Regra central

A arquitetura deve seguir esta separação:

Scanner
    define o que precisa ser analisado

Integração com o Premiere
    acessa e altera o editor

Cliente MCP
    faz a comunicação técnica

Conversores
    transformam dados externos em dados internos

Providers
    executam análises usando tecnologias específicas

Motor de decisão
    decide o que fazer com os resultados

Aplicador de plano
    transforma decisões em operações no editor

Portanto, a resposta direta é:

MCP deve ser um módulo de integração completo, com ClienteMCP como classe de comunicação central, classes especializadas de leitura e escrita, conversores e contratos. Ele não deve ser uma única classe gigante nem ficar misturado dentro do scanner.