Communitygithub.com

flow-video-playwright

Google Flow(labs.google/fx/pt/tools/flow)を使用した画像・動画生成の完全なメカニクス。パイプライン全体(送信→キュー→完了→ダウンロード→ゲート)をカバーし、メディアの取得、検証、プロジェクトへの移動を自動化します。

flow-video-playwright とは?

このスキルは、Google Flow(labs.google/fx/pt/tools/flow)を介した画像・動画生成の完全な自動化パイプラインを提供します。Omni 1.1 Flashモデルを使用し、プロンプトのみで画像と動画の両方を生成します。主な機能として、laneシステムによる並列セッション管理、クリップボード経由のプロンプト入力、生成ステータスのポーリング(キュー→生成中→完了)、新しいサムネイルを識別してコンテンツベースでダウンロードする仕組み、bt709色空間とオーディオが存在する場合の検証、そして生成されたメディアをプロジェクトのステージングディレクトリに移動する処理を備えています。このスキルは、Claude Code、Cursor、CodexなどのAIエージェントツールとの使用を想定して設計されており、Google Flow専用のプロファイル(`flow-enovalabs-pro`、ポート9265)を使用します。元の`hub-video-playwright`スキルの代替として機能し、Hubの有効期限が切れた場合やクォータ不足の場合に使用します。並列処理のために複数のクローン(-2、-3、-4)がサポートされています。

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

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

プレビュー

スキル README より

flow-video-playwright preview

ドキュメント

HUB無効化(2026年10月2日、ユーザー指示による): 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年9月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年9月30日に本番環境で確認済み。Veo 3.1よりもクレジット消費が少ない。マルチモーダルで、画像と動画の両方をプロンプトのみ(アップロードなし)で生成します。

生成前に、設定(tuneボタン、aria-label「設定」)を開き、以下を確認してください:

  • 生成前に確認する = しない(デフォルトは「常に」— クレジットを消費し、そのままにしておくと送信をブロックします)。
  • デフォルトの動画生成モデル = Omni 1.1 Flash。
  • 動画のアスペクト比 = crop_9_16 9:16(radio role="radio"、リスト内の2番目のcrop_9_16、現在のマッピングではインデックス10)。

保存します。

フロー(2026年10月1日確認済みのステップバイステップ)

  1. プロジェクトを作成:ダッシュボード → 「新規プロジェクト」ボタン → URLが https://flow.google.com/project/<uuid> になります。
  2. コンポーザー:[contenteditable=true]。クリップボード経由で貼り付け、innerTextは使用しないでください — 2026年10月1日測定:
    • c.innerText = prompt; c.dispatchEvent(new InputEvent('input')) はテキストを貼り付けますが、「生成開始」ボタンがクリック時にdisabledになりません(Materialの「テキスト変更」ハンドラがトリガーされません)。2回クリックしても何も生成されません。
    • 正しい方法: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='生成開始']。ボタンが disabled=true になると = 送信受理。テキスト「キューに入りました」が表示され、その後「動画を概念化中」 / 「play_circle」 + パーセンテージが表示されます。
  4. 待機:ステータスが「動画を概念化中」(Flow)または「画像を作成中」(ChatGPT)に変わります。「停止」ボタンは生成中のみ表示されます。画像プロンプトのみで約50秒、動画の場合はそれ以上かかります。
  5. 結果:<img src="blob:https://flow.google.com/..."> が9:16の場合 naturalWidth>800。fetch+blob+<a download>(ネイティブDOMリンク)でダウンロードします。

必須設定(初回送信前)

button[aria-label='設定'](tuneアイコン)を開く:

  • 生成前に確認する = しない(ラジオグループ mat-radio-group-2、value=2)。デフォルトは「常に」— クレジットを消費し、自動送信をブロックします。
  • デフォルトの動画生成モデル = Omni 1.1 Flash(コンボボックス)。
  • 動画のアスペクト比 = crop_9_16 9:16(button role="radio"、リスト内の2番目のcrop_9_16、インデックス10)。

input[type=radio]を直接操作してラジオボタンを設定します(mat-radio-buttonをクリックしても入力は反転しません):

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

// 9:16動画(2番目の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() === '保存').click();

参照アップロード — 2026年9月30日ブロック済み

「メディアを追加」パネルの「メディアを送信」ボタンは、OSネイティブのファイルダイアログを開きます(CDP Page.fileChooserOpened、DOM内の<input type=file>ではありません)。agent-browser uploadは黙って失敗します。

回避策:プロンプトのみで生成します。OmniFlashはマルチモーダルで、説明的なプロンプトを解釈します。アップロードによる参照画像への忠実度は劣りますが、ファイルダイアログを回避できます。プロンプトのみで不十分な場合は、Page.setInterceptFileChooserを使用してbrowser-harnessをスケールアップします — 本番環境ではテストされていません。

プロンプトのみ — 基本テンプレート

A <ショットタイプ> shot of <構図>. <主語> doing <動作(単一、スロー)>.
<背景>. <照明>. Shot in vertical 9:16 aspect ratio. Photorealistic,
shot on iPhone, no text, no watermark. <アンチモーフィング>.

必須アンチモーフィング(FlowにはNEGATIVEフィールドが別途ないので、同じ文字列に含めます):

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

2026年9月30日確認:シーン1(女性の手がピンクのリブ生地を引っ張る、背景は白いベッド)がOmniFlashで約50秒で生成、出力941x1672、説得力のあるiPhone UGCルック。

