Communitygithub.com

by-lua/video-editing

Mecânica completa do Google Flow — geração de imagem e vídeo via Omni 1.1 Flash, com fila, download, validação e movimentação para o projeto.

video-editing 是什么?

Esta skill automatiza o pipeline completo de geração de mídia no Google Flow, funcionando como alternativa ao Hub quando este está expirado. Ela gerencia a criação de projetos, configuração de modelos (Omni 1.1 Flash), proporção 9:16, e confirmação 'Nunca' para evitar desperdício de créditos. Após o envio, a skill monitora os três estados (fila, gerando, pronto), faz o download da mídia via modal e re-encode para BT709. Inclui também um sistema de 'lane' para evitar conflitos entre múltiplos Clientes Claude usando o mesmo perfil de navegador. Suporta downloads de imagem via blob e vídeo via modal, com validação de metadados de cor e áudio.

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/by-lua/video-editing/tree/HEAD/skills/flow-video-playwright

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

video-editing preview

文档

HUB DESATIVADO (02/10/2026, por ordem do usuário): NinjaBR Hub está SEM COTA e os perfis hub/hubv2/hubts foram removidos (backup em ~/.agent-profiles/_removidos-hub-2026-10-02/). NÃO use Hub, NÃO execute hub-livre.sh (sai com erro), NÃO espere perfil do Hub liberar. Imagem: ChatGPT — se a cota de upload de uma conta acabar, troque de CONTA: gpt-noelia-7-10* ↔ gpt-noelia.empt*. Vídeo: Google Flow (flow-video-playwright).

flow-video-playwright

Mecânica de geração de imagem+vídeo via Google Flow (labs.google/fx/pt/tools/flow). Alternativa ao hub-video-playwright quando o Hub está expirado (morreu 21/09/2026, veja [[feedback-ninjabr-hub-acesso-expirado]]).

Perfil

flow-enovalabs-pro (porta 9265), já logado no Google. Antes de gastar tempo, navegue e confirme o login:

agent-browser --session flow-enovalabs-pro navigate "https://labs.google/fx/pt/tools/flow"

Se cair na tela de login, pare e avise o usuário — as credenciais não estão em .credentials.env.

Modelo

Omni 1.1 Flash — confirmado em produção em 30/09/2026. Custa menos créditos que o Veo 3.1. É multimodal: gera imagem E vídeo a partir do prompt puro, sem upload.

Antes da geração, abra as configurações (botão tune, aria-label "Configurações") e garanta:

  • Confirmar antes de gerar = Nunca (o padrão vem como "Sempre" — gasta crédito e bloqueia o envio se deixar em Sempre).
  • Modelo padrão de geração de vídeo = Omni 1.1 Flash.
  • Proporção de vídeo = crop_9_16 9:16 (radio role="radio", o SEGUNDO crop_9_16 da lista, índice 10 no mapeamento atual).

Salve.

Fluxo (passo a passo verificado em 01/10/2026)

  1. Criar projeto: dashboard → botão "Novo projeto" → URL vira https://flow.google.com/project/<uuid>.
  2. Composer: [contenteditable=true]. Cole via clipboard, NÃO use innerText — medido em 01/10:
    • c.innerText = prompt; c.dispatchEvent(new InputEvent('input')) cola o texto, mas o botão "Iniciar geração" NÃO trava como disabled ao clicar (o handler de "text changed" do Material não dispara). 2 cliques não geram nada.
    • Caminho correto: clipboard write nativo do agent-browser, depois Ctrl+A Ctrl+V no composer:
      agent-browser --session flow-enovalabs-pro clipboard write "$PROMPT"
      agent-browser --session flow-enovalabs-pro click "[contenteditable=true]"
      agent-browser --session flow-enovalabs-pro press "Control+a"
      agent-browser --session flow-enovalabs-pro press "Control+v"
      
    • Confirme txtLen === prompt.length antes de enviar.
  3. Enviar: click button[aria-label='Iniciar geração']. O botão trava com disabled=true = envio aceito. O texto "Na fila" aparece, depois "Conceptualizing the Video" / "play_circle" + percentual.
  4. Aguardar: o status muda para "Conceptualizing the Video" (Flow) ou "Criando imagem" (ChatGPT). O botão "Parar" só aparece enquanto está gerando. ~50s para imagem apenas com prompt, mais para vídeo.
  5. Resultado: <img src="blob:https://flow.google.com/..."> com naturalWidth>800 quando é 9:16. Baixe via fetch+blob+<a download> (link DOM nativo).

