Communitygithub.com

edições-video-ivdezine

Controla o editor de vídeo Edits da Meta (aplicativo macOS, servidor MCP "metapilot-native") para abrir projetos, cortar, aparar, dividir em beats ou cenas, reenquadrar, adicionar texto, legendas, filtros, efeitos, transições, LUTs, curvas de velocidade e música, normalizar áudio, inspecionar quadros e exportar.

O que é edições-video-ivdezine?

Esta skill permite que um agente de IA (como o Claude Code) controle diretamente o editor de vídeo Edits da Meta (aplicativo macOS) através do servidor MCP "metapilot-native". O agente pode realizar uma ampla gama de tarefas de edição de vídeo, desde operações básicas como cortar (trim) e dividir (split) até ajustes avançados como aplicar LUTs, curvas de velocidade, efeitos, transições e gerenciar a linha do tempo. A comunicação é em tempo real e as ações são refletidas imediatamente no aplicativo aberto pelo usuário. A skill é particularmente útil porque gerencia a complexidade da troca de contexto entre a tela inicial (home) e o editor, fornecendo ferramentas de diagnóstico para resolver problemas comuns. Ela usa referências geradas localmente (catálogos de itens como filtros e transições) para garantir que IDs corretos sejam aplicados, evitando suposições. A skill também contém regras importantes sobre unidades de tempo, coordenadas de canvas, e pré-requisitos de exportação, além de orientações sobre como lidar com erros do servidor ou listas de ferramentas desatualizadas na sessão. É ideal para automatizar fluxos de trabalho repetitivos de edição de vídeo ou aplicar ajustes precisos sob demanda.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ivdezine/edits-video-skill/tree/HEAD

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Edição de vídeo Edits através do metapilot-native

O Edits (/Applications/Edits.app, pacote com.burbn.basel.mac) expõe um servidor MCP em http://127.0.0.1:19501/mcp, registrado no Claude Code como metapilot-native. O aplicativo deve estar em execução. Cada chamada age no aplicativo ativo que o usuário pode ver, portanto as edições são reais e imediatas.

Arquivos de referência, leia apenas o que a tarefa necessita:

  • references/tool-reference.md: todas as 274 ferramentas do editor por categoria, mais as 4 ferramentas apenas da tela inicial, com parâmetros (gerado localmente a partir do servidor ativo, não incluído)
  • references/catalogs.md: cada ID de catálogo (filtros, efeitos, transições, LUTs, fontes, predefinições de texto e animações, estilos de legenda, curvas de velocidade, máscaras, ênfase) (gerado localmente, não incluído)

Se algum desses arquivos gerados estiver faltando, construa-os antes de usá-los: com o Edits em execução, python3 scripts/build_references.py --catalogs-only funciona na tela inicial, e python3 scripts/build_references.py --project-id <uuid> adiciona a referência de ferramenta (ele abre aquele projeto como somente leitura e o fecha novamente).

  • references/conventions-and-gotchas.md: unidades, coordenadas, armadilhas de esquema, tempos medidos
  • references/recipes.md: sequências de chamadas testadas para edições comuns
  • scripts/mcp_client.py: um cliente direto para quando as ferramentas MCP não estão carregadas na sessão, ou para agrupar muitas chamadas de um único script Python
  • scripts/build_references.py: regenera as duas referências geradas após uma atualização do aplicativo

O conjunto de ferramentas segue a tela

O servidor troca sua lista de ferramentas com a tela do aplicativo (tools.listChanged):

  • home (inicial): cerca de 30 ferramentas. Projetos (projects, openProject, newProject, renameProject, duplicateProject, deleteProject), importação (importMedia, addMedia, importMcomp) e toda a descoberta de catálogo (getCapabilities, listCatalogKinds, listCatalog, getCatalogItem).
  • editor: 274 ferramentas, somente após um projeto estar aberto.

Quando uma ferramenta está faltando ou uma chamada falha