ダウンロード(2026年10月1日確認)

動画はグリッドに<video>をレンダリングしません — モーダルでカードを開いた後にのみ表示されます。フロー:

  1. サムネイルをクリック(img[alt="生成された動画のサムネイル"])— プレーヤーとヘッダーボタンがあるモーダルが開きます。
  2. button[aria-label="メディアをダウンロード"]をクリック(ヘッダーのダウンロードアイコン)。
  3. 品質メニューが開きます:270p(GIF)、720p(元のサイズ)、1080p(高品質)、4K(高品質)。
  4. 正しいオプションをDOMから直接クリック:
    Array.from(document.querySelectorAll('button'))
      .find(b => b.innerText.trim() === '720p\n元のサイズ').click();
    
  5. ファイルは Flow タイトル名 + タイムスタンプ(Hands_lifting_brown_skirt_fabric_20261001180016.mp4)で ~/Downloads/ に保存されます。プロジェクトのステージングディレクトリに移動し、名前を変更します。

画像の場合(動画なしで直接生成): <img src="blob:https://flow.google.com/..."> が生成後にグリッドに表示されます。fetch+blob+<a download> または直接スクリーンショットで保存します。

ダウンロード後の色ゲート

Flowからのメディアのほとんどは color_range/color_space/color_transfer/color_primaries = unknown で出力されます — 2026年10月1日に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 である必要があります。

Laneを取得する — 最初に、常に

複数のClaudeがこの同じブラウザを使用しています。Laneがないと、すべてが同じプロジェクトに落ちます:一方の「プロジェクト作成」が他方を上書きし、生成結果が混ざります。

~/.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 に送り、laneを壊します)。終了時:~/.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に放置されません。

送信チェックリスト — 「生成開始」をクリックする前に実行

Flowは生成間で何もクリアしません(Hubと同じ):コンポーザーのプロンプトが貼り付いたままになり、モデル/アスペクト比が送信後の再レンダリングでリセットされる可能性があります。以下の順序は、各ステップが適切でないと既にクレジットを消費した(無効な生成でも課金される)ために存在します。

1. 新しいプロジェクトを作成(または既存のものに切り替え)— 各バッチは新しいプロジェクトを使用します。 ダッシュボードの「新規プロジェクト」ボタン。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='生成開始']"
sleep 2
echo '(()=>{const c=document.querySelector("[contenteditable=true]");return c.contentEditable==="false"||c.getAttribute("aria-disabled")==="true"?"ロック":"フリー";})()' \
  | agent-browser --session $S eval --stdin

待機:3つの状態、3つの対応

送信後、ページ上のステータスは3つのフェーズを経ます。これらを混同すると、早期に中断して(クレジットを失う)か、待ちすぎて(既に完了しているのにスタックしたと思う)しまいます。

状態画面のテキスト対応
キュー"X はスケジュールされ、需要が高いためキューに入れられました。数分後にステータスを確認してください。"待機。 1〜30分かかる場合があります。再送信しないでください。
生成中"動画を概念化中" + アイコン play_circle + パーセンテージ待機。 「停止」ボタンが表示されます。
完了カードに <img alt="生成された動画のサムネイル"> がグリッドに表示されるダウンロード。 ダウンロードブロックを参照してください。

ハードリミット:キューで30分経過しても「生成中」に移行しない場合 = 中断。 2026年10月2日測定:Flowは flow-enovalabs-pro で「高需要」を45分間表示し、実際にステータスが変わったときには、ジョブは何も生成せずにクレジットを消費していました。症状:「高需要」が>30分続き、かつ前のコンポジションの「生成開始」ボタンが disabled=true のままロックされている — 実際のキューではなく、クォータロストです。

スタックした場合の回復手順:

# 1. 保留中のジョブをキャンセル(コンポーザーを解放して新しい送信を可能にする)
agent-browser --session $S click "button[aria-label='停止']" 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" — ログインを要求せずにダッシュボードに表示されればOKです。

短いポーリング、寛大な上限:

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 "キュー";
    if(/概念化|Criando/i.test(txt)) return "生成中";
    const imgs=document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]").length;
    if(imgs>0) return "完了";
    return "?")()' \
    | agent-browser --session $S eval --stdin | tr -d '"' | tail -1)
  echo "  [$(( $(date +%s)-T0 ))s] $STATE"
  [ "$STATE" = "完了" ] && break
  [ "$STATE" = "?" ] && [ $i -gt 6 ] && { echo "中断:状態なしでコンポーザーロック"; break; }
  sleep 5
done

コンテンツによるダウンロード — 以前を保存し、新しいものを選択

vs[vs.length-1] はFlowには存在しません(グリッドに<video>はありません)。Flowはグリッドにサムネイル(<img alt="生成された動画のサムネイル">)をレンダリングします。実際の動画は、モーダルでカードを開き、「メディアをダウンロード」をクリックした後にのみ表示されます。したがって、ダウンロード方法はHubとは異なります:

1. 送信の前に、既存のサムネイルのリストを保存します:

BEFORE=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]")].map(i=>i.src).join("|"))()' \
  | agent-browser --session $S eval --stdin | tr -d '"')

2. その後、完了 になったら、新しいサムネイルを見つけます:

AFTER=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]")].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=\\\"生成された動画のサムネイル\\\"]\")];'
      '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.

関連スキル