Configurações obrigatórias (antes do primeiro envio)

Abra button[aria-label='Configurações'] (ícone tune):

  • Confirmar antes de gerar = Nunca (radio group mat-radio-group-2, value=2). O padrão vem como "Sempre" — gasta o crédito E bloqueia o envio automático.
  • Modelo padrão de geração de vídeo = Omni 1.1 Flash (combobox).
  • Proporção de vídeo = crop_9_16 9:16 (button role="radio", SEGUNDO crop_9_16 da lista, índice 10).

Defina os radios via input[type=radio] diretamente (clicar no mat-radio-button não altera o input):

// Nunca
const inputs = Array.from(document.querySelectorAll('input[type=radio]'));
inputs.find(r => r.closest('mat-radio-button')?.innerText.startsWith('Nunca')).click();

// 9:16 vídeo (segundo crop_9_16)
const r916 = Array.from(document.querySelectorAll('button[role=radio]'))
  .filter(b => b.innerText === 'crop_9_16\n9:16')[1];
r916.click();

// Salvar
Array.from(document.querySelectorAll('button')).find(b => b.innerText?.trim() === 'Salvar').click();

Upload de referência — bloqueado em 30/09/2026

O botão "Enviar mídia" do painel "Adicionar elementos" abre o seletor de arquivos nativo do SO (CDP Page.fileChooserOpened, não <input type=file> no DOM). agent-browser upload falha silenciosamente.

Workaround: gere apenas com prompt. O OmniFlash é multimodal e interpreta o prompt descritivo. Não é tão fiel à referência quanto o upload seria, mas evita o seletor de arquivos. Escalone o browser-harness com Page.setInterceptFileChooser se o prompt-only não for suficiente — não testado em produção.

Prompt-only — template base

A <tipo de plano> shot of <composição>. <sujeito> doing <ação única, lenta>.
<cenário>. <luz>. Shot in vertical 9:16 aspect ratio. Photorealistic,
shot on iPhone, no text, no watermark. <anti-morphing>.

Anti-morphing obrigatório (o Flow não tem campo NEGATIVE separado, coloque na mesma string):

  • "Hand never clips through the fabric"
  • "Garment stays flat / never floats unsupported"
  • "Single continuous motion, no jumping"

Validado em 30/09/2026: cena 1 (mão feminina puxando tecido canelado rosa, fundo cama branco) gerada em ~50s no OmniFlash, saída 941x1672, visual iPhone UGC convincente.

Download (verificado em 01/10/2026)

O vídeo não renderiza <video> na grade — só após abrir o card no modal. Fluxo:

  1. Clique na thumbnail (img[alt="Miniatura do vídeo gerada"]) — abre o modal com player + botões no cabeçalho.
  2. Clique button[aria-label="Baixar mídia"] (ícone de download no cabeçalho).
  3. Abre o menu de qualidade: 270p (GIF), 720p (Tamanho original), 1080p (Aprimorada), 4K (Aprimorada).
  4. Clique na opção certa via DOM direto:
    Array.from(document.querySelectorAll('button'))
      .find(b => b.innerText.trim() === '720p\nTamanho original').click();
    
  5. O arquivo cai em ~/Downloads/ com o nome do título do Flow + timestamp (Hands_lifting_brown_skirt_fabric_20261001180016.mp4). Mova para o staging do projeto e renomeie.

Para imagem (gerada diretamente, sem vídeo): <img src="blob:https://flow.google.com/..."> aparece na grade após gerar. Salve via fetch+blob+<a download> OU screenshot direto.

Gate de cor após o download

Quase toda mídia do Flow sai com color_range/color_space/color_transfer/color_primaries = unknown — confirmado em 01/10/2026 no Flow Omni 1.1 Flash. O gate feedback-metadado-cor-video-final reprova. Re-encode para bt709 ANTES de marcar o clipe como pronto:

ffmpeg -nostdin -i cena-1.mp4 \
  -c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p \
  -x264-params "colorprim=bt709:transfer=bt709:colormatrix=bt709:fullrange=off" \
  -color_primaries bt709 -color_trc bt709 -colorspace bt709 -color_range tv \
  -c:a copy cena-1-fixed.mp4
mv cena-1-fixed.mp4 cena-1.mp4

