Communitygithub.com

by-lua/video-editing

Google Flow(labs.google/fx/pt/tools/flow)的完整機制 — 透過 Omni 1.1 Flash 提示產生圖片或影片,等待佇列/生成完成,根據內容(而非「最新卡片」)下載,驗證時長+bt709 色彩+音訊,並移至專案。涵蓋完整流程(送出→佇列→就緒→下載→閘門),而非僅僅點擊。在母技能(`tiktok-shop` 或 `criativo-ads-video-orq`)要求透過 Flow 產生影片時使用(Hub 過期時的替代方案)。使用 Profile `flow-enovalabs-pro`(連接埠 9265),已登入 Google 帳號 contato.inovalabsx;複製 -2/3/4 以平行處理。

video-editing 是什麼?

此技能為 AI 代理(例如 Claude Code、Cursor 等)提供與 Google Flow(labs.google/fx/pt/tools/flow)互動的完整自動化功能,用於產生圖片和影片。它涵蓋了從建立專案、透過剪貼簿貼上提示詞、設定模型偏好(Omni 1.1 Flash,9:16 比例)到提交任務、監控佇列狀態、以及以高精確度下載產出物的整個管道。執行的關鍵區別在於使用內容感知策略來識別新產生的媒體(避免競爭條件)並強制執行嚴格的驗證閘門,包括使用 FFmpeg 重新編碼為 BT.709 色彩空間,這是 AI 影片後製工作流程中的常見要求。此技能專為路徑不明的環境設計,使用獨特的 `lane.sh` 機制來管理共享瀏覽器狀態,防止多個代理實例之間的配置衝突。它支援平行執行使用 `flow-enovalabs-pro` 設定檔體的衍生環境,提供冗餘以應對佇列延遲或配額限制。此詳細文件包含對瀏覽器自動化(`agent-browser`)、DOM 操作和錯誤恢復的具體指導,使其成為需要可靠、生產級別 Google Flow 整合的開發者的強大工具。

相容平台✓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 已停用(2026/10/02,用戶指示): NinjaBR Hub 配額用盡,且 hub/hubv2/hubts 設定檔已被移除(備份於 ~/.agent-profiles/_removidos-hub-2026-10-02/)。請勿使用 Hub,請勿執行 hub-livre.sh(會報錯退出),請勿等待 Hub 設定檔釋放。圖片:ChatGPT — 如果一個帳號的上傳配額用完,請切換帳號:gpt-noelia-7-10* ↔ gpt-noelia.empt*。影片:Google Flow(flow-video-playwright)。

flow-video-playwright

透過 Google Flow(labs.google/fx/pt/tools/flow)產生圖片+影片的機制。當 Hub 過期時(於 2026/09/21 停止服務,參見 [[feedback-ninjabr-hub-acesso-expirado]])作為 hub-video-playwright 的替代方案。

設定檔

flow-enovalabs-pro(連接埠 9265),已登入 Google。在花費時間之前,先瀏覽並確認登入狀態:

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

如果出現登入畫面,請停止並通知用戶 — 憑證不在 .credentials.env 中。

模型

Omni 1.1 Flash — 已於 2026/09/30 在生產環境確認。消耗的點數比 Veo 3.1 少。它是多模態的:可直接從純文字提示產生圖片和影片,無需上傳。

在產生之前,開啟設定(tune 按鈕,aria-label "Configurações")並確保:

  • 產生前確認 = 永不(預設為「總是」— 會消耗點數,且如果保持「總是」會阻止發送)。
  • 預設影片產生模型 = Omni 1.1 Flash。
  • 影片比例 = crop_9_16 9:16(radio role="radio",清單中第二個 crop_9_16,在目前對應中索引為 10)。

儲存。

流程(已於 2026/10/01 逐步驗證)

  1. 建立專案:儀表板 → "Novo projeto" 按鈕 → URL 變成 https://flow.google.com/project/<uuid>。
  2. 作曲家:[contenteditable=true]。透過剪貼簿貼上,不要使用 innerText — 於 10/01 測量:
    • c.innerText = prompt; c.dispatchEvent(new InputEvent('input')) 會貼上文字,但點擊時「Iniciar geração」按鈕不會保持在 disabled 狀態(Material 的「文字已更改」處理程序未觸發)。點擊兩次不會產生任何結果。
    • 正確方法:agent-browser 的原生 clipboard write,然後在作曲家上按 Ctrl+A Ctrl+V:
      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"
      
    • 在發送前確認 txtLen === prompt.length。
  3. 發送:click button[aria-label='Iniciar geração']。按鈕鎖定為 disabled=true = 送出成功。會出現文字 "Na fila",接著是 "Conceptualizing the Video" / "play_circle" + 進度百分比。
  4. 等待:狀態變為 "Conceptualizing the Video"(Flow)或 "Criando imagem"(ChatGPT)。「停止」按鈕僅在生成期間出現。純提示圖片約需 50 秒,影片則更久。
  5. 結果:<img src="blob:https://flow.google.com/...">,當比例為 9:16 時 naturalWidth>800。透過 fetch+blob+<a download>(原生 DOM 連結)下載。