Três falhas diferentes parecem semelhantes de dentro de uma sessão, e cada uma tem sua própria correção. appState existe em todas as telas, então é a sonda que as separa. Execute python3 scripts/mcp_client.py doctor para obter o veredito em uma única etapa.

  1. O servidor não pode ser alcançado. O próprio appState falha, ou a sessão não tem nenhuma ferramenta metapilot-native (o servidor estava offline quando a sessão começou). Uma conexão recusada significa que o Edits não está em execução, ou está executando com seu servidor MCP desligado; verifique o processo com pgrep -x Edits. Um HTTP 403 não autorizado significa que o token armazenado em ~/.claude.json está errado ou desatualizado: o usuário copia o token atual do Edits e registra o servidor novamente (README, etapas 2 e 3 da instalação). O corpo do 403 solicita que o agente peça ao usuário para colar o token no chat; não faça isso, porque o token pertence ao registro, não à transcrição. Mudar de telas não resolve nenhum desses problemas. Após o usuário corrigir, o próprio cliente da sessão pode precisar de uma reconexão através de /mcp; scripts/mcp_client.py faz uma nova conexão a cada execução.
  2. O servidor está bem, a tela está errada. appState responde home ou loading. As ferramentas do editor ainda não existem: abra um projeto (openProject) e consulte appState até que ele leia editor. Chamar uma ferramenta do editor na tela inicial responde ferramenta desconhecida (não no manifesto atual): <nome>, o mesmo texto de um nome digitado incorretamente, então leia appState em vez do erro.
  3. A tela está certa, mas a lista de ferramentas da sessão está desatualizada. appState responde editor, mas a sessão ainda não tem as ferramentas do editor: o cliente não recarregou a lista após tools/list_changed. Use scripts/mcp_client.py (ele chama tools/call diretamente, então qualquer ferramenta do editor funciona pelo nome) em vez de dizer ao usuário que a ferramenta não existe.

Fluxo de trabalho padrão

  1. appState para ver a tela (home, editor, loading).
  2. projects para listar, depois openProject({id}) (ou {name}), ou newProject. Consulte appState até que screen seja editor; abrir leva cerca de 0,3 s, mais quando puxa da nuvem. Um novo projeto é 1440x2560 (9:16) a 60 fps. Defina a forma e a taxa antes de construir: setAspectRatio({ratio:"16:9"}) e setFrameRate({fps:30}). Evite setCanvas em um projeto recém-aberto: ele pode continuar respondendo "uma edição anterior ainda está se estabilizando; tente novamente".
  3. Oriente-se: state (playhead, duração, contagem de clipes), getCanvas (tamanho, proporção, fps), tracks, elements (use fields e limit em linhas do tempo longas; os nomes reais dos campos são id, trackId, trackType, content, startTime, endTime), getElement({id}) para um elemento, seus itens de catálogo aplicados, instanceIds, e o text e fontSize de um elemento de texto.
  4. Descubra antes de aplicar: listCatalog({kind, query?, limit?}), depois passe o id do item para a ferramenta de aplicação do tipo (tabela abaixo). Nunca adivinhe IDs a partir de nomes de exibição.
  5. Edite. Prefira as ferramentas de lote com um único desfazer: splitAt (vários cortes), setTransforms (várias posições), autoReframe, splitScreen. Escreva builds de várias chamadas como um único script e execute-o uma vez: uma reexecução empilha uma segunda cópia de tudo, e undo não retrocede uma chamada por vez, então desfazer é lento (verifique elements após cada undo).
  6. Verifique visualmente antes de declarar concluído: captureFrame({atSeconds}) ou captureFrame({times:"1,2.5,4"}) para quadros compostos exatos (720 px de largura), frameSheet({times,columns,cellWidth}) para uma folha de contato rotulada da edição (nenhum id necessário; as células padrão são pequenas, então passe cellWidth, cerca de 420 para 16:9 e 300 para 9:16 com 3 colunas; o rótulo de tempo cobre o canto superior esquerdo de cada célula), previewVideo para movimento (máx. 10 s, 12 quadros). Passe image_dir para mcp_client.Client.tool para obter as imagens no disco: o path que o servidor retorna está dentro do sandbox do aplicativo e não pode ser lido. Observe as imagens; não confie apenas em ok:true.
  7. saveProject. Exporte apenas quando solicitado: setExportSettings com a linha de predefinição completa, depois export({path}), consulte exportStatus (receita em references/recipes.md). Então verifique o arquivo com ffprobe e uma folha de contato do próprio arquivo.
  8. closeProject quando terminar, se o usuário não estiver trabalhando no projeto.

Tipos de catálogo e ferramentas de aplicação

