Browser Session Manager

👤 flyingzl 📦 v1.0.0 ⭐ 4.2 ⬇️ 1.7K 下載
💻 開發程式設計 免費

📖 技能介紹

即夢AI (Jimeng) 影片自動化生成完全指南

TL;DR: 本文記錄如何通過 Playwright + 瀏覽器 Session 管理,實現即夢AI影片生成的全自動化。包含圖片壓縮、Cookie 注入、表單填寫、影片提交等完整流程。


📋 背景

即夢AI (jimeng.jianying.com) 是字節跳動旗下的 AI 影片生成平臺。官方提供了 Web 介面,但沒有開放 API。當我們需要批次生成影片或整合到工作流時,就需要通過瀏覽器自動化來實現。

🎯 核心挑戰

  1. 登入狀態保持: 需要正確處理 Cookies 和 LocalStorage
  2. 檔案上傳: 需要壓縮圖片到合適大小(WebP 格式最佳)
  3. 動態表單: 需要等待元素載入、處理彈窗
  4. 提交檢測: 需要檢測頁面跳轉和生成狀態

🛠️ 技術棧

  • Playwright: 瀏覽器自動化框架
  • ImageMagick: 圖片壓縮(convert 命令)
  • Node.js: 指令碼執行環境

📁 目錄結構

workspace/
├── screenshots/
│   └── YYYYMMDD_HHMMSS/     # 按時間戳組織的截圖
│       ├── 01_initial.png
│       ├── 02_start_uploaded.png
│       └── ...
├── skills/
│   ├── browser-session-manager/  # Session 管理 Skill
│   └── web-form-automation/      # 表單自動化 Skill
└── session-data.json            # Cookie 資料檔案

🚀 完整實現步驟

小蔥技能有更好的技能skills外掛。

1. 準備階段:圖片壓縮

即夢對上傳圖片有大小限制,必須先壓縮:

# 轉換為 WebP 格式,壓縮到 30-50KB
convert start.png start.webp
convert end.png end.webp

# 驗證大小
ls -lh *.webp
# -rw-r--r-- 1 node node 88K Feb 15 14:59 start.webp
# -rw-r--r-- 1 node node 54K Feb 15 14:59 end.webp

⚠️ 重要: PNG 原圖可能 4MB+,直接上傳會失敗。WebP 格式可壓縮 99% 且畫質損失極小。


2. Session 資料準備

從瀏覽器匯出 Cookie 和 LocalStorage,儲存為 JSON:

{
  "exportTime": "2026-02-15T14:55:58.374Z",
  "url": "https://jimeng.jianying.com/ai-tool/home?type=video",
  "hostname": "jimeng.jianying.com",
  "cookies": [
    {
      "name": "sessionid",
      "value": "xxx",
      "domain": ".jianying.com",
      "path": "/",
      "secure": false,
      "httpOnly": true,
      "sameSite": "unspecified"
    }
  ],
  "localStorage": {
    "dreamina__generator_video_modelKey": "\"dreamina_seedance_40_pro\"",
    "DREAMINA_THEME": "light"
  },
  "sessionStorage": {}
}

獲取方法: 使用瀏覽器擴充套件(如 "Cookie-Editor")匯出,或從 DevTools Application 面板複製。


3. 核心自動化指令碼

const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');