Confira com ffprobe -show_entries stream=color_* — os 4 campos devem estar como bt709/tv.

Pegar a lane — PRIMEIRA COISA, SEMPRE

Vários Clientes Claude usam este mesmo navegador. Sem lane, todos caem no mesmo projeto: o criar projeto de um sobrescreve o do outro, e as gerações saem trocadas.

~/.claude/bin/lane.sh take flow <lane>      # ex.: lane.sh take flow pov-bella
S=flow-<lane>                               # use $S em TODO comando daqui pra frente

Perfil persistente ~/.agent-profiles/flow-enovalabs-pro, porta 9265, URL https://labs.google/fx/pt/tools/flow. Nunca use agent-browser open, press Escape (envia a aba para about:blank e quebra a lane). Ao terminar: ~/.claude/bin/lane.sh drop flow <lane>.

A área de download do Flow é FLOW, não HUB nem PLAYWRIGHT. Exporte uma vez no início:

export LANE_AREA=FLOW

O arquivo sai do Flow com o nome do título + timestamp (ex.: Hands_lifting_brown_skirt_fabric_20261001180016.mp4), cai em ~/Downloads/, e o lane.sh collect move para ~/Downloads/FLOW/$LANE/ → pasta do projeto. Nada fica solto em Downloads.

CHECK-LIST DE ENVIO — execute ANTES de cada clique em "Iniciar geração"

O Flow não limpa nada entre gerações (igual o Hub): o prompt do composer fica grudado, o modelo/proporção podem ser resetados pelo re-render após o envio. A ordem abaixo existe porque cada passo fora do lugar já custou crédito (cota cobrada mesmo em geração inválida).

1. CRIE um projeto novo (ou mude para um existente) — cada leva usa um projeto. Botão "Novo projeto" no dashboard. URL vira https://flow.google.com/project/<uuid>. Reutilizar um projeto velho acumula lixo e confunde a diff de src do download (veja adiante).

2. LIMPE o composer do projeto novo:

agent-browser --session $S click "[contenteditable=true]"
agent-browser --session $S press "Control+a"
agent-browser --session $S press "Delete"

Confirme:

echo '(()=>document.querySelector("[contenteditable=true]").textContent.length)()' \
  | agent-browser --session $S eval --stdin    # deve retornar 0

3. VERIFIQUE as configurações: "Confirmar antes de gerar" = Nunca, modelo = Omni 1.1 Flash, proporção = crop_9_16 9:16. A skill abre com padrões errados (Sempre + modelo Lite + 16:9) — veja o bloco Configurações obrigatórias.

4. ESCREVA o prompt via clipboard (não innerText) e CONFIRME — txtLen === prompt.length antes de enviar. Detalhes no bloco Fluxo abaixo.

5. ENVIE e confirme que o composer travou em disabled:

agent-browser --session $S click "button[aria-label='Iniciar geração']"
sleep 2
echo '(()=>{const c=document.querySelector("[contenteditable=true]");return c.contentEditable==="false"||c.getAttribute("aria-disabled")==="true"?"travado":"livre";})()' \
  | agent-browser --session $S eval --stdin

ESPERA: três estados, três condutas

Depois de enviar, o status na página passa por três fases. Confundi-las faz você abortar cedo (perder crédito) ou esperar demais (achar que travou quando já saiu).

EstadoTexto na telaConduta
Fila"X foi agendado e está na fila devido à alta demanda. Sinta-se à vontade para verificar o status daqui a alguns minutos."Espere. Pode levar de 1 a 30min. NÃO reenvie.
Gerando"Conceptualizing the Video" + ícone play_circle + percentualEspere. Botão "Parar" visível.
ProntoCard com <img alt="Miniatura do vídeo gerada"> aparece na gradeBaixe. Veja o bloco de download.

Limite máximo: 30 minutos na fila sem transição para "Gerando" = abortar. Medido em 02/10/2026: o Flow mostrou "alta demanda" por 45min em flow-enovalabs-pro, e quando moveu o status de fato o job já tinha consumido o crédito sem entregar nada. Sintoma: "alta demanda" >30min E o botão "Iniciar geração" da composição anterior continua disabled=true travado — não é fila real, é cota perdida.

Caminho de recuperação se travar:

# 1. Cancelar o job pendente (libera o composer para novo envio)
agent-browser --session $S click "button[aria-label='Parar']" 2>/dev/null
sleep 2
# 2. Se o composer não destravar, recarregue a página inteira (perde o projeto atual)
agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow"
# 3. Tente um clone paralelo
S=flow-<lane>-2  # ou -3, -4

Se o flow-enovalabs-pro-2/3/4 também estiver logado e na fila, use-o em paralelo (o Flow permite múltiplos perfis do mesmo login, diferente do Hub). Confirme o login: lane.sh take flow <lane> && agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow" — se cair no dashboard sem pedir login, está OK.

Polling curto, teto generoso:

T0=$(date +%s)
for i in $(seq 1 360); do                                # 30min × 6 = 360 × 5s
  STATE=$(echo '(()=>{const txt=document.body.innerText;
    if(/alta demanda/i.test(txt)) return "fila";
    if(/Conceptualizing|Criando/i.test(txt)) return "gerando";
    const imgs=document.querySelectorAll("img[alt=\\"Miniatura do vídeo gerada\\"]").length;
    if(imgs>0) return "pronto";
    return "?")()' \
    | agent-browser --session $S eval --stdin | tr -d '"' | tail -1)
  echo "  [$(( $(date +%s)-T0 ))s] $STATE"
  [ "$STATE" = "pronto" ] && break
  [ "$STATE" = "?" ] && [ $i -gt 6 ] && { echo "abort: composer travado sem estado"; break; }
  sleep 5
done

DOWNLOAD pelo CONTEÚDO — guarde antes, escolha o novo

vs[vs.length-1] não existe no Flow (não há <video> na grade). O Flow renderiza uma thumbnail (<img alt="Miniatura do vídeo gerada">) na grade; o vídeo real só aparece depois de abrir o card no modal e clicar em Baixar mídia. Logo, o caminho de download é diferente do Hub:

1. ANTES do envio, guarde a lista de thumbnails existentes:

BEFORE=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"Miniatura do vídeo gerada\\"]")].map(i=>i.src).join("|"))()' \
  | agent-browser --session $S eval --stdin | tr -d '"')

2. DEPOIS que pronto sair, encontre a thumbnail nova:

AFTER=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"Miniatura do vídeo gerada\\"]")].map(i=>i.src).join("|"))()' \
  | agent-browser --session $S eval --stdin | tr -d '"')
NEW=$(python3 -c "import sys;a=set('$AFTER'.split('|'));b=set('$BEFORE'.split('|'));print('|'.join(a-b))")

Se NEW vier vazio, o card ainda não apareceu — espere mais 10-30s e tente novamente.

3. Abra o modal do card novo e baixe 720p:

# clique no thumbnail novo
python3 -c "
import sys
srcs='$NEW'.split('|')
print('(()=>{const imgs=[...document.querySelectorAll(\"img[alt=\\\\

Individual skills in this repo

This repo contains 9 individual skills — each has its own dedicated page.

by-lua/video-editing

Coleta, pré-visualiza e entrega B-rolls com revisão humana e origem registrada. Use quando alguém pedir b-roll, vídeos de apoio, imagens de apoio, cutaways, inserts, footage, "um corte do X falando Y", um print da tela de um site ou de uma notícia, ou material para ilustrar um vídeo, Reel ou aula — buscando em YouTube, Instagram, TikTok, Wikimedia Commons, NASA ou bancos (Pexels, Pixabay), gerando prévias para revisão humana e entregando os trechos com origem e condições de uso. Also in English: collect B-roll, cutaways, inserts, supporting footage, stock video, screen grabs. Não serve para editar, montar ou renderizar o vídeo final. Not for editing or rendering the finished video.

by-lua/video-editing

Contorna bloqueio de Cloudflare, "Confirme que é humano", detecção de bot e telas de login em automação de browser. Sobe o Chromium do sistema com perfil persistente e porta CDP, e conecta o agent-browser nele em vez de deixar ele lançar o Chromium empacotado. Use sempre que o agent-browser empacar em desafio do Cloudflare, checkbox de verificação humana, "Just a moment", tela de bot detection, ou quando precisar automatizar site logado com várias contas ao mesmo tempo.

by-lua/video-editing

Escalonamento de baixo nivel do agent-browser. Use quando precisar de CDP cru: interceptar/inspecionar requests de rede, iframes cross-origin, shadow DOM, drag-and-drop, upload/download travado, print-as-PDF, dialogs nativos, ou quando um comando do agent-browser falhar duas vezes no mesmo passo. Padrao continua sendo agent-browser.

by-lua/video-editing

Porta de entrada ÚNICA de criativo de anúncio (Meta/TikTok) — vídeo, imagem estática ou carrossel. Faz a estratégia (briefing, matriz persona × dor/bolha, escolha de formato, quantidade por fase da conta, regras do Kevones 2026) e depois puxa a mecânica certa — `criativo-ads-video-orq` para vídeo, `modelagem-escalados` + `gpt-imagem-playwright` para estático/carrossel, `narracao-hub-tts` para voz. Use sempre que o usuário pedir criativo, anúncio, ad, leva de criativos, hook, variação de criativo, novo ângulo, "criativo de vídeo", "criativo estático", carrossel, banner de anúncio, UGC, modelar um criativo que está escalando, ou mencionar metodologia Kevones de criativo, bolhas, ângulos, gatilhos.

by-lua/video-editing

Mecânica de produção e edição de anúncios em vídeo, chamada por criativo-ads. Use para criativo de vídeo, UGC, hook novo, variação de vencedor, modelagem de escalados, Veo/Flow, cenas com imagem de referência, b-roll, gravação de tela, PiP, narração ou trilha. Cobre briefing, persona/ângulo/oferta, orçamento de palavras, prompts de continuidade/voz/lip-sync, QA de imagem e clipe, montagem, cortes por palavra e gesto, repetição, limpeza de áudio, volume, legendas e entrega. Modos: do zero, hook+body, bodies variados, modelagem Kevones e Vitrine Guiada. Delega geração às skills de browser; usa video-use para cortes, Remotion para composição/legenda, Hyperframes para motion e ffmpeg para medição/normalização/mix. A estratégia da leva vem de criativo-ads; motor e restrições seguem as regras atuais do corpo desta skill.

by-lua/video-editing

Gera imagens no ChatGPT usando o perfil de browser persistente já logado (sessão gpt). Aceita imagem de referência anexada para manter rosto, produto ou estilo, e gera até 10 imagens separadas por vez. Baixa os resultados direto para a pasta pedida. Use sempre que o usuário pedir para criar, gerar ou editar imagem no GPT/ChatGPT, pedir imagem de referência, mockup, cena, retrato, variação visual, ou disser "gera uma imagem".

by-lua/video-editing

MECÂNICA de estático/carrossel chamada pela skill `criativo-ads` (porta de entrada de todo criativo; estratégia e quantidade moram lá). Modela criativos de anúncio a partir de uma biblioteca local de 103 formatos que já estão escalando (87 estáticos, 16 vídeos, 47 categorias) — anexa a referência real no ChatGPT e adapta para a marca do usuário via pipeline de 12 prompts (brandkit, dossiê, matriz de ângulos, seleção de formato, leitura estrutural, copy, arte 1:1 1080×1080 (9:16 só se pedido), leva de headlines, reenquadramento, gate de QA, ponte para vídeo, nomenclatura). Use quando o usuário pedir criativo estático, modelar/clonar um criativo que está escalando, "modelagem de escalados", leva de anúncios, variação de headline, banco de formatos, biblioteca de anúncios, ou mencionar Antonio Ferriani, formatos escalados, antes e depois, print de WhatsApp, caixa de perguntas, Reclame Aqui, notícia, ilustração como formato de anúncio.

by-lua/video-editing

Gera narração/voz off em WAV pela API do NinjaVoice (NinjaBR Hub), sem browser e sem login — 82 vozes, português nativo, resposta síncrona. Cobre escolha de voz por nicho e gênero, quebra de texto acima de 2000 caracteres, geração em lote cena a cena, gate de validação do arquivo e mixagem com trilha de fundo no ffmpeg. Use sempre que precisar de narração para criativo de vídeo, voz off, VO, locução, áudio de anúncio, dublar um roteiro, ou quando o usuário mencionar NinjaVoice, TTS, text-to-speech, voz masculina/feminina para o criativo.

by-lua/video-editing

SLASH-COMMAND-ONLY. Invoke ONLY when the user explicitly types the literal `/watch-video` slash command. Never auto-trigger on phrases like "watch this video," "summarize this video," "take notes on this video," or on a bare YouTube URL. For ad-hoc YouTube questions, fetch the transcript directly (YouTube page or yt-dlp) and skim — do not run this heavyweight pipeline.

相关技能