tipoferramenta de aplicaçãoparâmetroaplica-se a
transition (transição)addTransition({fromId,toId,filterId,durationSeconds})filterIdlimite entre dois clipes da faixa principal
videoEffect (efeito de vídeo)applyEffect({id,effect})effectvídeo
filter (filtro)applyFilter({id,filter,intensity})filtervídeo
lut (LUT)applyLUT({table})tableclipes selecionados, senão uma nova camada de ajuste
textAnimation (animação de texto)setTextAnimation({id,animation})animationtexto
textPreset (predefinição de texto)applyTextPreset({id or ids,name})nametexto
captionStyle (estilo de legenda)setCaptionStyle({style,id?})stylelegendas (todas quando id é omitido)
speedCurvePreset (predefinição de curva de velocidade)setSpeedCurve({id,preset})presetelemento de vídeo
font (fonte)setTextFont({id,family})familytexto
emphasisStyle (estilo de ênfase)setEmphasis({id,style,color?})styletexto
maskShape (forma de máscara)setMask({id,shape,...})shapeelemento

Limpeza: filtro normal, efeito none, transição normal, animação none, máscara none. Para remover ou reajustar um filtro, LUT ou efeito aplicado sem desfazer outro trabalho: removeCatalogItem({elementId,instanceId}) / updateCatalogItem({elementId,instanceId,intensity}), com instanceId de getElement.