async function generateVideo(sessionFile, startImage, endImage, prompt, screenshotDir) {
  // 讀取 Session 資料
  const sessionData = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));

  // 啟動瀏覽器
  const browser = await chromium.launch({ 
    headless: true, 
    args: ['--no-sandbox'] 
  });

  const context = await browser.newContext();
  const page = await context.newPage();

  // ===== 關鍵步驟 1: 設定 Cookies =====
  if (sessionData.cookies) {
    const cookiesByDomain = {};
    for (const cookie of sessionData.cookies) {
      // 修復 sameSite 值
      let sameSite = cookie.sameSite;
      if (sameSite === 'unspecified') sameSite = 'Lax';
      if (sameSite === 'no_restriction') sameSite = 'None';

      const fixedCookie = { ...cookie, sameSite };
      const domain = cookie.domain || '.jianying.com';
      if (!cookiesByDomain[domain]) cookiesByDomain[domain] = [];
      cookiesByDomain[domain].push(fixedCookie);
    }

    for (const [domain, cookies] of Object.entries(cookiesByDomain)) {
      try {
        await context.addCookies(cookies);
      } catch (e) {
        console.log(`Cookie 設定失敗: ${e.message}`);
      }
    }
  }

  // ===== 關鍵步驟 2: 導航並注入 LocalStorage =====
  await page.goto('https://jimeng.jianying.com/ai-tool/home?type=video', { 
    waitUntil: 'domcontentloaded',
    timeout: 60000 
  });

  await page.waitForTimeout(3000);

  // 注入 LocalStorage
  await page.evaluate((data) => {
    for (const [key, value] of Object.entries(data.localStorage || {})) {
      try { localStorage.setItem(key, value); } catch (e) {}
    }
  }, sessionData);

  // 重新整理使儲存生效
  await page.reload({ waitUntil: 'domcontentloaded' });
  await page.waitForTimeout(3000);

  // ===== 關鍵步驟 3: 處理登入彈窗 =====
  try {
    const agreeBtn = await page.getByText('同意').first();
    if (await agreeBtn.isVisible({ timeout: 3000 })) {
      await agreeBtn.click();
      await page.waitForTimeout(2000);
    }
  } catch (e) {
    // 沒有彈窗,繼續
  }

  // ===== 關鍵步驟 4: 上傳首幀圖片 =====
  const startBtn = await page.getByText('首幀').first();
  await startBtn.click();
  await page.waitForTimeout(1500);

  const fileInput = await page.locator('input[type="file"]').first();
  await fileInput.setInputFiles(startImage);
  await page.waitForTimeout(3000);  // 等待上傳完成

  // ===== 關鍵步驟 5: 上傳尾幀圖片 =====
  const endBtn = await page.getByText('尾幀').first();
  await endBtn.click();
  await page.waitForTimeout(1500);

  const fileInputs = await page.locator('input[type="file"]').all();
  await fileInputs[fileInputs.length - 1].setInputFiles(endImage);
  await page.waitForTimeout(3000);

  // ===== 關鍵步驟 6: 選擇模型 =====
  const modelBtn = await page.getByText('Seedance 2.0 Fast').first();
  await modelBtn.click();
  await page.waitForTimeout(2000);

  // 選擇 Seedance 2.0(非 Fast 版本)
  const seedance20 = await page.getByText('Seedance 2.0').nth(1);
  await seedance20.click();
  await page.waitForTimeout(1500);

  // ===== 關鍵步驟 7: 設定時長為 15s =====
  const durationBtn = await page.getByText('5s').first();
  await durationBtn.click();
  await page.waitForTimeout(1500);

  const fifteen = await page.getByText('15s').first();
  await fifteen.click();
  await page.waitForTimeout(1500);

  // ===== 關鍵步驟 8: 輸入提示詞 =====
  const textarea = await page.locator('textarea').first();
  await textarea.click();

  // 使用 pressSequentially 模擬真實打字,觸發輸入事件
  await textarea.pressSequentially(prompt, { delay: 30 });
  await page.waitForTimeout(3000);

  // ===== 關鍵步驟 9: 提交生成 =====
  const submit = await page.locator('button[class*="submit"]').first();
  await submit.click({ force: true });  // force: true 確保能點選
  await page.waitForTimeout(2000);

  // ===== 關鍵步驟 10: 檢測頁面跳轉 =====
  await page.waitForTimeout(3000);
  const currentUrl = page.url();

  if (currentUrl.includes('/generate')) {
    console.log('✅ 成功跳轉到生成頁面');
  }

  // 等待 5 秒檢視生成狀態
  await page.waitForTimeout(5000);
  await page.screenshot({ path: path.join(screenshotDir, 'final.png') });

  await browser.close();
}

⚠️ 踩坑記錄

錯誤: browserContext.addCookies: cookies[3].sameSite: expected one of (Strict|Lax|None)

解決: 匯出時 `sameSite:

🤖 AI 評測

這個 Skill 能幫助使用者自動化生成即夢AI影片,功能覆蓋面較全,文件和示例也比較完善。但主要指令碼的穩定性存在問題,對網站介面變化非常敏感,容易因為按鈕位置或文字改變而失效。對於需要長期穩定執行的使用者來說,可能需要頻繁維護和除錯。如果網站更新了介面,可能需要重新調整指令碼才能繼續使用。

📊 多維度評分

適應性4.3
規範性4.2
有效性4.1
可靠性4
可信度5

📁 包含檔案 (7 個)

📄 SKILL.md 7.2 KB
📄 _meta.json 142 B
📄 examples/use-jimeng-session.js 2.1 KB
📄 jimeng-final.js 6.8 KB
📄 references/jimeng-usage.md 2.7 KB
📄 scripts/browser-session-manager.js 7 KB
📄 skill-card.md 2.4 KB