必要設定(首次發送前)

開啟 button[aria-label='Configurações'](tune 圖示):

  • 產生前確認 = 永不(radio group mat-radio-group-2,value=2)。預設為「總是」— 會消耗點數並阻止自動發送。
  • 預設影片產生模型 = Omni 1.1 Flash(combobox)。
  • 影片比例 = crop_9_16 9:16(button role="radio",清單中第二個 crop_9_16,索引 10)。

直接透過 input[type=radio] 設定 radio(點擊 mat-radio-button 不會切換 input):

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

// 9:16 影片(第二個 crop_9_16)
const r916 = Array.from(document.querySelectorAll('button[role=radio]'))
  .filter(b => b.innerText === 'crop_9_16\n9:16')[1];
r916.click();

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

參考上傳 — 已於 2026/09/30 封鎖

「Adicionar elementos」面板中的「Enviar mídia」按鈕會開啟作業系統的原生檔案對話方塊(CDP Page.fileChooserOpened,DOM 中無 <input type=file>)。agent-browser upload 會靜默失敗。

解決方案:僅使用提示詞進行生成。OmniFlash 是多模態的,可以解釋描述性提示。雖然不如上傳參考那麼精確,但避免了檔案對話方塊。如果僅使用提示詞不足夠,可考慮使用 Page.setInterceptFileChooser 擴充 browser-harness — 尚未在生產環境測試。

僅提示詞 — 基礎範本

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>.

必要防變形提示(Flow 沒有單獨的 NEGATIVE 欄位,請將其加入同一字串中):

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

已於 2026/09/30 驗證:場景 1(女性手拉粉色羅紋布料,白色床背景)在 OmniFlash 上約 50 秒生成,輸出為 941x1672,iPhone UGC 風格令人信服。

下載(已於 2026/10/01 驗證)

影片不會在網格中渲染 <video> — 只有在卡片於模態框中開啟後才會出現。流程如下:

  1. 點擊縮圖(img[alt="Miniatura do vídeo gerada"])— 開啟包含播放器和標題按鈕的模態框。
  2. 點擊 button[aria-label="Baixar mídia"](標題中的下載圖示)。
  3. 開啟品質選單:270p(GIF)、720p(Tamanho original)、1080p(Aprimorada)、4K(Aprimorada)。
  4. 直接透過 DOM 點擊正確選項:
    Array.from(document.querySelectorAll('button'))
      .find(b => b.innerText.trim() === '720p\nTamanho original').click();
    
  5. 檔案會下載到 ~/Downloads/,檔名為 Flow 標題 + 時間戳記(Hands_lifting_brown_skirt_fabric_20261001180016.mp4)。移動到專案的暫存區並重新命名。

對於圖片(直接生成,無影片):<img src="blob:https://flow.google.com/..."> 在生成後會出現在網格中。透過 fetch+blob+<a download> 或直接截圖儲存。

下載後色彩閘門

幾乎所有來自 Flow 的媒體都含有 color_range/color_space/color_transfer/color_primaries = unknown — 已於 2026/10/01 在 Flow Omni 1.1 Flash 上確認。feedback-metadado-cor-video-final 閘門會拒絕。在將片段標記為就緒之前,重新編碼為 bt709:

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

使用 ffprobe -show_entries stream=color_* 檢查 — 4 個欄位都必須是 bt709/tv。

取得路徑 — 永遠是第一件事

多個 Claude 實例共用同一個瀏覽器。沒有路徑,所有人都會掉進同一個專案:一個實例的 criar projeto 會覆蓋另一個的,導致生成結果錯亂。

~/.claude/bin/lane.sh take flow <lane>      # 例如:lane.sh take flow pov-bella
S=flow-<lane>                               # 從這裡開始,在所有指令中使用 $S

持久化設定檔 ~/.agent-profiles/flow-enovalabs-pro,連接埠 9265,URL https://labs.google/fx/pt/tools/flow。永遠不要使用 agent-browser open、press Escape(會將分頁導向 about:blank 並破壞路徑)。完成後:~/.claude/bin/lane.sh drop flow <lane>。

Flow 的下載區域是 FLOW,不是 HUB 也不是 PLAYWRIGHT。在一開始匯出一次:

export LANE_AREA=FLOW

檔案從 Flow 輸出時帶有標題 + 時間戳記(例如:Hands_lifting_brown_skirt_fabric_20261001180016.mp4),下載到 ~/Downloads/,然後 lane.sh collect 會將其移動到 ~/Downloads/FLOW/$LANE/ → 專案資料夾。Downloads 中不會留下任何檔案。

發送檢查清單 — 在每次點擊「Iniciar geração」之前執行

Flow 不會在生成之間清除任何內容(與 Hub 相同):作曲家的提示會殘留,模型/比例可能會在發送後的重新渲染中被重置。以下順序之所以存在,是因為任何步驟的錯位都已經消耗了點數(即使生成無效也會扣配額)。

1. 建立新專案(或切換到現有專案) — 每批使用一個專案。 儀表板中的 "Novo projeto" 按鈕。URL 變成 https://flow.google.com/project/<uuid>。重用舊專案會累積垃圾,並混淆下載的 src 差異(見下文)。

2. 清除新專案的作曲家:

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

確認:

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

3. 檢查設定: 「產生前確認」= 永不,模型 = Omni 1.1 Flash,比例 = crop_9_16 9:16。技能開啟時預設是錯誤的(總是 + Lite 模型 + 16:9)— 參見必要設定區塊。

4. 透過剪貼簿寫入提示(不要用 innerText)並檢查 — 發送前確保 txtLen === prompt.length。詳細資訊請參閱下方流程區塊。

5. 發送並確認作曲家已鎖定為 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"?"travao":"livre";})()' \
  | agent-browser --session $S eval --stdin

等待:三種狀態,三種應對方式

發送後,頁面上的狀態會經歷三個階段。混淆它們會導致您過早放棄(浪費點數)或等待過久(以為當機但實際上已完成)。

狀態螢幕上的文字應對方式
佇列"X 已排程並因需求量大而處於佇列中。請隨時在幾分鐘後檢查狀態。"等待。 可能需要 1-30 分鐘。請勿重新發送。
生成中"Conceptualizing the Video" + play_circle 圖示 + 進度百分比等待。 可見「停止」按鈕。
就緒網格中出現帶有 <img alt="Miniatura do vídeo gerada"> 的卡片下載。 參見下載區塊。

硬性限制:在佇列中超過 30 分鐘未轉換為「生成中」= 放棄。 已於 2026/10/02 測量:Flow 在 flow-enovalabs-pro 上顯示「高需求量」達 45 分鐘,當狀態實際移動時,工作已消耗了點數但未產出任何內容。症狀:"高需求量" >30 分鐘,且上一個組合的「Iniciar geração」按鈕仍保持 disabled=true 鎖定 — 這不是真正的佇列,而是配額已耗盡。

卡住時的恢復路徑:

# 1. 取消待處理的作業(釋放作曲家以供新發送)
agent-browser --session $S click "button[aria-label='Parar']" 2>/dev/null
sleep 2
# 2. 如果作曲家仍未解鎖,重新載入整個頁面(會遺失當前專案)
agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow"
# 3. 嘗試平行複製
S=flow-<lane>-2  # 或 -3, -4

如果 flow-enovalabs-pro-2/3/4 也已登入並在佇列中,請平行使用它們(Flow 允許同一帳號的多個設定檔,與 Hub 不同)。確認登入狀態:lane.sh take flow <lane> && agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow" — 如果直接進入儀表板而無需登入,則表示正常。

短輪詢,寬鬆上限:

T0=$(date +%s)
for i in $(seq 1 360); do                                # 30 分鐘 × 6 = 360 × 5 秒
  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

根據內容下載 — 先保存舊的,再選擇新的

Flow 中不存在 vs[vs.length-1](網格中沒有 <video>)。Flow 在網格中渲染一個縮圖(<img alt="Miniatura do vídeo gerada">);實際影片只有在在模態框中開啟卡片並點擊 Baixar mídia 後才會出現。因此,下載路徑與 Hub 不同:

1. 在發送之前,保存現有縮圖的清單:

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. 在 pronto 狀態出現之後,找到新的縮圖:

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))")

如果 NEW 為空,表示卡片尚未出現 — 請再等待 10-30 秒並重試。

3. 開啟新卡片的模態框並下載 720p:

# 點擊新縮圖
python3 -c "
import sys
srcs='$NEW'.split('|')
print('(()=>{const imgs=[...document.querySelectorAll(\"img[alt=\\\"Miniatura do vídeo gerada\\\"]\")];'
      'const t=imgs.find(i=>i.src===\\

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.

相關技能