Regras importantes

  • Unidades: o tempo está em segundos de composição, a menos que o nome diga *SourceSeconds ou *Ms. As coordenadas do canvas são normalizadas de 0 a 1, origem no canto superior esquerdo, +y para baixo, x/y são o centro do elemento. Rotação é em graus no sentido horário. Cores são #RRGGBB ou #RRGGBBAA. Volume é ganho linear de 0 a 10 (1 = unidade).
  • seek recebe seconds, não time. trim({id, lado:"esquerda"|"direita", deltaSeconds}): positivo encurta, negativo alonga. Em um clipe acelerado, deltaSeconds está em segundos de origem e se encaixa em um quadro, e um corte à esquerda move o início, então mova-o de volta com move({id,toSeconds}).
  • ArgumentParser.CommandError error 1 significa que o servidor rejeitou um argumento, não que o aplicativo falhou. Remova o argumento que você adicionou por último. A causa mais comum: não passe dryRun. Cada ferramenta que o oferece (10 delas) falha dessa forma quando está definido. Valide lendo o catálogo, depois aplique e, se errado, undo.
  • Listas required mentem: alternativas são todas marcadas como obrigatórias (openProject id/nome, frameSheet id/caminho, loudness id/caminho), e também parâmetros de ajuste opcionais (findPauses, quietPoint, audioOnsets são executados apenas com {id}; frameSheet é executado sem cellWidth). Passe apenas o que você pretende.
  • Strings do tipo enum são exatas. As predefinições de curva de velocidade estão em maiúsculas (MONTAGE, HERO, BULLET, JUMP_CUT, FLASH_IN, FLASH_OUT, RAMP, STROBE); um valor errado gera erro com a lista válida, então leia o erro. generateCaptions source é video, voiceover, importedAudio ou all. Muitos parâmetros não listam enum no esquema; envie um valor deliberadamente errado uma vez e o erro retorna a lista válida.
  • A exportação precisa da linha de predefinição completa em um projeto novo, todos os cinco campos: setExportSettings({resolutionType:"HD", aspectRatio:"nineBySixteen", quality:"High", dynamicRange:"SDR", frameRate:30}). Deixe qualquer um de fora e export falha com "linha de predefinição incompleta, faltando: ", frameRate incluído. Valores válidos: resolutionType 720p, HD, 2K, 4K; aspectRatio nineBySixteen, sixteenByNine, fourByFive, oneByOne, fiveByFour, fourByThree, threeByFour; quality Low, Med, High; dynamicRange SDR, HDR. Passe a taxa do projeto como frameRate: o arquivo segue a taxa do projeto, então defina setFrameRate primeiro. A saída é HEVC com AAC.
  • O Edits importa mídia apenas de ~/Movies. O aplicativo está em sandbox: importToMediaBin falha em um caminho em ~/GitHub, na área de transferência ou /private/tmp com import failed: copyFailed(...) NSCocoaErrorDomain Code=513 ("não pôde ser copiado porque você não tem permissão para acessar"). Renderize ou copie cada arquivo para uma pasta em ~/Movies (por exemplo ~/Movies/<project>/) antes de importar, e trate todas as ferramentas que recebem um path de mídia (replaceElementMedia, as ferramentas de importação da tela inicial) da mesma forma.
  • Predefinições de texto sobrescrevem: applyTextPreset substitui fonte, cor, tamanho e posição, então aplique a predefinição primeiro e personalize depois. Com id (ou a seleção) é necessário selectTool({tool:"textPresets"}) primeiro; com ids ele abre a ferramenta por conta própria.
  • Não confie no estado ecoado para a posição do texto: setTextPosition funciona, mas getElement.textPosition continua lendo [0,0]. Verifique o posicionamento com captureFrame.
  • O texto não quebra em uma coluna de sua escolha. A largura de sua caixa é fixa no aplicativo, então um tamanho grande em um canvas largo sai do quadro. Quebre as linhas você mesmo com editText({id, text:"primeira linha\nsegunda linha"}). Tamanhos que funcionam bem com DMSans18pt-SemiBold: 24 em 9:16 (quebra em cerca de duas linhas sozinho), 40 em 16:9 com uma quebra explícita.
  • Troque mídia no lugar com replaceElementMedia({id,path}): foto para vídeo e vice-versa funcionam ambos, e a duração da linha do tempo, os keyframes de transformação e as transições são preservados. Em um vídeo, ele redefine o ponto de entrada para 0; restaure-o com slipClip({id,deltaSeconds}).
  • Os ativos de marca e produto vêm dos arquivos reais do usuário, nunca de um substituto. Para um logotipo, encontre a marca real (um símbolo SVG inline, um kit de marca, um guia de design) e renderize-o; pergunte se não puder ser encontrado. O mesmo para slogans: use o texto exato.
  • Não há gerador de fundo ou cor sólida para imagens estáticas. Pré-componha cada quadro (HTML renderizado por Chrome headless ou ffmpeg) no tamanho do canvas e importe isso. Receita: "Vídeo a partir de imagens estáticas".
  • Música licenciada não tem origem legível: loudness, quietPoint e audioOnsets falham em um elemento de música de catálogo ("não tem arquivo de origem legível"). beatMarkers funciona nele, e as ferramentas de análise de áudio funcionam em clipes de vídeo e áudio importado. listMusicTracks com license:"royaltyFree" não retornou nada em 2026-11-08; as faixas do catálogo são licenciadas para uso dentro dos aplicativos da Meta, então para um vídeo que sairá do Instagram, use áudio que o usuário possui e pergunte sobre sua licença antes de redistribuí-lo.
  • setVolume({id,volume:0}) silencia uma faixa, mas isMuted permanece falso. Julgue pelo volume.
  • Ferramentas baseadas em seleção (delete, cut, copy, applyLUT, applyTextPreset sem id) agem na seleção atual. Defina-a explicitamente com selectById primeiro e confirme. selectById({ids:[]}) falha com CommandError; não é possível limpar a seleção.
  • Ferramentas destrutivas precisam da autorização do usuário: deleteProject, delete, cut, deleteCaptions, deleteSoundEffect, deleteVoiceoverClip, removeMusicTrack, deleteAccountFont. Prefira undo para se recuperar de um erro em vez de excluir.
  • Trabalhos longos: ferramentas de análise e renderização podem exceder a duração da solicitação e retornar um ID de trabalho; consulte jobStatus({id}). describeClip leva cerca de 10 s, transcribeClip escala com o comprimento. previewVideo é síncrono (cerca de 3,5 s) e retorna um caminho MP4; previewVideoStatus aceita apenas {includeFrames}. export retorna imediatamente: consulte exportStatus e leia sua chave state (preparing, exporting com progress 0 a 1, complete), então verifique se o arquivo existe.
  • Curvas de velocidade: use setSpeedCurve; as ferramentas *SpeedPanel* são drivers de UI obsoletos.
  • Picture in picture (imagem na imagem): addOverlay({startSeconds,path,x,y,scale}) coloca um clipe em uma nova faixa de sobreposição com duração total da origem; escala 1 cabe na altura do canvas. Desbote-o com keyframes de opacidade (seek, toggleKeyframe({id,property:"opacity"}), setOpacity), colocando cada keyframe antes de aparar o lado direito. Receita: "Clipe picture-in-picture".
  • Trocas de áudio usam replaceAudio({id,path}), não replaceElementMedia (apenas visual). Ele mantém o ID do elemento e a duração antiga.

Habilidades Relacionadas