{
  "name": "Sora 2 Pro Talking-Head Video Generator | AI \u6570\u5b57\u4eba\u53e3\u64ad\u89c6\u9891\u751f\u6210\uff08Sora 2 Pro + MiniMax TTS + FFmpeg \u81ea\u52a8\u5408\u6210\uff09",
  "active": false,
  "nodes": [
    {
      "parameters": {
        "content": "## Sora 2 Pro \u6570\u5b57\u4eba\u53e3\u64ad\u89c6\u9891\u751f\u6210 | Talking-Head Video Generator\n\n**Built:** 2026-01\u3000|\u3000**Nodes:** 73\n\n**Model stack:** sora-2-pro-text-to-video, sora-2-text-to-video, gemini-3-pro-preview, gemini-3-flash-preview, claude-sonnet-4.5, gpt-5.2, MiniMax speech-2.6-hd\n\n**External services:** api.kie.ai, api.minimaxi.com\n\nAll credentials are `YOUR_*` placeholders \u2014 fill them in before the first run.\nSetup guide and placeholder reference: see the repository README.\n\n---\n\n## \u4e2d\u6587\u8bf4\u660e\n\n**\u6784\u5efa\u65f6\u95f4\uff1a** 2026-01\u3000|\u3000**\u8282\u70b9\u6570\uff1a** 73\n\n**\u6a21\u578b\u6808\uff1a** sora-2-pro-text-to-video, sora-2-text-to-video, gemini-3-pro-preview, gemini-3-flash-preview, claude-sonnet-4.5, gpt-5.2, MiniMax speech-2.6-hd\n\n**\u5916\u90e8\u670d\u52a1\uff1a** api.kie.ai, api.minimaxi.com\n\n\u6240\u6709\u51ed\u8bc1\u90fd\u662f `YOUR_*` \u5360\u4f4d\u7b26\uff0c\u9996\u6b21\u8fd0\u884c\u524d\u8bf7\u5148\u586b\u597d\u3002\n\u90e8\u7f72\u6b65\u9aa4\u548c\u5360\u4f4d\u7b26\u5bf9\u7167\u8868\u89c1\u4ed3\u5e93 README\u3002\n",
        "height": 640,
        "width": 760,
        "color": 4
      },
      "id": "snapshot-meta-sora2-ta",
      "name": "Overview | \u5de5\u4f5c\u6d41\u8bf4\u660e",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -13136,
        -292
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "3351ae7a-e4c2-48c8-87ad-dd4c5f380f5c",
              "name": "=\u7247\u6bb5",
              "type": "string",
              "value": "=cap:{{ $runIndex + 1 }}\nfilename:{{ $json.response.filename }}\nfile_url:{{ $json.response.file_url }}"
            }
          ]
        },
        "options": {}
      },
      "id": "a292f8d2-fa4f-4a29-bbbb-ab3a11e14fad",
      "name": "Edit Fields4",
      "type": "n8n-nodes-base.set",
      "position": [
        -6208,
        384
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/s3/upload",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "x-api-key",
              "value": "nca-api-key-2024"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"file_url\": \"{{ $json.videoUrl }}\",\n  \"filename\": \"cap{{ $json.index + 1 }}_{{ $('code-5').all()[$json.index].json['\u5206\u955c'].shot_id }}.mp4\",\n  \"public\": true\n}",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 10
            }
          }
        }
      },
      "id": "9abd757e-751c-4bee-be7d-53e51955f7d5",
      "name": "\u4e0a\u4f20\u5230n8n-storage\u687617",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -6448,
        384
      ],
      "typeVersion": 4.2
    },
    {
      "parameters": {
        "amount": 55
      },
      "id": "aacd1c06-135e-4199-97ed-ceef2050a494",
      "name": "Wait 30s1",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        -8960,
        432
      ]
    },
    {
      "parameters": {
        "url": "https://api.kie.ai/api/v1/jobs/recordInfo",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "taskId",
              "value": "={{ $json.task_Id }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_KIE_API_KEY"
            }
          ]
        },
        "options": {}
      },
      "id": "e3f5458c-ef64-49b8-bfe2-58f26e38d473",
      "name": "HTTP - Check Video Status1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -8272,
        432
      ]
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst videoUrls = items\n  .filter(item => item.json.video_url)\n  .map(item => ({\n    json: {\n      index: item.json.index,\n      shot_id: item.json.shot_id,\n      videoUrl: item.json.video_url\n    }\n  }));\n\nif (videoUrls.length === 0) {\n  throw new Error('\u6ca1\u6709\u627e\u5230\u4efb\u4f55\u89c6\u9891URL');\n}\n\nconsole.log(`\u6210\u529f\u63d0\u53d6 ${videoUrls.length} \u4e2a\u89c6\u9891URL`);\n\nreturn videoUrls;"
      },
      "id": "1d6f4280-6f5c-44b1-8afe-e02da5711de7",
      "name": "Code - Get Video URL1",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -6896,
        384
      ]
    },
    {
      "parameters": {
        "jsCode": "// n8n Code Node: Flatten storyboard shots into standard items\n// Compatible with both:\n// 1) storyboard.scenes[].shots[]\n// 2) storyboard.shots[] at top level\n\nfunction stripCodeFences(s) {\n  if (typeof s !== \"string\") return s;\n  return s\n    .replace(/```json\\s*/gi, \"\")\n    .replace(/```\\s*/g, \"\")\n    .trim();\n}\n\nfunction safeParseJSON(maybeString) {\n  if (typeof maybeString === \"object\" && maybeString !== null) return maybeString;\n  if (typeof maybeString !== \"string\") {\n    throw new Error(\"AI Agent output is neither string nor object.\");\n  }\n  const cleaned = stripCodeFences(maybeString);\n  try {\n    return JSON.parse(cleaned);\n  } catch (e) {\n    // Provide a more helpful error message\n    throw new Error(\"Failed to JSON.parse AI Agent output. Error: \" + e.message);\n  }\n}\n\nconst input = $input.first().json;\n\n// AI Agent typically returns: { output: \"{...json...}\" }\nconst storyboard = safeParseJSON(input.output ?? input);\n\n// Prepare scene defaults (used if shots are top-level)\nconst scenes = Array.isArray(storyboard.scenes) ? storyboard.scenes : [];\nconst defaultScene = scenes[0] ?? {};\n\nconst defaultSceneName =\n  defaultScene.scene_name ||\n  defaultScene.sceneName ||\n  storyboard.scene_name ||\n  storyboard.sceneName ||\n  \"\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\";\n\nconst defaultLocation =\n  defaultScene.location ||\n  storyboard.location ||\n  \"\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\";\n\n// Collect shots (from either nested or top-level)\nlet collected = [];\n\n// Case B: top-level shots\nif (Array.isArray(storyboard.shots) && storyboard.shots.length > 0) {\n  collected = storyboard.shots.map((shot) => ({\n    __scene: defaultScene,\n    __shot: shot,\n  }));\n} else {\n  // Case A: scenes[].shots[]\n  for (const scene of scenes) {\n    if (Array.isArray(scene.shots)) {\n      for (const shot of scene.shots) {\n        collected.push({ __scene: scene, __shot: shot });\n      }\n    }\n  }\n}\n\n// Fail fast if nothing found\nif (!collected.length) {\n  const keys = Object.keys(storyboard || {}).join(\", \");\n  throw new Error(\n    `No shots found. Expected storyboard.shots[] or storyboard.scenes[].shots[]. Top-level keys: ${keys}`\n  );\n}\n\n// Flatten to the downstream \"standard\" shot object\nreturn collected.map(({ __scene, __shot }, idx) => {\n  const scene = __scene || {};\n  const shot = __shot || {};\n\n  const narrative = shot.narrative || {};\n  const visual = shot.visual || {};\n  const kve = visual.key_visual_elements || {};\n  const camera = visual.camera || {};\n  const perf = shot.performance || {};\n\n  // Some outputs might not provide shot_id; generate a fallback\n  const fallbackShotId = `S${String(idx + 1).padStart(2, \"0\")}`;\n\n  return {\n    json: {\n      // \u57fa\u7840\u4fe1\u606f\n      shot_id: shot.shot_id || fallbackShotId,\n      time_code: shot.time_code || \"\",\n      duration_seconds: shot.duration_seconds ?? 15,\n      scene_name: scene.scene_name || scene.sceneName || defaultSceneName,\n      location: scene.location || defaultLocation,\n\n      // \u6545\u4e8b\u5185\u5bb9\n      story_beat: narrative.story_beat || \"\",\n      voiceover: narrative.voiceover || \"\",\n      dialogue: narrative.dialogue || [],\n      sound_fx: narrative.sound_fx || \"\",\n      is_opening: narrative.is_opening ?? false,\n      is_ending: narrative.is_ending ?? false,\n\n      // \u89c6\u89c9\u63cf\u8ff0\n      image_prompt: visual.image_prompt || \"\",\n      subject: kve.subject || \"\",\n      action: kve.action || \"\",\n      environment: kve.environment || \"\",\n      lighting: kve.lighting || \"\",\n      mood: kve.mood || \"\",\n      color_scheme: kve.color_scheme || \"\",\n\n      // \u955c\u5934\u53c2\u6570\n      shot_type: camera.shot_type || \"\",\n      angle: camera.angle || \"\",\n      movement: camera.movement || \"\",\n      focus: camera.focus || \"\",\n\n      // \u8868\u6f14\u7ec6\u8282\n      expression: perf.expression || \"\",\n      gesture: perf.gesture || \"\",\n      posture: perf.posture || \"\",\n      eye_contact: perf.eye_contact || \"\",\n\n      // \u989d\u5916\u4fdd\u7559\uff1a\u7528\u4e8e\u540e\u7eed\u66f4\u5f3a\u63a7\u5236\uff08\u4e0d\u5f71\u54cd\u539f\u6d41\u7a0b\uff09\n      overlays: visual.overlays || [],\n      continuity: shot.continuity || {},\n      timing_plan: shot.timing_plan || [],\n      meta: storyboard.meta || {},\n      quality_check: storyboard.quality_check || {},\n    },\n  };\n});\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -10704,
        432
      ],
      "id": "47b8bb5a-2681-49f0-ae06-3de697989df1",
      "name": "\u8f93\u51fa\u6240\u6709\u5206\u955c"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.allDone }}",
                    "rightValue": "success",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    },
                    "id": "115c749b-cbbe-4ed7-baa1-1314e9279fbc"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "4fe86652-6ffb-456d-a955-3291bf8c6ecd",
                    "leftValue": "={{ $json.hasRetryable }}",
                    "rightValue": "waiting",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "d7478896-711b-44c6-b1d5-708d072aa845",
                    "leftValue": "={{ $json.shouldContinue }}",
                    "rightValue": "fail",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "d42a71c0-921d-4c7c-b44d-2bb3c78e1aff",
                    "leftValue": "=",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        -7472,
        400
      ],
      "id": "b343a112-ee6b-499a-a41a-83872a376994",
      "name": "Switch"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=This shot failed with complex prompt. Generate a simpler but VISUALLY CONSISTENT prompt.\n\n[SHOT DATA]\nShot ID: {{ $json['\u5206\u955c'].shot_id }}\nStory Beat: {{ $json['\u5206\u955c'].story_beat }}\nVoiceover (Mandarin): {{ $json['\u5206\u955c'].voiceover }}\nExpression: {{ $json['\u5206\u955c'].expression || 'confident, natural' }}\nGesture: {{ $json['\u5206\u955c'].gesture || 'subtle hand movements' }}\nIs Opening: {{ $json['\u5206\u955c'].is_opening }}\nIs Ending: {{ $json['\u5206\u955c'].is_ending }}\n\n[CAMERA - MUST MATCH PRIMARY]\nShot Type: {{ $json['\u5206\u955c'].shot_type || 'Medium Shot' }}\nAngle: {{ $json['\u5206\u955c'].angle || 'Eye Level' }}\nMovement: {{ $json['\u5206\u955c'].movement || 'Static' }}\n\n[CONTINUITY - CRITICAL]\nPrevious shot exit state: {{ $json.prev_anchor || 'N/A (first shot)' }}\nNext shot entry state: {{ $json.next_anchor || 'N/A (last shot)' }}\nSeries Lock: {{ $json.series_lock }}\n\n[VOICEOVER ADJUSTMENT]\n- Count characters in voiceover (Chinese chars only, exclude punctuation)\n- If > 55 chars: Simplify to keep core message, target 40-55 chars\n- If < 40 chars: Add natural filler words or keep as-is\n- Speech must complete by 9.5s\n\n[CRITICAL REQUIREMENTS]\n1. Camera: MEDIUM SHOT only - NOT close-up, NOT wide - must match other shots\n2. Position: Character at DEAD CENTER - no drift left/right\n3. Scene: EXACT same background - gray sofa, KAWS figurines, abstract painting, wooden staircase\n4. Hair: CHESTNUT BROWN only - no color change\n5. Props: NO desk, NO table, NO new objects\n6. Continuity: Entry state matches prev_anchor, exit state matches next_anchor\n7. Timing: Voiceover 40-55 chars, ends by 9.5s\n8. Output plain English prompt, video dialogue in Mandarin Chinese\n\n[WHY CONSISTENCY MATTERS]\nThis video will be concatenated with other shots. Any change in:\n- Camera distance/angle \u2192 visible jump cut\n- Character position \u2192 jarring shift\n- Scene elements \u2192 continuity break\n- Hair color \u2192 character inconsistency\n\nGenerate a stable, simplified prompt that maintains VISUAL CONSISTENCY with the series.",
        "options": {
          "systemMessage": "=## Role\nYou are a \"stability-first\" video prompt generator. Activated when the primary prompt fails. \nYour goal: generate simpler but CONSISTENT prompts that match the primary agent's visual style.\n\n## Core Principle\nConsistency > Complexity | Stability > Detail | Match Primary Agent > Simplify Everything\n\n---\n\n## CRITICAL: INHERIT FROM PRIMARY AGENT\n\nYou MUST maintain visual consistency with the primary agent's output:\n1. SAME camera shot type (medium shot, eye-level, static)\n2. SAME scene composition (exact same background elements)\n3. SAME character position (dead center of frame)\n4. SAME lighting setup (bright soft key light, f/2.8)\n5. SAME anchor timing (0.0-0.5s in, 8.5-9.0s out)\n\nThe only difference: your prompt is SIMPLER in structure, not DIFFERENT in visuals.\n\n---\n\n## ABSOLUTE LOCKS (Never Violate)\n\n### 1. Camera Lock\u3010CRITICAL FOR CONSISTENCY\u3011\n- Shot Type: MEDIUM SHOT (waist to head visible, NOT close-up, NOT wide shot)\n- Angle: EYE-LEVEL (camera at subject's eye height)\n- Movement: COMPLETELY STATIC (no pan, no tilt, no zoom, no dolly, no shake)\n- Framing: Character occupies center 40% of frame width\n- DO NOT change to close-up, DO NOT change to wide shot\n\n### 2. Character Position Lock\n- Character MUST sit at DEAD CENTER of frame\n- NO position drift (no left shift, no right shift, no standing, no leaning out of frame)\n- Distance from camera: FIXED throughout (same as other shots in series)\n- Head position: Centered horizontally, upper third of frame vertically\n\n### 3. Appearance Lock\n- Hair: CHESTNUT BROWN (warm medium brown), long straight, center-parted, no bangs, chest-length\n- Hair color MUST NOT change to blonde, black, red, or any other shade\n- Outfit: Black crew-neck sweatshirt with white shoulder/sleeve panels, white collar trim\n- NO appearance changes (hair color, hairstyle, clothing, accessories)\n\n### 4. Scene Lock\u3010MUST MATCH PRIMARY AGENT EXACTLY\u3011\n- Setting: Home recording studio, modern minimalist style\n- Furniture: Light gray fabric sofa ONLY, character seated centrally\n- Background Left: Wooden staircase with black metal handrail\n- Background Right: White low cabinet with KAWS figurines (black-gray, red, gray) and purple vinyl record\n- Background Wall: Abstract painting with red, yellow, blue, green color blocks\n- Lighting: Bright soft key light from front, slight depth-of-field blur f/2.8\n- FORBIDDEN: NO desk, NO table, NO computer, NO phone, NO cup, NO additional props\n\n### 5. Continuity Lock\n- 0.0-0.5s: ANCHOR IN - static pose, mouth closed, hands resting on lap\n- 0.5-8.5s: Main performance with voiceover\n- 8.5-9.0s: ANCHOR OUT - return to static, mouth closed, hands at rest\n- Voiceover: 40-55 characters, must complete by 8.5s\n- Entry state must match prev_anchor (if provided)\n- Exit state must match next_anchor (if provided)\n\n---\n\n## Output Format\n- Plain text prompt in English, 1800-2500 characters\n- No code blocks, no JSON, no markdown\n- Character speaks Mandarin Chinese in the video\n\n## Output Template\n\n[VIDEO SPECS]\n16:9 landscape | 1920x1080 | 10 seconds | 24fps | Realistic live-action talking-head video\n\n[CAMERA LOCK - MUST MATCH SERIES]\nShot Type: MEDIUM SHOT (waist to head visible)\nAngle: Eye-level (camera at subject's eye height)\nMovement: Completely static, no camera movement whatsoever\nFraming: Character centered, occupying middle 40% of frame width\nDepth of Field: f/2.8, slight background blur\nCRITICAL: Maintain exact same framing as other shots in this series\n\n[SCENE LOCK - MUST MATCH SERIES]\nSetting: Home recording studio, modern minimalist living room corner\nMain Element: Light gray fabric sofa, character @your_persona seated at center\nBackground Left: Wooden staircase with black metal handrail (partially visible)\nBackground Right: White low cabinet displaying KAWS figurines and purple vinyl record\nBackground Wall: Abstract painting with red, yellow, blue, green color blocks\nLighting: Bright soft key light from front-center, warm tone\nFORBIDDEN: NO desk, NO table, NO additional furniture, NO new props\n\n[CHARACTER LOCK]\n@your_persona - young Asian female finance blogger, seated at exact center of frame\nHair: Chestnut brown (warm medium brown), long straight, center-parted, no bangs, chest-length\nCRITICAL: Hair color must stay chestnut brown - NO blonde, NO black, NO red, NO other colors\nOutfit: Black crew-neck sweatshirt with white shoulder/sleeve panels, white collar trim\nSkin: Fair, natural makeup, rose-tinted lips\nDemeanor: Confident, approachable, professional\nEyes: Maintain camera contact throughout\n\n[POSITION LOCK]\nCharacter Position: Dead center of frame, no drift allowed\nHorizontal: Exactly centered\nVertical: Head in upper third of frame\nDistance: Fixed, same as series standard\nCRITICAL: Position must not shift left, right, forward, or backward\n\n[CONTINUITY ANCHORS]\nEntry State (0.0-0.5s): {prev_anchor or \"Static seated pose, mouth closed, hands on lap, looking at camera\"}\nExit State (8.5-9.0s): {next_anchor or \"Return to rest, mouth closed, hands settling, stable pose\"}\n\n[PERFORMANCE - SIMPLIFIED]\n0.0-0.5s ANCHOR IN:\n- Pose: Static, seated, centered\n- Expression: Neutral ready\n- Hands: Resting on lap\n- Mouth: Closed\n- Eyes: Looking at camera\n\n0.5-8.5s MAIN ACTION:\n- Expression: {basic expression from input}\n- Gesture: {basic gesture from input, keep subtle}\n- Voiceover: \u300c{voiceover text, 40-55 chars}\u300d\n- Eyes: Maintain camera contact\n- Position: Remain centered, no drift\n\n8.5-9.0s ANCHOR OUT:\n- Pose: Settling to static\n- Expression: Neutral, relaxed\n- Hands: Returning to rest\n- Mouth: Closing naturally\n- Eyes: Maintained camera contact\n\n[DIALOGUE - MANDARIN CHINESE]\n\u300c{full voiceover text}\u300d\nWord Count: {count} characters (target: 40-55, excluding punctuation)\nTiming: Speech completes by 8.5s, final 0.5s is silent\n\n[NEGATIVE CONSTRAINTS - CRITICAL]\nCamera:\n- NO close-up shots\n- NO wide shots  \n- NO camera movement (pan, tilt, zoom, dolly)\n- NO angle changes\n- NO framing changes\n\nScene:\n- NO desk or table\n- NO additional props\n- NO scene transitions\n- NO background changes\n- NO lighting changes\n\nCharacter:\n- NO position drift from center\n- NO hair color changes (must stay chestnut brown)\n- NO outfit changes\n- NO standing up\n- NO exaggerated movements\n\nAudio:\n- NO speech after 8.5s\n- NO added dialogue beyond provided voiceover\n\n---\n\n## Processing Logic\n\n1. Extract camera/scene parameters from input - MUST match primary agent\n2. Extract voiceover - adjust to 40-55 characters if needed\n3. Extract prev_anchor/next_anchor - use for continuity\n4. Simplify performance to 3 phases only (anchor-in / main / anchor-out)\n5. Emphasize ALL visual locks repeatedly\n6. Output plain English prompt, video dialogue in Mandarin Chinese",
          "batching": {
            "batchSize": 5
          }
        }
      },
      "id": "a49ea9eb-1d10-4a57-968a-d1b8466cb6b7",
      "name": "\u515c\u5e95",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -8880,
        992
      ],
      "typeVersion": 3
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const currentData = $json;\nconst retryCount = (currentData.retryCount || 0) + 1;\n\nreturn {\n  json: {\n    ...currentData,  // \ud83d\udd11 \u4fdd\u7559\u6240\u6709\u5b57\u6bb5\uff0c\u5305\u62ec \u5206\u955c\u3001prev_anchor \u7b49\n    retryCount: retryCount,\n    retryLevel: retryCount,\n    index: currentData.index,\n    skipShot: retryCount > 3\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9296,
        912
      ],
      "id": "968ad7a0-e9d7-4a8d-85f6-ed0d94179b75",
      "name": "\u91cd\u8bd5\u8ba1\u6570"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.kie.ai/api/v1/jobs/createTask",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_KIE_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  model: \"sora-2-pro-text-to-video\",\n  input: {\n    prompt: $json.output,\n    aspect_ratio: \"landscape\",\n    n_frames: \"15\",\n    size: \"standard\",              \n    remove_watermark: true\n  },\n  callBackUrl: \"http://YOUR_N8N_HOST:5678/webhook/kie-sora-callback\"\n}) }}",
        "options": {}
      },
      "id": "e356824f-3448-4eb0-9436-bed7e5b30a63",
      "name": "HTTP - Create Video Task",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -9552,
        432
      ],
      "retryOnFail": true
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=This shot failed with complex prompt. Generate a simpler but VISUALLY CONSISTENT prompt.\n\n[SHOT DATA]\nShot ID: {{ $node[\"code-5\"].json['\u5206\u955c'].shot_id }}\nStory Beat: {{ $node[\"code-5\"].json['\u5206\u955c'].story_beat }}\nVoiceover (Mandarin): {{ $node[\"code-5\"].json['\u5206\u955c'].voiceover }}\nExpression: {{ $node[\"code-5\"].json['\u5206\u955c'].expression || 'confident, natural' }}\nGesture: {{ $node[\"code-5\"].json['\u5206\u955c'].gesture || 'subtle hand movements' }}\nIs Opening: {{ $node[\"code-5\"].json['\u5206\u955c'].is_opening }}\nIs Ending: {{ $node[\"code-5\"].json['\u5206\u955c'].is_ending }}\n\n[CAMERA - MUST MATCH PRIMARY]\nShot Type: {{ $node[\"code-5\"].json['\u5206\u955c'].shot_type || 'Medium Shot' }}\nAngle: {{ $node[\"code-5\"].json['\u5206\u955c'].angle || 'Eye Level' }}\nMovement: {{ $node[\"code-5\"].json['\u5206\u955c'].movement || 'Static' }}\n\n[CONTINUITY - CRITICAL]\nPrevious shot exit state: {{ $node[\"code-5\"].json.prev_anchor || 'N/A (first shot)' }}\nNext shot entry state: {{ $node[\"code-5\"].json.next_anchor || 'N/A (last shot)' }}\nSeries Lock: {{ $node[\"code-5\"].json.series_lock }}\n\n[VOICEOVER ADJUSTMENT]\n- Count characters in voiceover (Chinese chars only, exclude punctuation)\n- If > 55 chars: Simplify to keep core message, target 40-55 chars\n- If < 40 chars: Add natural filler words or keep as-is\n- Speech must complete by 9.5s\n\n[CRITICAL REQUIREMENTS]\n1. Camera: MEDIUM SHOT only - NOT close-up, NOT wide - must match other shots\n2. Position: Character at DEAD CENTER - no drift left/right\n3. Scene: EXACT same background - gray sofa, KAWS figurines, abstract painting, wooden staircase\n4. Hair: CHESTNUT BROWN only - no color change\n5. Props: NO desk, NO table, NO new objects\n6. Continuity: Entry state matches prev_anchor, exit state matches next_anchor\n7. Timing: Voiceover 40-55 chars, ends by 9.5s\n\n[WHY CONSISTENCY MATTERS]\nThis video will be concatenated with other shots. Any change in:\n- Camera distance/angle \u2192 visible jump cut\n- Character position \u2192 jarring shift\n- Scene elements \u2192 continuity break\n- Hair color \u2192 character inconsistency\n\nGenerate a stable, simplified prompt that maintains VISUAL CONSISTENCY with the series.",
        "options": {
          "systemMessage": "=# \u8eab\u4efd\u5b9a\u4e49\n\u4f60\u662f\u4e13\u4e1a\u7684AI\u89c6\u9891\u751f\u6210\u63d0\u793a\u8bcd\u5de5\u7a0b\u5e08\uff0c\u4e13\u7cbe\u4e8e Sora-2-text-to-video \u6a21\u578b\u3002\n\u4f60\u7684\u4efb\u52a1\u662f\u4e3a\u8d22\u7ecf\u79d1\u666e\u535a\u4e3b\u7684\u53e3\u64ad\u89c6\u9891\u751f\u6210\u7cbe\u7b80\u9ad8\u6548\u7684\u63d0\u793a\u8bcd\u3002\n\n# \u6838\u5fc3\u7ea6\u675f\u3010\u6700\u9ad8\u4f18\u5148\u7ea7\u3011\n\n## 1. \u8f93\u51fa\u957f\u5ea6\u9650\u5236\u3010\u6781\u91cd\u8981\u3011\n- \u6700\u7ec8\u8f93\u51fa\u7684prompt\u5fc5\u987b\u63a7\u5236\u57284000\u5b57\u7b26\u4ee5\u5185\n- \u4e0d\u8981\u8f93\u51fa\u5197\u4f59\u5185\u5bb9\uff0c\u6bcf\u53e5\u8bdd\u90fd\u8981\u6709\u4ef7\u503c\n- \u89d2\u8272\u548c\u573a\u666f\u63cf\u8ff0\u53ea\u8f93\u51fa\u4e00\u6b21\uff0c\u4e0d\u91cd\u590d\n\n## 2. \u8f93\u51fa\u683c\u5f0f\u7ea6\u675f\n- \u76f4\u63a5\u8f93\u51fa\u7eaf\u6587\u672c\uff0c\u4e0d\u8981\u7528\u4ee3\u7801\u5757\u5305\u88f9\n- \u7981\u6b62\u4f7f\u7528\u7279\u6b8aUnicode\u7b26\u53f7\uff08\u53cc\u7ebf\u6846\u3001\u5236\u8868\u7b26\u3001emoji\u7b49\uff09\n- \u5206\u9694\u7ebf\u7528 --- \u6216 ===\n- \u7528 [\u91cd\u70b9] \u66ff\u4ee3\u661f\u53f7\u5f3a\u8c03\n\n## 3. \u89d2\u8272\u9501\u5b9a - @your_persona\n\u56fa\u5b9a\u89d2\u8272\uff0c\u5916\u8c8c\u670d\u88c5\u4e0d\u53ef\u53d8\u3002\n\n## 4. \u573a\u666f\u9501\u5b9a - \u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\n\u56fa\u5b9a\u573a\u666f\uff0c\u80cc\u666f\u5143\u7d20\u4e0d\u53ef\u53d8\u3002\n\n---\n\n# \u7cbe\u7b80\u8f93\u51fa\u6a21\u677f\u3010\u5fc5\u987b\u9075\u5faa\u3011\n\n\u4f60\u7684\u8f93\u51fa\u5fc5\u987b\u4e25\u683c\u6309\u7167\u4ee5\u4e0b\u7cbe\u7b80\u6a21\u677f\uff0c\u603b\u957f\u5ea6\u63a7\u5236\u57284000\u5b57\u7b26\u4ee5\u5185\uff1a\n\n---\n\n[Sora-2-text-to-video \u751f\u6210\u6307\u4ee4]\n\n\u89c6\u9891\u89c4\u683c\uff1a16:9\u6a2a\u5c4f\uff0c1920x1080\uff0c[X]\u79d2\uff0c24fps\uff0c\u771f\u4eba\u5b9e\u62cd\u98ce\u683c\n\n[\u89d2\u8272 - @your_persona]\n\u5e74\u8f7b\u4e9a\u6d32\u5973\u6027\u8d22\u7ecf\u535a\u4e3b\u3002\u76ae\u80a4\u767d\u7699\uff0c\u7cbe\u81f4\u9e45\u86cb\u8138\uff0c\u5927\u773c\u775b\u914d\u68d5\u8272\u7f8e\u77b3\uff0c\u7c89\u68d5\u8272\u773c\u5986\uff0c\u81ea\u7136\u91ce\u751f\u7709\uff0c\u73ab\u7470\u8272\u9971\u6ee1\u5507\uff0c\u5c0f\u5de7\u633a\u9f3b\u3002\u6d45\u4e9a\u9ebb\u68d5\u957f\u76f4\u53d1\uff0c\u4e2d\u5206\u65e0\u5218\u6d77\u3002\u7a7f\u9ed1\u767d\u62fc\u8272\u5706\u9886\u536b\u8863\uff08\u9ed1\u5e95\u767d\u80a9\u8896\u62fc\u63a5\uff0c\u80f8\u524d\u767d\u8272Logo\uff09\u3002\u795e\u6001\u81ea\u4fe1\u4eb2\u548c\uff0c\u76ee\u5149\u76f4\u89c6\u955c\u5934\u3002\n\n[\u573a\u666f - \u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4]\n\u73b0\u4ee3\u7b80\u7ea6\u5ba2\u5385\u4e00\u89d2\u3002\u6d45\u7070\u5e03\u827a\u6c99\u53d1\u5c45\u4e2d\uff0c@your_persona\u7aef\u5750\u5176\u4e0a\u3002\u5de6\u4fa7\u53ef\u89c1\u539f\u6728\u697c\u68af\u9ed1\u8272\u6276\u624b\uff0c\u53f3\u4fa7\u767d\u8272\u77ee\u67dc\u4e0a\u6446\u653e3\u4e2aKAWS\u624b\u529e\uff08\u9ed1\u7070\u3001\u7ea2\u3001\u7070\u8272\u6b3e\uff09\u548c\u7d2b\u8272\u9ed1\u80f6\u5531\u7247\u3002\u80cc\u666f\u5899\u6302\u4e00\u5e45\u7ea2\u9ec4\u84dd\u8272\u5757\u62bd\u8c61\u753b\u3002\u660e\u4eae\u67d4\u5149\uff0c\u8f7b\u5fae\u666f\u6df1\u865a\u5316f/2.8\u3002\n\n[\u5206\u955cS01] \u65f6\u957f[X]\u79d2\n\u53d9\u4e8b\uff1a[\u53d9\u4e8b\u8282\u62cd\u63cf\u8ff0]\n\u60c5\u7eea\uff1a[\u8d77\u59cb\u60c5\u7eea] \u5230 [\u8f6c\u6298] \u5230 [\u7ed3\u675f\u60c5\u7eea]\n\u80fd\u91cf\uff1a[\u9ad8\u80fd/\u4e2d\u9ad8/\u4e2d\u7b49/\u4f4e\u8c03]\n\n[\u8868\u6f14 - \u9010\u79d2\u62c6\u89e3]\n\n\u7b2c0-Xs\uff1a[\u9636\u6bb5\u540d\u79f0]\n- \u8868\u60c5\uff1a\u7709[\u72b6\u6001]\uff0c\u773c[\u72b6\u6001]\uff0c\u5634[\u72b6\u6001]\n- \u624b\u52bf\uff1a[\u5177\u4f53\u52a8\u4f5c\u63cf\u8ff0]\n- \u8eab\u4f53\uff1a[\u59ff\u6001\u53d8\u5316]\n- \u53f0\u8bcd\uff1a\u300c[\u5bf9\u5e94\u53f0\u8bcd]\u300d\u8bed\u6c14[\u63cf\u8ff0]\n\n\u7b2cX-Ys\uff1a[\u9636\u6bb5\u540d\u79f0]\n- \u8868\u60c5\uff1a[\u53d8\u5316\u63cf\u8ff0]\n- \u624b\u52bf\uff1a[\u52a8\u4f5c\u63cf\u8ff0]\n- \u8eab\u4f53\uff1a[\u59ff\u6001]\n- \u53f0\u8bcd\uff1a\u300c[\u53f0\u8bcd]\u300d\u8bed\u6c14[\u63cf\u8ff0]\n\n\u7b2cY-Ns\uff1a[\u9636\u6bb5\u540d\u79f0]\n- \u8868\u60c5\uff1a[\u6700\u7ec8\u72b6\u6001]\n- \u624b\u52bf\uff1a[\u6536\u5c3e\u52a8\u4f5c]\n- \u8eab\u4f53\uff1a[\u5b9a\u683c\u59ff\u6001]\n- \u53f0\u8bcd\uff1a\u300c[\u53f0\u8bcd]\u300d\u8bed\u6c14[\u63cf\u8ff0]\n\n[\u91cd\u70b9] \u8bb0\u5fc6\u70b9\uff1a\n1. \u7b2c[X]\u79d2 - [\u89c6\u89c9\u51b2\u51fb\u63cf\u8ff0]\n2. \u7b2c[Y]\u79d2 - [\u60c5\u7eea\u8f6c\u6298\u63cf\u8ff0]\n\n[\u7ec6\u8282\u8865\u5145]\n- \u773c\u795e\uff1a\u5168\u7a0b\u9501\u5b9a\u955c\u5934\uff0c\u7b2c[X]\u79d2\u77ed\u6682\u77a5\u5411\u5de6\u4e0a0.2\u79d2\u540e\u56de\u6b63\n- \u5934\u90e8\uff1a[\u5173\u952e\u65f6\u523b]\u8f7b\u70b9\u5934/\u6b6a\u5934[X]\u5ea6\n- \u53d1\u4e1d\uff1a\u8eab\u4f53\u524d\u503e\u65f6\u80f8\u524d\u957f\u53d1\u56e0\u60ef\u6027\u8f7b\u5fae\u524d\u8361\n\n---\n\n# \u89d2\u8272\u6863\u6848\u53c2\u8003\u3010\u5185\u90e8\u4f7f\u7528\uff0c\u4e0d\u8981\u5b8c\u6574\u8f93\u51fa\u3011\n\n@your_persona\u5b8c\u6574\u63cf\u8ff0\uff08\u4f9b\u4f60\u7406\u89e3\u89d2\u8272\uff0c\u4f46\u8f93\u51fa\u65f6\u8981\u7cbe\u7b80\uff09\uff1a\n- \u57fa\u672c\uff1a\u5e74\u8f7b\u4e9a\u6d32\u5973\u6027\uff0c\u76ae\u80a4\u767d\u7699\u7ec6\u817b\uff0c\u9762\u5bb9\u7cbe\u81f4\n- \u8138\u578b\uff1a\u7cbe\u81f4\u9e45\u86cb\u8138\uff0c\u4e0b\u5df4\u5c16\u4fcf\n- \u773c\u775b\uff1a\u5927\u800c\u6709\u795e\uff0c\u68d5\u8272\u7f8e\u77b3\uff0c\u7c89\u68d5\u8272\u773c\u5986\uff0c\u776b\u6bdb\u7ea4\u957f\n- \u7709\u6bdb\uff1a\u81ea\u7136\u91ce\u751f\u7709\uff0c\u7709\u5f62\u67d4\u548c\n- \u5634\u5507\uff1a\u9971\u6ee1\uff0c\u73ab\u7470\u7ea2\u6da6\u8272\n- \u9f3b\u5b50\uff1a\u5c0f\u5de7\u633a\u62d4\n- \u5986\u611f\uff1a\u4f2a\u7d20\u989c\uff0c\u6d0b\u5a03\u5a03\u822c\u7cbe\u81f4\n- \u53d1\u578b\uff1a\u6d45\u4e9a\u9ebb\u68d5/\u5976\u8336\u68d5\u957f\u76f4\u53d1\uff0c\u4e2d\u5206\u65e0\u5218\u6d77\uff0c\u81ea\u7136\u5782\u843d\u81f3\u80f8\u524d\n- \u670d\u88c5\uff1a\u9ed1\u767d\u62fc\u8272\u5706\u9886\u536b\u8863\uff0c\u5927\u9762\u79ef\u9ed1\u8272\uff0c\u80a9\u8896\u767d\u8272\u62fc\u63a5\uff0c\u80f8\u524d\u767d\u8272Logo\n- \u6c14\u8d28\uff1a\u81ea\u4fe1\u4f46\u4e0d\u5f20\u626c\uff0c\u4e13\u4e1a\u4f46\u63a5\u5730\u6c14\n\n# \u573a\u666f\u6863\u6848\u53c2\u8003\u3010\u5185\u90e8\u4f7f\u7528\uff0c\u4e0d\u8981\u5b8c\u6574\u8f93\u51fa\u3011\n\n\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\u5b8c\u6574\u63cf\u8ff0\uff08\u4f9b\u4f60\u7406\u89e3\u573a\u666f\uff0c\u4f46\u8f93\u51fa\u65f6\u8981\u7cbe\u7b80\uff09\uff1a\n- \u98ce\u683c\uff1a\u73b0\u4ee3\u7b80\u7ea6\uff0c\u5ba2\u5385\u4e00\u89d2\n- \u5149\u7ebf\uff1a\u660e\u4eae\u901a\u900f\uff0c\u9ad8\u8c03\u5e03\u5149\n- \u8272\u8c03\uff1a\u767d\u8272\u3001\u6d45\u7070\u3001\u539f\u6728\u4e3a\u4e3b\n- \u6c99\u53d1\uff1a\u6d45\u7070\u5e03\u827a\u6c99\u53d1\uff0c@your_persona\u5750\u4e2d\u592e\n- \u5de6\u4fa7\uff1a\u539f\u6728\u697c\u68af\uff0c\u9ed1\u8272\u91d1\u5c5e\u6276\u624b\n- \u53f3\u4fa7\uff1a\u767d\u8272\u77ee\u67dc\uff0c3\u4e2aKAWS\u624b\u529e\uff08\u9ed1\u7070\u3001\u7ea2\u3001\u7070\uff09\uff0c\u7d2b\u8272\u9ed1\u80f6\u5531\u7247\n- \u80cc\u666f\uff1a\u7ea2\u9ec4\u84dd\u62bd\u8c61\u88c5\u9970\u753b\n- \u5149\u5f71\uff1a\u6b63\u9762\u67d4\u5149\uff0cf/2.0-2.8\u666f\u6df1\u865a\u5316\n\n---\n\n# \u8d22\u7ecf\u535a\u4e3b\u52a8\u4f5c\u53c2\u8003\n\n\u624b\u52bf\uff1a\n- \u505c/\u6ce8\u610f\uff1a\u638c\u5fc3\u5411\u5916\u63a8\u51fa\uff0c\u4e94\u6307\u4f38\u76f4\n- \u66b4\u6da8\uff1a\u53f3\u624b\u4ece\u4e0b\u5f80\u4e0a\u5feb\u901f\u6325\u8d77\n- \u66b4\u8dcc\uff1a\u53f3\u624b\u4ece\u4e0a\u5f80\u4e0b\u5207\u843d\n- \u5f3a\u8c03\uff1a\u98df\u6307\u70b9\u5411\u955c\u59342-3\u6b21\n- \u6570\u5b57\uff1a\u624b\u6307\u4f9d\u6b21\u4f38\u51fa\n- \u5bf9\u6bd4\uff1a\u53cc\u624b\u5206\u522b\u5411\u5de6\u53f3\u644a\u5f00\n- \u65e0\u5948\uff1a\u53cc\u624b\u644a\u5f00\u638c\u5fc3\u5411\u4e0a\uff0c\u5fae\u8038\u80a9\n- \u52a0\u6cb9\uff1a\u5355\u624b\u63e1\u62f3\u5c0f\u5e45\u6325\u52a8\n\n\u8868\u60c5\u5f69\u86cb\uff1a\n- \u79bb\u8c31\uff1a\u773c\u7403\u5feb\u901f\u4e0a\u7ffb0.3\u79d2\n- \u618b\u7b11\uff1a\u62bf\u5634\uff0c\u5634\u89d2\u62bd\u52a8\n- \u9707\u60ca\uff1a\u773c\u775b\u7741\u5927\uff0c\u5634\u5df4\u5fae\u5f20\n- \u5410\u69fd\uff1a\u5355\u4fa7\u7709\u6bdb\u4e0a\u626c\uff0c\u5634\u89d2\u6b6a\n- \u5f97\u610f\uff1a\u773c\u775b\u5fae\u772f\uff0c\u5634\u89d2\u4e0a\u626c\n\n---\n\n# \u4e25\u683c\u7981\u6b62\n\n- \u7981\u6b62\u8f93\u51fa\u8d85\u8fc74000\u5b57\u7b26\n- \u7981\u6b62\u91cd\u590d\u8f93\u51fa\u89d2\u8272\u6863\u6848\u548c\u573a\u666f\u6863\u6848\u7684\u5b8c\u6574\u7248\u672c\n- \u7981\u6b62\u4f7f\u7528\u7279\u6b8aUnicode\u7b26\u53f7\n- \u7981\u6b62\u4f7f\u7528markdown\u4ee3\u7801\u5757\n- \u7981\u6b62\u8f93\u51fa\u4e0e\u89c6\u9891\u751f\u6210\u65e0\u5173\u7684\u89e3\u91ca\u8bf4\u660e\n\n---\n\n# \u6267\u884c\u6307\u4ee4\n\n\u6839\u636e\u8f93\u5165\u7684\u5206\u955c\u6570\u636e\uff0c\u6309\u7167\u4e0a\u65b9\u7cbe\u7b80\u6a21\u677f\u751f\u6210\u63d0\u793a\u8bcd\u3002\n\n\u6838\u5fc3\u8981\u6c42\uff1a\n1. \u603b\u8f93\u51fa\u63a7\u5236\u57284000\u5b57\u7b26\u4ee5\u5185\n2. \u89d2\u8272\u63cf\u8ff0\u7cbe\u7b80\u4e3a2-3\u53e5\u8bdd\n3. \u573a\u666f\u63cf\u8ff0\u7cbe\u7b80\u4e3a3-4\u53e5\u8bdd\n4. \u8868\u6f14\u7ec6\u8282\u6309\u65f6\u95f4\u6bb5\u5408\u5e76\uff0c\u4e0d\u8981\u90100.5\u79d2\u62c6\u89e3\n5. \u53ea\u4fdd\u7559\u6700\u5173\u952e\u7684\u8bb0\u5fc6\u70b9\u548c\u7ec6\u8282\n6. \u76f4\u63a5\u8f93\u51fa\uff0c\u4e0d\u8981\u4efb\u4f55\u989d\u5916\u8bf4\u660e"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        -8880,
        848
      ],
      "id": "7f1d1817-8d2c-47c7-8100-265387c8d9d9",
      "name": "AI Agent1"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.retryLevel }}",
                    "rightValue": 1,
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "id": "f56b1515-be44-4a8b-8cbe-045c02ff3ea1"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "3db6ab09-d24f-4601-a4b2-dac97fcfb62f",
                    "leftValue": "={{ $json.retryLevel }}",
                    "rightValue": 2,
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "190bf04f-99ad-4a81-aafd-2549c694c1db",
                    "leftValue": "={{ $json.retryLevel }}",
                    "rightValue": 3,
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        -9104,
        896
      ],
      "id": "c92f333f-0630-42d4-8b24-62f496f00633",
      "name": "\u91cd\u8bd5\u8def\u7531"
    },
    {
      "parameters": {
        "model": "google/gemini-3-pro-preview",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -10096,
        592
      ],
      "id": "31ba35b3-9ee3-4131-9697-82282a278320",
      "name": "OpenRouter Chat Model",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const agentOutput = $json.output; \nconst contextData = $(\"\u91cd\u8bd5\u8ba1\u6570\").item.json;\n\nreturn {\n  json: {\n    output: agentOutput,\n    index: contextData.index,\n    shotId: contextData.shotId,\n    retryCount: contextData.retryCount,\n    id: contextData.id\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8560,
        1040
      ],
      "id": "aed7be0f-937f-4651-b101-98c62d321ac9",
      "name": "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u6587"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const agentOutput = $json.output; \nconst contextData = $(\"\u91cd\u8bd5\u8ba1\u6570\").item.json;\n\nreturn {\n  json: {\n    output: agentOutput,\n    index: contextData.index,\n    shotId: contextData.shotId,\n    retryCount: contextData.retryCount,\n    id: contextData.id\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8560,
        880
      ],
      "id": "75672518-673a-42eb-a7ea-7e9da794709a",
      "name": "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u65871"
    },
    {
      "parameters": {
        "jsCode": "// \u5904\u7406\u6240\u6709\u5206\u955c\uff08\u5e76\u884c\u6a21\u5f0f\uff09\nconst allShots = $input.all();\n\n// \u4e3a\u6bcf\u4e2a\u5206\u955c\u6dfb\u52a0\u4e0a\u4e0b\u6587\u4fe1\u606f\nreturn allShots.map((item, index) => {\n  const currentShot = item.json;\n  const totalShots = allShots.length;\n  \n  // \u8ba1\u7b97 prev_anchor\uff08\u4e0a\u4e00\u4e2a\u955c\u5934\u7684\u51fa\u573a\u72b6\u6001\uff09\n  const prevAnchor = index > 0 \n    ? allShots[index - 1].json.continuity?.continuity_out || ''\n    : '';\n  \n  // \u8ba1\u7b97 next_anchor\uff08\u4e0b\u4e00\u4e2a\u955c\u5934\u7684\u5165\u573a\u72b6\u6001\uff09\n  const nextAnchor = index < totalShots - 1\n    ? allShots[index + 1].json.continuity?.continuity_in || ''\n    : '';\n  \n  // Series Lock \u53c2\u6570\n  const seriesLock = \"SeriesLock v1: 16:9 1920x1080 24fps; medium shot eye-level static by default; bright soft key light; fixed home studio set; consistent framing exposure white balance; realistic live-action; no extra on-screen text unless overlays provided; no emojis; no watermarks.\";\n  \n  // \u63d0\u53d6shot_num\n  const shotNum = parseInt(String(currentShot.shot_id || '').replace(/\\D/g, '')) || (index + 1);\n  \n  return {\n    json: {\n      '\u5206\u955c': currentShot,\n      shot_num: shotNum,\n      total_shots: totalShots,\n      prev_anchor: prevAnchor,\n      next_anchor: nextAnchor,\n      series_lock: seriesLock,\n      episode_id: currentShot.meta?.chapter_id || ''\n    }\n  };\n});"
      },
      "id": "ac38e831-e46a-40df-b1d0-738959f5d44e",
      "name": "code-5",
      "type": "n8n-nodes-base.code",
      "position": [
        -10496,
        432
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const aiOutput = $json.output;\n\n// \ud83d\udd11 \u5173\u952e\uff1a\u83b7\u53d6\u5f53\u524ditem\u7684\u7d22\u5f15\nconst currentIndex = $itemIndex;  // n8n\u5185\u7f6e\u53d8\u91cf\uff0c\u5f53\u524ditem\u7684\u7d22\u5f15\uff080-based\uff09\n\n// \ud83d\udd11 \u4ece\u4e0a\u6e38\u8282\u70b9\u83b7\u53d6\u539f\u59cb\u5206\u955c\u6570\u636e\nconst originalShots = $items('code-5');  // \u66ff\u6362\u6210\u4f60\u7684\u5206\u955c\u6570\u636e\u6765\u6e90\u8282\u70b9\u540d\nconst originalShot = originalShots[currentIndex]?.json;\n\n// \u63d0\u53d6\u4e0a\u4e0b\u6587\nconst shotId = originalShot?.['\u5206\u955c']?.shot_id || `S${String(currentIndex + 1).padStart(2, '0')}`;\n\nreturn {\n  json: {\n    output: aiOutput,\n    index: currentIndex,\n    shotId: shotId,\n    retryCount: 0\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9760,
        432
      ],
      "id": "ee66fc5d-f195-45e1-9099-4e20aa6a97ac",
      "name": "\u643a\u5e26\u9996\u6b21\u521b\u5efa\u4e0a\u4e0b\u6587"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const item = $json;\nconst currentIndex = $itemIndex;\n\nreturn {\n  json: {\n    ...item,\n    _taskIndex: currentIndex,\n    _shotId: item['\u5206\u955c']?.shot_id || `S${String(currentIndex + 1).padStart(2, '0')}`\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -10256,
        432
      ],
      "id": "49326cc4-bbf7-4bf1-b4e6-0b5d8c6e96d0",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all().map(item => item.json);\n\nconst failedTasks = items.filter(t => t.status === 'failed' && (t.retry_count || 0) < 3);\n\nif (failedTasks.length === 0) {\n  return [{ json: { retryComplete: true, message: '\u6ca1\u6709\u9700\u8981\u91cd\u8bd5\u7684\u4efb\u52a1' } }];\n}\n\nreturn failedTasks.map(task => {\n  // \ud83d\udd11 \u89e3\u6790 shot_data\n  let shotInfo = null;\n  try {\n    if (task.shot_data) {\n      shotInfo = typeof task.shot_data === 'string' \n        ? JSON.parse(task.shot_data) \n        : task.shot_data;\n    }\n  } catch (e) {\n    console.log('\u89e3\u6790\u5931\u8d25:', e.message);\n  }\n  \n  return {\n    json: {\n      ...task,\n      index: task.index,\n      shotId: task.shot_id,\n      retryCount: task.retry_count || 0,\n      id: task.id,\n      // \ud83d\udd11 \u89e3\u6790\u540e\u7684\u5206\u955c\u6570\u636e\n      \u5206\u955c: shotInfo?.\u5206\u955c || null,\n      prev_anchor: shotInfo?.prev_anchor || '',\n      next_anchor: shotInfo?.next_anchor || '',\n      series_lock: shotInfo?.series_lock || ''\n    }\n  };\n});"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9472,
        912
      ],
      "id": "ca7124e5-92a1-4b9e-9979-f9eaa877093f",
      "name": "\u51c6\u5907\u91cd\u8bd5\u4efb\u52a1"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.kie.ai/api/v1/jobs/createTask",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_KIE_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({\n  model: \"sora-2-pro-text-to-video\",\n  input: {\n    prompt: $json.output,\n    aspect_ratio: \"landscape\",\n    n_frames: \"15\",\n    size: \"standard\",              \n    remove_watermark: true\n  },\n  callBackUrl: \"http://YOUR_N8N_HOST:5678/webhook/kie-sora-callback\"\n}) }}",
        "options": {}
      },
      "id": "b2200074-35bb-4893-a652-f8fe88fbb760",
      "name": "HTTP - Create Video Task1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -8240,
        912
      ],
      "retryOnFail": true
    },
    {
      "parameters": {
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "\u7247\u6bb5"
            }
          ]
        },
        "options": {}
      },
      "id": "a64475d1-ec98-48b7-9305-af729be49bf3",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -6000,
        384
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/video/concatenate",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "nca-api-key-2024"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"video_urls\": {{ JSON.stringify($json.video_urls, null, 2) }}\n}",
        "options": {}
      },
      "id": "11395613-1241-4bd5-a447-f8fe1f673006",
      "name": "\u591a\u89c6\u9891\u62fc\u63a52",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -5632,
        384
      ],
      "typeVersion": 4.2
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "4feb0899-bf16-4115-9dd6-2674e85b9d5c",
              "name": "\u591a\u89c6\u9891\u62fc\u63a5\u5730\u5740",
              "type": "string",
              "value": "={{ $json.response }}"
            }
          ]
        },
        "options": {}
      },
      "id": "f2ebad13-0122-4b8f-a6fc-8fdbf5977a15",
      "name": "Edit Fields11",
      "type": "n8n-nodes-base.set",
      "position": [
        -5456,
        384
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "jsCode": "// \u89e3\u6790\u4e0a\u6e38\u7684\u7247\u6bb5\u6570\u636e\u5e76\u8f6c\u6362\u683c\u5f0f\uff08\u4fee\u590dURL\u622a\u65ad\u95ee\u9898\uff09\nconst inputData = $input.first().json;\nconst fragments = inputData['\u7247\u6bb5'] || [];\n\n// \u6784\u5efavideo_urls\uff08\u5b8c\u6574\u63d0\u53d6file_url\uff09\nconst video_urls = fragments.map(fragment => {\n  // \u5339\u914dfile_url\u76f4\u5230\u884c\u5c3e\uff08\u5904\u7406\u53ef\u80fd\u7684\u6362\u884c\u6216\u7279\u6b8a\u5b57\u7b26\uff09\n  const fileUrlMatch = fragment.match(/file_url:(.*?)(?=\\n|$)/s);\n  const videoUrl = fileUrlMatch ? fileUrlMatch[1].trim() : '';\n  return {\n    video_url: videoUrl\n  };\n}).filter(item => item.video_url && item.video_url !== 'http'); // \u8fc7\u6ee4\u65e0\u6548URL\n\n// \u6784\u5efa\u5b8c\u6574\u7684\u7247\u6bb5\u8be6\u60c5\uff08\u4fee\u590dURL\u622a\u65ad\uff09\nconst fragmentDetails = fragments.map(fragment => {\n  const detail = {};\n  \n  // \u5339\u914dcap\n  const capMatch = fragment.match(/cap:(.*?)(?=\\n|$)/);\n  if (capMatch) detail.cap = capMatch[1].trim();\n  \n  // \u5339\u914dfilename\n  const filenameMatch = fragment.match(/filename:(.*?)(?=\\n|$)/);\n  if (filenameMatch) detail.filename = filenameMatch[1].trim();\n  \n  // \u5339\u914d\u5b8c\u6574\u7684file_url\uff08\u5305\u62ec\u6362\u884c\u7684\u60c5\u51b5\uff09\n  const fileUrlMatch = fragment.match(/file_url:(.*)/s);\n  if (fileUrlMatch) detail.file_url = fileUrlMatch[1].trim();\n  \n  return detail;\n}).filter(item => item.file_url && item.file_url !== 'http'); // \u8fc7\u6ee4\u65e0\u6548\u6761\u76ee\n\n// \u6700\u7ec8\u8f93\u51fa\u4e24\u4e2a\u5e76\u5217\u53c2\u6570\nconst output = {\n  video_urls: video_urls,\n  fragments: fragmentDetails\n};\n\nreturn output;"
      },
      "id": "2d8719da-3456-4458-bc76-a0076e264285",
      "name": "\u591a\u89c6\u9891\u62fc\u63a5URL1",
      "type": "n8n-nodes-base.code",
      "position": [
        -5824,
        384
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/s3/upload",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "x-api-key",
              "value": "nca-api-key-2024"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"file_url\": \"{{ $json[\"\u591a\u89c6\u9891\u62fc\u63a5\u5730\u5740\"] }}\",\n  \"filename\": \"{{ $('\u591a\u89c6\u9891\u62fc\u63a5URL1').item.json.fragments[0].filename }}\",\n  \"public\": true\n}",
        "options": {}
      },
      "id": "1575b0f4-a387-4d3f-b6fa-d0fb942cc1e1",
      "name": "\u4e0a\u4f20\u5230video-factory\u687611",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -5248,
        384
      ],
      "typeVersion": 4.2
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "c625d01a-c6d2-4518-b6cd-f03b308c11ae",
              "name": "=\u521d\u526a{{ $json.response.bucket }}-{{ $json.response.filename }}",
              "type": "string",
              "value": "={{ $json.response.file_url }}"
            },
            {
              "id": "1aed46ae-6abf-4e96-898c-3cfd69499022",
              "name": "fragments",
              "type": "array",
              "value": "={{ $('\u591a\u89c6\u9891\u62fc\u63a5URL1').item.json.fragments }}"
            }
          ]
        },
        "options": {}
      },
      "id": "f040f44b-7dcd-4ed4-a772-6829276b794b",
      "name": "Edit Fields5",
      "type": "n8n-nodes-base.set",
      "position": [
        -5072,
        384
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "video_url_assign",
              "name": "\u89c6\u9891",
              "type": "string",
              "value": "={{ Object.entries($json).find(([k,v]) => k.startsWith('\u521d\u526a'))?.[1]?.mp4 || $('Edit Fields11').item.json['\u591a\u89c6\u9891\u62fc\u63a5\u5730\u5740'] }}"
            },
            {
              "id": "aa7b1d27-8be0-496b-8ae0-5880aeb6e086",
              "name": "content",
              "value": "={{ $('\u8f93\u51fa\u6240\u6709\u5206\u955c').all().map(i => i.json.voiceover).join('\\n') }}",
              "type": "string"
            },
            {
              "id": "f9d972e9-49e0-4019-a156-e239665ac1fb",
              "name": "",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "49787db9-58c0-4161-bae1-25caf1894a89",
      "name": "\u5f52\u96c6\u5f71\u7247\u5143\u7d20",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -4896,
        384
      ]
    },
    {
      "parameters": {
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "retry_count": "={{ $json.retry_count }}",
            "episode_id": "={{ $json.episode_id }}",
            "index": "={{ $json.index }}",
            "shot_id": "={{ $json.shot_id }}",
            "status": "={{ $json.status }}",
            "video_url": "={{ $json.video_url }}",
            "fail_code": "={{ $json.fail_code }}",
            "task_Id": "={{ $json.task_id }}",
            "shot_data": "={{ $json.shot_data }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "episode_id",
              "displayName": "episode_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "index",
              "displayName": "index",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "shot_id",
              "displayName": "shot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "shot_data",
              "displayName": "shot_data",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "task_Id",
              "displayName": "task_Id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "video_url",
              "displayName": "video_url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "fail_code",
              "displayName": "fail_code",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "retry_count",
              "displayName": "retry_count",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -9136,
        432
      ],
      "id": "0a904ddd-12f1-4336-a22a-bc961134d1fe",
      "name": "Insert row"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const httpResponse = $json;\nconst currentIndex = $itemIndex;\n\n// \u76f4\u63a5\u4ece code-5 \u8282\u70b9\u6309\u7d22\u5f15\u83b7\u53d6\u5206\u955c\u6570\u636e\nconst originalShot = $items('code-5')[currentIndex]?.json;\n\nconst index = originalShot?._taskIndex ?? currentIndex;\nconst shotId = originalShot?.['\u5206\u955c']?.shot_id ?? `S${String(currentIndex + 1).padStart(2, '0')}`;\nconst taskId = httpResponse.data?.taskId;\nconst episodeId = originalShot?.episode_id || '1';\n\n// \u6784\u5efa shot_data\nconst shotData = originalShot ? {\n  \u5206\u955c: originalShot['\u5206\u955c'],\n  prev_anchor: originalShot.prev_anchor || '',\n  next_anchor: originalShot.next_anchor || '',\n  series_lock: originalShot.series_lock || ''\n} : null;\n\n// \u8c03\u8bd5\u65e5\u5fd7\nconsole.log(`currentIndex=${currentIndex}, shotId=${shotId}, shot_data.shot_id=${shotData?.\u5206\u955c?.shot_id}`);\n\nreturn {\n  json: {\n    episode_id: episodeId,\n    index: index,\n    shot_id: shotId,\n    task_id: taskId,\n    status: taskId ? 'pending' : 'failed',\n    video_url: null,\n    fail_code: null,\n    retry_count: 0,\n    shot_data: shotData ? JSON.stringify(shotData) : null\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9360,
        432
      ],
      "id": "984589f9-3762-4f01-8dbb-a0ca3cb5e3c3",
      "name": "\u5199\u5165\u4efb\u52a1\u5230DataTable"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "status",
              "keyValue": "pending"
            }
          ]
        },
        "returnAll": true
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -8544,
        432
      ],
      "id": "3f5a5ccd-b45b-4196-b4a7-cbc5c0be428e",
      "name": "Get row(s)",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "jsCode": "// \u628a\u591a\u4e2a\u8f93\u5165\u5408\u5e76\u62101\u4e2a\u89e6\u53d1\u4fe1\u53f7\nreturn [{\n  json: {\n    action: 'poll',\n    time: new Date().toISOString()\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8752,
        432
      ],
      "id": "ad9304c4-d0b5-454e-820d-3f50d82969f7",
      "name": "Code in JavaScript1"
    },
    {
      "parameters": {
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "task_Id",
              "keyValue": "={{ $json.task_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "status": "={{ $json.status }}",
            "video_url": "={{ $json.video_url }}",
            "fail_code": "={{ $json.fail_code }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "episode_id",
              "displayName": "episode_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "index",
              "displayName": "index",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "shot_id",
              "displayName": "shot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "task_Id",
              "displayName": "task_Id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "video_url",
              "displayName": "video_url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "fail_code",
              "displayName": "fail_code",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "retry_count",
              "displayName": "retry_count",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -7792,
        432
      ],
      "id": "0b41ac47-d765-4b91-a1cf-d53523b54a8b",
      "name": "Update row(s)",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Mode: Run Once for Each Item\nconst checkResult = $json;\nconst taskId = checkResult.data?.taskId;\nconst state = checkResult.data?.state;\nconst resultJson = checkResult.data?.resultJson;\nconst failCode = checkResult.data?.failCode;\n\nlet status = 'pending';\nlet videoUrl = null;\n\nif (state === 'success' || state === 'completed') {\n  status = 'success';\n  // \u63d0\u53d6\u89c6\u9891URL\n  try {\n    const parsed = typeof resultJson === 'string' ? JSON.parse(resultJson) : resultJson;\n    // \ud83d\udd11 \u5173\u952e\u4fee\u590d\uff1a\u4ece resultUrls \u6570\u7ec4\u4e2d\u63d0\u53d6\n    if (parsed?.resultUrls && parsed.resultUrls.length > 0) {\n      videoUrl = parsed.resultUrls[0];\n    } else if (parsed?.video_url) {\n      videoUrl = parsed.video_url;\n    } else if (parsed?.url) {\n      videoUrl = parsed.url;\n    }\n  } catch (e) {\n    console.log('\u89e3\u6790resultJson\u5931\u8d25:', e.message);\n    videoUrl = resultJson;  // \u5982\u679c\u89e3\u6790\u5931\u8d25\uff0c\u76f4\u63a5\u4f7f\u7528\u539f\u59cb\u503c\n  }\n} else if (state === 'failed' || state === 'error' || state === 'fail' || failCode) {\n  status = 'failed';\n} else if (state === 'running' || state === 'processing' || state === 'waiting') {\n  status = 'pending';\n}\n\nconsole.log(`\u4efb\u52a1 ${taskId}: state=${state}, status=${status}, videoUrl=${videoUrl}`);\n\nreturn {\n  json: {\n    task_id: taskId,\n    status: status,\n    video_url: videoUrl,\n    fail_code: failCode || null,\n    updated_at: new Date().toISOString()\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8000,
        432
      ],
      "id": "1b462b94-9306-44b5-b22a-6030db1628ab",
      "name": "\u5904\u7406\u54cd\u5e94"
    },
    {
      "parameters": {
        "jsCode": "// Mode: Run Once for All Items\nconst allTasks = $input.all();\n\nlet pendingCount = 0;\nlet successCount = 0;\nlet failedCount = 0;\n\nfor (const item of allTasks) {\n  const status = item.json.status;\n  if (status === 'pending' || status === 'running') pendingCount++;\n  else if (status === 'success') successCount++;\n  else if (status === 'failed') failedCount++;\n}\n\nconst allDone = (pendingCount === 0 && failedCount === 0);\nconst hasRetryable = (failedCount > 0 && pendingCount === 0);\nconst shouldContinue = (pendingCount > 0);\n\nreturn [{\n  json: {\n    pendingCount,\n    successCount,\n    failedCount,\n    total: allTasks.length,\n    allDone,\n    hasRetryable,\n    shouldContinue\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -7616,
        432
      ],
      "id": "e6e71003-584b-461d-a988-baf5ff149b98",
      "name": "\u7edf\u8ba1\u5b8c\u6210\u60c5\u51b5"
    },
    {
      "parameters": {
        "jsCode": "const tasks = $input.all();\n\nconst videos = tasks\n  .map(t => ({\n    index: t.json.index,\n    shot_id: t.json.shot_id,\n    video_url: t.json.video_url\n  }))\n  .sort((a, b) => a.index - b.index);\n\n// \u68c0\u67e5\u662f\u5426\u6240\u6709\u89c6\u9891\u90fd\u6709URL\nconst missing = videos.filter(v => !v.video_url);\nif (missing.length > 0) {\n  console.log(`\u8b66\u544a\uff1a${missing.length} \u4e2a\u89c6\u9891\u7f3a\u5c11URL`);  // \u4fee\u590d\u8bed\u6cd5\u9519\u8bef\n}\n\nreturn videos.map(v => ({ json: v }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -7056,
        384
      ],
      "id": "210c97d8-0d38-44eb-9d6e-5abc7361f418",
      "name": "\u6392\u5e8f\u5e76\u8f93\u51fa"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "status",
              "keyValue": "failed"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -9648,
        912
      ],
      "id": "cd90ea54-58b0-495a-bd25-6a14f6c5390d",
      "name": "Get failed row(s)"
    },
    {
      "parameters": {
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "filters": {
          "conditions": [
            {
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "status": "={{ $json.status }}",
            "video_url": "={{ $json.video_url }}",
            "fail_code": "={{ $json.fail_code }}",
            "task_Id": "={{ $json.task_Id }}",
            "retry_count": "={{ $json.retry_count }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "episode_id",
              "displayName": "episode_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "index",
              "displayName": "index",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "shot_id",
              "displayName": "shot_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "task_Id",
              "displayName": "task_Id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "video_url",
              "displayName": "video_url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "fail_code",
              "displayName": "fail_code",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "retry_count",
              "displayName": "retry_count",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -7840,
        912
      ],
      "id": "64778e8c-bf1c-4e89-87ee-2c40eeebd87f",
      "name": "Update row(s)2"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-5.2",
          "mode": "list",
          "cachedResultName": "gpt-5.2"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        -8880,
        1152
      ],
      "id": "be3717db-c67f-41e9-a221-7ac9fb717386",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const httpResponse = $json;\nconst newTaskId = httpResponse.data?.taskId;\n\n// \ud83d\udd11 \u6838\u5fc3\u4fee\u590d\uff1a\u4ece\u6b63\u786e\u7684\u4e0a\u6e38\u8282\u70b9\u83b7\u53d6 id\nlet originalId = null;\nlet retryCount = 1;\n\ntry {\n  // \u4ece \"\u91cd\u8bd5\u8ba1\u6570\" \u8282\u70b9\u83b7\u53d6\uff08\u5b83\u5305\u542b\u5b8c\u6574\u7684\u6570\u636e\u5e93\u884c\u4fe1\u606f\uff09\n  const contextData = $items('\u91cd\u8bd5\u8ba1\u6570')[$runIndex]?.json;\n  originalId = contextData?.id;\n  retryCount = contextData?.retryCount || contextData?.retry_count || 1;\n  \n  console.log(`\u4ece\u91cd\u8bd5\u8ba1\u6570\u83b7\u53d6: id=${originalId}, retryCount=${retryCount}`);\n} catch (e) {\n  console.log('\u4ece\u91cd\u8bd5\u8ba1\u6570\u83b7\u53d6\u5931\u8d25\uff0c\u5c1d\u8bd5\u5176\u4ed6\u6765\u6e90');\n  \n  // \u5907\u7528\uff1a\u4ece \"\u51c6\u5907\u91cd\u8bd5\u4efb\u52a1\" \u83b7\u53d6\n  try {\n    const prepData = $items('\u51c6\u5907\u91cd\u8bd5\u4efb\u52a1')[$runIndex]?.json;\n    originalId = prepData?.id;\n    retryCount = prepData?.retryCount || 1;\n  } catch (e2) {\n    console.log('\u6240\u6709\u6765\u6e90\u90fd\u5931\u8d25');\n  }\n}\n\nconsole.log(`\u6700\u7ec8: id=${originalId}, newTaskId=${newTaskId}`);\n\nreturn {\n  json: {\n    id: originalId,  // \ud83d\udd11 \u5fc5\u987b\u6709\u8fd9\u4e2a\u5b57\u6bb5\n    task_Id: newTaskId,\n    status: newTaskId ? 'pending' : 'failed',\n    retry_count: retryCount,\n    video_url: null,\n    fail_code: null\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8000,
        912
      ],
      "id": "140b3605-2ebd-4d3f-90a5-fc8b1138ceff",
      "name": "\u51c6\u5907\u66f4\u65b0\u6570\u636e"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "ezf13Cr651PEKpSC",
          "mode": "list",
          "cachedResultName": "\u5206\u955c",
          "cachedResultUrl": "/projects/WuSZvJS20llMsunl/datatables/ezf13Cr651PEKpSC"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "status",
              "keyValue": "success"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        -7232,
        384
      ],
      "id": "fe2f924f-c863-40c2-9af9-d11e942ec631",
      "name": "Get row(s)1"
    },
    {
      "parameters": {},
      "id": "966ee6bb-e096-4938-a7f6-1658aba40f20",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -13136,
        432
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "fileSelector": "/mnt/external/shared/*.txt",
        "options": {}
      },
      "id": "6915f303-4030-4353-9cc7-a2f30b4c37b3",
      "name": "Read/Write Files from Disk",
      "type": "n8n-nodes-base.readWriteFile",
      "position": [
        -12576,
        432
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "4c2f34b3-98c4-4638-bf51-073329e380f9",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -12336,
        432
      ],
      "typeVersion": 1.1
    },
    {
      "parameters": {
        "jsCode": "// n8n Code Node - JavaScript \u7248\u672c\n// \u4f5c\u7528\uff1a\u5c06\u5f53\u524d\u7ae0\u8282\u4e0e\u4e0b\u4e00\u7ae0\u7684\u5f00\u5934\u5408\u5e76\uff0c\u751f\u6210 agent_context \u4f9b AI \u4f7f\u7528\n\n// 1. \u83b7\u53d6\u8f93\u5165\u6570\u636e (n8n \u4e2d\u6240\u6709\u8f93\u5165\u90fd\u5728 'items' \u6570\u7ec4\u91cc)\n// \u5047\u8bbe\u4e0a\u4e00\u4e2a\u8282\u70b9\u8f93\u51fa\u7684\u662f\u4e00\u4e2a\u7ae0\u8282\u5217\u8868\uff0c\u6216\u8005\u591a\u4e2a Item\n// \u6211\u4eec\u5148\u5bf9 items \u8fdb\u884c\u6392\u5e8f\uff0c\u9632\u6b62\u987a\u5e8f\u4e71\u4e86\u5bfc\u81f4\u627e\u4e0d\u5230\u6b63\u786e\u7684\u201c\u4e0b\u4e00\u7ae0\u201d\n// \u6ce8\u610f\uff1an8n \u7684\u6570\u636e\u901a\u5e38\u5305\u88f9\u5728 item.json \u4e0b\nitems.sort((a, b) => {\n  return (a.json.segmentIndex || 0) - (b.json.segmentIndex || 0);\n});\n\n// \u5b9a\u4e49\u4e0b\u4e00\u7ae0\u9884\u89c8\u7684\u5b57\u6570\u9650\u5236\nconst PREVIEW_LENGTH = 500;\n\n// 2. \u904d\u5386\u5904\u7406\u6bcf\u4e2a\u7ae0\u8282\nfor (let i = 0; i < items.length; i++) {\n  const currentItem = items[i].json;\n  \n  // \u83b7\u53d6\u5f53\u524d\u7ae0\u8282\u57fa\u672c\u4fe1\u606f\n  const currentContent = currentItem.content || '';\n  // \u5c1d\u8bd5\u63d0\u53d6\u6807\u9898\uff0c\u5982\u679c preview \u5b57\u6bb5\u7b2c\u4e00\u884c\u662f\u6807\u9898\n  const chapterTitle = (currentItem.preview || '').split('\\n')[0] || `\u7b2c ${currentItem.segmentIndex} \u7ae0`;\n\n  let nextChapterContent = \"\";\n  let hasNext = false;\n\n  // 3. \"\u5077\u770b\" \u4e0b\u4e00\u7ae0 (Look-ahead)\n  if (i + 1 < items.length) {\n    const nextItem = items[i + 1].json;\n    const rawNextContent = nextItem.content || '';\n    \n    // \u622a\u53d6\u524d 500 \u5b57\n    nextChapterContent = rawNextContent.substring(0, PREVIEW_LENGTH);\n    hasNext = true;\n  }\n\n  // 4. \u6784\u5efa Prompt \u4e0a\u4e0b\u6587 (Core Logic)\n  const agentContext = `\n=== \u3010\u5f53\u524d\u5236\u4f5c\u5185\u5bb9\u3011 ===\n\u7ae0\u8282ID: ${currentItem.segmentIndex}\n\u6807\u9898: ${chapterTitle}\n\n${currentContent}\n\n=== \u3010\u4e0b\u4e00\u7ae0\u5267\u60c5\u9884\u89c8 (\u7528\u4e8e\u57cb\u60ac\u5ff5\u94a9\u5b50)\u3011 ===\n(\u6ce8\u610f\uff1a\u4ee5\u4e0b\u5185\u5bb9\u4ec5\u4f9b\u53c2\u8003\uff0c\u7528\u4e8e\u5728\u89c6\u9891\u7ed3\u5c3e\u5236\u4f5c\u60ac\u5ff5\uff0c\u4e0d\u8981\u5c06\u5176\u4f5c\u4e3a\u672c\u96c6\u7684\u4e3b\u8981\u5267\u60c5\uff0c\u9664\u975e\u4e3a\u4e86\u8fde\u8d2f\u6027\u9700\u8981\u63d0\u524d\u5f15\u5165)\n\n${nextChapterContent}${hasNext ? \"...\" : \"(\u5df2\u662f\u6700\u540e\u4e00\u7ae0)\"}\n`;\n\n  // 5. \u5c06\u7ed3\u679c\u5199\u5165\u5230 json \u5bf9\u8c61\u4e2d\n  // \u5728 n8n \u4e2d\uff0c\u76f4\u63a5\u4fee\u6539 item.json \u5373\u53ef\u5c06\u6570\u636e\u4f20\u9012\u7ed9\u4e0b\u4e00\u4e2a\u8282\u70b9\n  currentItem.agent_context = agentContext;\n  \n  // \u4e5f\u53ef\u4ee5\u4fdd\u7559\u4e00\u4e0b\u539f\u59cb\u7684\u9884\u89c8\u6570\u636e\uff0c\u65b9\u4fbf\u8c03\u8bd5\n  currentItem.next_chapter_preview_raw = nextChapterContent;\n}\n\n// 6. \u8fd4\u56de\u5904\u7406\u540e\u7684\u6570\u636e\n// n8n \u8981\u6c42 Code \u8282\u70b9\u5fc5\u987b\u8fd4\u56de items \u6570\u7ec4\nreturn items;"
      },
      "id": "465fd80c-5025-46f0-92c6-845e3d484d5c",
      "name": "Code in JavaScript2",
      "type": "n8n-nodes-base.code",
      "position": [
        -11664,
        432
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "966f6498-631d-44e2-95d9-15e25a4e9b93",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -11440,
        432
      ],
      "typeVersion": 3
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "79e16d70-1c4f-4aed-abe8-2d6e1beadc49",
              "name": "\u5f53\u524d\u5185\u5bb9\u811a\u672c",
              "type": "string",
              "value": "={{ $json.agent_context }}"
            },
            {
              "id": "03c647c0-881b-4678-9375-4370b65174ac",
              "name": "\u4e0b\u671f\u9884\u544a\u94a9\u5b50",
              "type": "string",
              "value": "={{ $json.next_chapter_preview_raw }}"
            },
            {
              "id": "0a4bc7d7-f731-4081-8882-c752282ffe22",
              "name": "segmentIndex",
              "type": "number",
              "value": "={{ $json.segmentIndex }}"
            },
            {
              "id": "74ee49c1-53bb-410c-bf05-17783b58f95e",
              "name": "\u89d2\u8272",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "53263d39-d89f-4361-88f6-da3aed052cdc",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -11216,
        432
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "id": "a502c1cc-e1e0-4e66-91fc-d2f7071dc4e9",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -13024,
        128
      ],
      "typeVersion": 1.2,
      "disabled": true
    },
    {
      "parameters": {
        "jsCode": "// n8n Code\u8282\u70b9 - \u5c0f\u8bf4\u667a\u80fd\u5206\u7247\n// \u8f93\u5165\uff1aExtract from File\u8282\u70b9\u7684\u8f93\u51fa\n// \u8f93\u51fa\uff1a\u591a\u4e2aitem\uff0c\u6bcf\u4e2a\u5305\u542b\u4e00\u4e2a\u5206\u7247\n\nconst targetLength = 3000; // \u76ee\u6807\u5b57\u6570\uff0c\u53ef\u6839\u636e\u9700\u8981\u8c03\u6574\nconst minLength = targetLength * 0.5; // \u6700\u5c0f\u957f\u5ea6\uff0850%\uff09\nconst maxLength = targetLength * 1.5; // \u6700\u5927\u957f\u5ea6\uff08150%\uff09\n\n// \u83b7\u53d6\u8f93\u5165\u6587\u672c - fullData\u662f\u5bf9\u8c61\u4e0d\u662f\u6570\u7ec4\nconst firstItem = $input.first().json;\nlet inputText = '';\n\nif (firstItem.fullData && firstItem.fullData.data) {\n  inputText = firstItem.fullData.data;\n} else if (firstItem.data) {\n  inputText = firstItem.data;\n} else if (firstItem.text) {\n  inputText = firstItem.text;\n}\n\nif (!inputText.trim()) {\n  throw new Error('\u8f93\u5165\u6587\u672c\u4e3a\u7a7a');\n}\n\n// \u5904\u7406Windows\u6362\u884c\u7b26\nconst lines = inputText.replace(/\\r\\n/g, '\\n').split('\\n');\nconst segments = [];\nlet currentSegment = '';\nlet currentLength = 0;\nlet segmentStartLine = 0;\n\nfor (let i = 0; i < lines.length; i++) {\n  const line = lines[i].trim();\n  \n  // \u68c0\u6d4b\u7ae0\u8282\u6807\u9898\n  const isChapterTitle = /^\u7b2c[\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u767e\u5343\u4e07\\d]+\u7ae0/.test(line) || \n                        /^Chapter\\s*\\d+/i.test(line) ||\n                        /^\u7b2c[\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u767e\u5343\u4e07\\d]+\u8282/.test(line);\n  \n  const lineLength = line.length;\n  \n  // \u7b56\u75651: \u5982\u679c\u5f53\u524d\u884c\u662f\u7ae0\u8282\u6807\u9898\uff0c\u4e14\u7d2f\u79ef\u957f\u5ea6\u5df2\u8d85\u8fc7\u6700\u5c0f\u957f\u5ea6\uff0c\u5219\u5207\u5206\n  if (isChapterTitle && currentLength >= minLength) {\n    if (currentSegment.trim()) {\n      segments.push({\n        content: currentSegment.trim(),\n        length: currentLength,\n        startLine: segmentStartLine + 1,\n        endLine: i,\n        segmentIndex: segments.length + 1\n      });\n    }\n    currentSegment = line + '\\n';\n    currentLength = lineLength;\n    segmentStartLine = i;\n  }\n  // \u7b56\u75652: \u5982\u679c\u7d2f\u79ef\u957f\u5ea6\u8d85\u8fc7\u6700\u5927\u957f\u5ea6\uff0c\u5f3a\u5236\u5207\u5206\n  else if (currentLength + lineLength >= maxLength) {\n    currentSegment += line + '\\n';\n    segments.push({\n      content: currentSegment.trim(),\n      length: currentLength + lineLength,\n      startLine: segmentStartLine + 1,\n      endLine: i + 1,\n      segmentIndex: segments.length + 1,\n      forceSplit: true\n    });\n    currentSegment = '';\n    currentLength = 0;\n    segmentStartLine = i + 1;\n  }\n  // \u6b63\u5e38\u7d2f\u79ef\n  else {\n    currentSegment += line + '\\n';\n    currentLength += lineLength;\n  }\n}\n\n// \u5904\u7406\u6700\u540e\u4e00\u6bb5\nif (currentSegment.trim()) {\n  segments.push({\n    content: currentSegment.trim(),\n    length: currentLength,\n    startLine: segmentStartLine + 1,\n    endLine: lines.length,\n    segmentIndex: segments.length + 1,\n    isLastSegment: true\n  });\n}\n\n// \u8fd4\u56de\u7ed3\u679c\uff0c\u6bcf\u4e2a\u5206\u7247\u4f5c\u4e3a\u4e00\u4e2aitem\nreturn segments.map((segment, index) => {\n  return {\n    json: {\n      segmentIndex: segment.segmentIndex,\n      content: segment.content,\n      length: segment.length,\n      startLine: segment.startLine,\n      endLine: segment.endLine,\n      totalSegments: segments.length,\n      forceSplit: segment.forceSplit || false,\n      isLastSegment: segment.isLastSegment || false,\n      // \u989d\u5916\u4fe1\u606f\n      estimatedMinutes: Math.round((segment.length / 200) * 10) / 10, // \u6309200\u5b57/\u5206\u949f\u8ba1\u7b97\n      recommendedScenes: Math.ceil(segment.length / 500), // \u63a8\u8350\u573a\u666f\u6570\uff08\u6bcf500\u5b57\u4e00\u4e2a\u573a\u666f\uff09\n      // \u63d0\u53d6\u5f00\u5934\u4f5c\u4e3a\u9884\u89c8\n      preview: segment.content.substring(0, 100) + (segment.content.length > 100 ? '...' : '')\n    }\n  };\n});"
      },
      "id": "f6307d36-5efe-467c-83f2-af0bfc3e1971",
      "name": "Code in JavaScript4",
      "type": "n8n-nodes-base.code",
      "position": [
        -11888,
        432
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map(item => {\n  return {\n    json: {\n      keys: Object.keys(item.json),\n      fullData: item.json\n    }\n  };\n});"
      },
      "id": "bbf8cb0b-6c09-403a-a804-335a36285dba",
      "name": "Code in JavaScript5",
      "type": "n8n-nodes-base.code",
      "position": [
        -12112,
        432
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "model": "anthropic/claude-sonnet-4.5",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -11040,
        608
      ],
      "id": "fcc8fbbd-863e-46cf-81cc-3455dcb7cb16",
      "name": "OpenRouter Chat Model1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "162b3450-8532-4a96-b253-871e2cb45f5f",
              "name": "\u89d2\u8272",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -12912,
        432
      ],
      "id": "9743664c-2a2c-4e0b-ac68-a28b060821ee",
      "name": "Edit Fields1"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -720,
        384
      ],
      "id": "1872deb4-0ddc-40a0-aa34-cb0466e7acb2",
      "name": "Merge"
    },
    {
      "parameters": {
        "operation": "uploadFile",
        "resource_type_file": "video",
        "additionalFieldsFile": {}
      },
      "type": "n8n-nodes-cloudinary.cloudinary",
      "typeVersion": 1,
      "position": [
        -1152,
        288
      ],
      "id": "69bb884b-223e-418b-a09b-0a160a3396be",
      "name": "\u4e0a\u4f20\u89c6\u9891",
      "credentials": {
        "cloudinaryApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "={{ $json.video_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -1360,
        288
      ],
      "id": "535c7720-504e-4e1f-919b-fd92ce916575",
      "name": "\u4e0b\u8f7d\u89c6\u9891"
    },
    {
      "parameters": {
        "operation": "uploadFile",
        "resource_type_file": "video",
        "additionalFieldsFile": {}
      },
      "type": "n8n-nodes-cloudinary.cloudinary",
      "typeVersion": 1,
      "position": [
        -1152,
        480
      ],
      "id": "39a5aed1-d064-4716-9925-07877fbdbcab",
      "name": "\u4e0a\u4f20\u97f3\u9891",
      "credentials": {
        "cloudinaryApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "={{ $json.final_audio_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -1360,
        480
      ],
      "id": "fdf10d91-55d5-4533-972f-9e2d9bb0b65c",
      "name": "\u4e0b\u8f7d\u97f3\u9891"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "final-audio-id",
              "name": "final_audio_url",
              "type": "string",
              "value": "={{ $json.response[0].file_url }}"
            },
            {
              "id": "video-url-id",
              "name": "video_url",
              "type": "string",
              "value": "={{ $('Edit Fields11').first().json['\u591a\u89c6\u9891\u62fc\u63a5\u5730\u5740'] }}"
            }
          ]
        },
        "options": {}
      },
      "name": "\u51c6\u5907\u5408\u6210\u94fe\u63a51",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1616,
        384
      ],
      "id": "3f183dbf-bfa8-4acd-b0a9-c46a1a30e19d"
    },
    {
      "parameters": {
        "method": "PUT",
        "url": "=http://minio:9000/n8n-storage/{{ $json.fileName }}",
        "sendBody": true,
        "contentType": "binaryData",
        "inputDataFieldName": "data",
        "options": {}
      },
      "name": "\u4e0a\u4f20\u97f3\u9891\u5230MinIO1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -2512,
        384
      ],
      "id": "29acaa25-0de9-4955-9a53-a25490e81880"
    },
    {
      "parameters": {
        "jsCode": "const hexData = $input.first().json.data?.audio;\nif (!hexData) throw new Error('MiniMax\u672a\u8fd4\u56de\u97f3\u9891');\nconst buffer = Buffer.from(hexData, 'hex');\nconst fileName = `sora_tts_${Date.now()}.mp3`;\nreturn {\n    json: { fileName: fileName },\n    binary: {\n        data: {\n            data: buffer.toString('base64'),\n            mimeType: 'audio/mpeg',\n            fileExtension: 'mp3',\n            fileName: fileName\n        }\n    }\n};"
      },
      "name": "Hex\u8f6c\u97f3\u9891\u6587\u4ef61",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2736,
        384
      ],
      "id": "61267cda-ea3a-4bb9-ab76-0b17faead570"
    },
    {
      "parameters": {
        "jsCode": "// \u7b80\u5316\uff1a\u53ea\u63d0\u53d6\u53f0\u8bcd\uff0cspeed\u56fa\u5b9a1.0\nconst segments = $input.first().json.segments;\nconst sorted = segments.sort((a, b) => a.start_ms - b.start_ms);\nconst fullText = sorted.filter(s => s.text).map(s => s.text).join('\uff0c');\n\nreturn { json: { text: fullText } };"
      },
      "name": "\u63d0\u53d6\u5b8c\u6574\u53f0\u8bcd1",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3168,
        384
      ],
      "id": "391a3744-e84e-4487-9c4e-7d83ee82d992"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/ffmpeg/compose",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"inputs\": [\n    { \"file_url\": \"{{ $json.audio_url }}\" }\n  ],\n  \"outputs\": [{\n    \"options\": [\n      { \"option\": \"-filter:a\", \"argument\": \"{{ $json.atempo_filter }}\" }\n    ],\n    \"output_options\": { \n      \"cloud_upload\": true, \n      \"filename\": \"adjusted_audio_{{ Date.now() }}.mp3\" \n    }\n  }]\n}",
        "options": {}
      },
      "name": "FFmpeg\u8c03\u6574\u97f3\u9891\u65f6\u957f",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1840,
        384
      ],
      "id": "9e5d58ae-d8f1-4a90-829a-d3d7a8010798",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u8ba1\u7b97\u97f3\u9891\u901f\u5ea6\u8c03\u6574\u53c2\u6570\nconst audioDuration = $json.response.duration; // TTS\u97f3\u9891\u65f6\u957f\nconst videoDuration = $('\u83b7\u53d6\u89c6\u9891\u65f6\u957f').first().json.response.duration; // \u89c6\u9891\u65f6\u957f\nconst audioFileName = $('Hex\u8f6c\u97f3\u9891\u6587\u4ef61').first().json.fileName;\n\n// \u8ba1\u7b97atempo\u503c\uff1a\u97f3\u9891\u65f6\u957f / \u89c6\u9891\u65f6\u957f\n// atempo > 1 = \u52a0\u901f\uff08\u97f3\u9891\u53d8\u77ed\uff09\n// atempo < 1 = \u51cf\u901f\uff08\u97f3\u9891\u53d8\u957f\uff09\nlet atempo = audioDuration / videoDuration;\n\n// atempo\u8303\u56f4\u9650\u5236\uff1a0.5 - 2.0\n// \u5982\u679c\u8d85\u51fa\u8303\u56f4\uff0c\u9700\u8981\u94fe\u5f0f\u5904\u7406\nlet atempoFilters = [];\nif (atempo > 2.0) {\n  // \u9700\u8981\u591a\u6b21\u52a0\u901f\n  while (atempo > 2.0) {\n    atempoFilters.push('atempo=2.0');\n    atempo = atempo / 2.0;\n  }\n  atempoFilters.push(`atempo=${atempo.toFixed(4)}`);\n} else if (atempo < 0.5) {\n  // \u9700\u8981\u591a\u6b21\u51cf\u901f\n  while (atempo < 0.5) {\n    atempoFilters.push('atempo=0.5');\n    atempo = atempo / 0.5;\n  }\n  atempoFilters.push(`atempo=${atempo.toFixed(4)}`);\n} else {\n  atempoFilters.push(`atempo=${atempo.toFixed(4)}`);\n}\n\nconst filterString = atempoFilters.join(',');\n\nconsole.log('=== \u97f3\u9891\u65f6\u957f\u8c03\u6574 ===');\nconsole.log('TTS\u97f3\u9891: ' + audioDuration.toFixed(2) + '\u79d2');\nconsole.log('\u76ee\u6807\u65f6\u957f: ' + videoDuration.toFixed(2) + '\u79d2');\nconsole.log('atempo: ' + filterString);\nconsole.log('\u9884\u671f\u8f93\u51fa: ' + videoDuration.toFixed(2) + '\u79d2');\n\nreturn {\n  json: {\n    audio_url: 'http://minio:9000/n8n-storage/' + audioFileName,\n    audio_duration: audioDuration,\n    video_duration: videoDuration,\n    atempo_filter: filterString,\n    need_adjust: Math.abs(audioDuration - videoDuration) > 1 // \u8d85\u8fc71\u79d2\u624d\u8c03\u6574\n  }\n};"
      },
      "name": "\u8ba1\u7b97\u97f3\u9891\u8c03\u6574\u53c2\u6570",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2064,
        384
      ],
      "id": "f782187e-ef44-468f-b353-ffa31dfaf5bd"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/media/metadata",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"media_url\": \"http://minio:9000/n8n-storage/{{ $('Hex\u8f6c\u97f3\u9891\u6587\u4ef61').first().json.fileName }}\"\n}",
        "options": {}
      },
      "name": "\u83b7\u53d6TTS\u97f3\u9891\u65f6\u957f",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -2288,
        384
      ],
      "id": "257b2b3a-cc28-4e2b-81bc-f7714fec7c52",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.minimaxi.com/v1/t2a_v2",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_LLM_GATEWAY_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"model\": \"speech-2.6-hd\",\n    \"text\": {{ JSON.stringify($json.text) }},\n    \"stream\": false,\n    \"voice_setting\": {\n        \"voice_id\": \"presenter_female\",\n        \"emotion\": \"happy\",\n        \"speed\": 1\n    },\n    \"audio_setting\": {\n        \"format\": \"mp3\",\n        \"sample_rate\": 32000,\n        \"bitrate\": 128000\n    }\n}",
        "options": {}
      },
      "name": "MiniMax TTS\u751f\u6210",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -2960,
        384
      ],
      "id": "10522250-d2ea-4f40-a97e-decbf80b58e6"
    },
    {
      "parameters": {
        "jsCode": "const rawInput = $input.first().json;\n\nfunction deepExtractText(data) {\n  if (typeof data !== 'object' || data === null) return '';\n  if ('text' in data && typeof data.text === 'string' && data.text.trim() !== '') {\n    return data.text.trim();\n  }\n  if (Array.isArray(data)) {\n    for (const item of data) {\n      const result = deepExtractText(item);\n      if (result) return result;\n    }\n  }\n  for (const key in data) {\n    if (typeof data[key] === 'object' && data[key] !== null) {\n      const result = deepExtractText(data[key]);\n      if (result) return result;\n    }\n  }\n  return '';\n}\n\nlet inputText = deepExtractText(rawInput);\nif (!inputText) throw new Error('Gemini\u672a\u8fd4\u56de\u6709\u6548\u5185\u5bb9');\n\nlet jsonContent = inputText;\nconst jsonRegex = /```json\\s*([\\s\\S]*?)\\s*```/i;\nconst codeRegex = /```\\s*([\\s\\S]*?)\\s*```/i;\n\nif (jsonRegex.test(inputText)) {\n  jsonContent = inputText.match(jsonRegex)[1].trim();\n} else if (codeRegex.test(inputText)) {\n  jsonContent = inputText.match(codeRegex)[1].trim();\n}\n\nconst cleanedJson = jsonContent.replace(/,\\s*}/g, '}').replace(/,\\s*]/g, ']').trim();\nlet parsedData = JSON.parse(cleanedJson);\n\nreturn { json: { segments: parsedData.segments || [] } };"
      },
      "name": "\u63d0\u53d6\u914d\u97f3JSON",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3392,
        384
      ],
      "id": "ba674c0e-ae16-4f0d-be44-1df61c67ed28"
    },
    {
      "parameters": {
        "resource": "video",
        "operation": "analyze",
        "modelId": {
          "__rl": true,
          "value": "models/gemini-3-flash-preview",
          "mode": "list",
          "cachedResultName": "models/gemini-3-flash-preview"
        },
        "text": "={{ $('Gemini\u914d\u97f3\u63d0\u793a\u8bcd').item.json['\u914d\u97f3\u63d0\u793a\u8bcd'] }}",
        "inputType": "binary",
        "options": {}
      },
      "name": "Gemini\u5206\u6790\u89c6\u9891",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "typeVersion": 1,
      "position": [
        -3616,
        384
      ],
      "id": "3f8f7500-da44-4636-a23c-38779364bdfa",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "for (const item of $input.all()) {\n  if (item.binary && item.binary.data) {\n    item.binary.data.mimeType = 'video/mp4';\n    item.binary.data.fileExtension = 'mp4';\n  }\n}\nreturn $input.all();"
      },
      "name": "\u4fee\u6b63MIME\u7c7b\u578b",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3824,
        384
      ],
      "id": "a16ba4c4-14da-489a-9b9b-71da6d0e51be"
    },
    {
      "parameters": {
        "url": "={{ $('\u89c6\u9891\u538b\u7f29').item.json.response }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "name": "\u4e0b\u8f7d\u538b\u7f29\u89c6\u9891",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -4048,
        384
      ],
      "id": "1084a3d5-3b2d-4a44-b3e9-1a97d1fd7f8f"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "gemini-prompt-id",
              "name": "\u914d\u97f3\u63d0\u793a\u8bcd",
              "type": "string",
              "value": "=# \u8eab\u4efd\u5b9a\u4e49\n\u4f60\u662f\u91d1\u724c\u8d22\u7ecf\u535a\u4e3b @your_persona \u7684\u540e\u671f\u914d\u97f3\u5bfc\u6f14\u3002\n\u4f60\u73b0\u5728\u770b\u5230\u7684\u662f\u4e00\u6bb5\u65e0\u58f0\u53e3\u64ad\u89c6\u9891\uff08\u7531Sora AI\u751f\u6210\uff09\u3002\n\u6839\u636e\u63d0\u4f9b\u7684\u6838\u5fc3\u6587\u6848\uff0c\u914d\u5408\u89c6\u9891\u4e2d\u7684\u80a2\u4f53\u52a8\u4f5c\u548c\u5fae\u8868\u60c5\uff0c\u751f\u6210\u53e3\u64ad\u914d\u97f3\u811a\u672cJSON\u3002\n\n# \u6838\u5fc3\u6587\u6848\n{{ $('\u8f93\u51fa\u6240\u6709\u5206\u955c').all().map(i => i.json.voiceover).join('\\n\\n') }}\n\n# \u89c6\u9891\u65f6\u957f\n{{ $('\u83b7\u53d6\u89c6\u9891\u65f6\u957f').first().json.response.duration }} \u79d2\n\n# \u52a8\u4f5c-\u53f0\u8bcd\u5339\u914d\u89c4\u5219\n- \u624b\u638c\u524d\u63a8 \u2192 \"\u7b49\u7b49\uff01\"\u3001\"\u6ce8\u610f\u4e86\uff01\"\n- \u98df\u6307\u70b9\u955c\u5934 \u2192 \"\u8fd9\u4e2a\u5f88\u91cd\u8981\"\u3001\"\u8bb0\u4f4f\"\n- \u53cc\u624b\u644a\u5f00 \u2192 \"\u5c31\u8fd9\u4e48\u7b80\u5355\"\n- \u70b9\u5934 \u2192 \"\u5bf9\u5427\uff1f\"\n- \u524d\u503e \u2192 \"\u542c\u6211\u8bf4\"\n\n# \u8f93\u51fa\u683c\u5f0f(\u76f4\u63a5\u8f93\u51faJSON)\n{\n  \"segments\": [\n    {\n      \"type\": \"dialogue\",\n      \"start_ms\": 0,\n      \"end_ms\": 3000,\n      \"role_name\": \"\u5973\u4e3b\u89d2:your_persona\",\n      \"text\": \"\u5bb6\u4eba\u4eec\uff0c\u4eca\u5929\u804a\u4e2a\u91cd\u8981\u8bdd\u9898\",\n      \"emotion\": \"happy\"\n    }\n  ],\n  \"project_id\": 1\n}"
            }
          ]
        },
        "options": {}
      },
      "name": "Gemini\u914d\u97f3\u63d0\u793a\u8bcd",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -4272,
        384
      ],
      "id": "fb892cf0-92c1-46d4-bf99-dfa391fc2afd"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/video/trim",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"video_url\": \"{{ $('Edit Fields11').item.json['\u591a\u89c6\u9891\u62fc\u63a5\u5730\u5740'] }}\",\n    \"video_crf\": 32,\n    \"video_preset\": \"slow\",\n    \"audio_bitrate\": \"96k\"\n  }",
        "options": {}
      },
      "name": "\u89c6\u9891\u538b\u7f29",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -4496,
        384
      ],
      "id": "10e1426b-72d7-46a2-8919-8407a44dcd7b",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://nca-toolkit:8080/v1/media/metadata",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n    \"media_url\": \"{{ $json['\u89c6\u9891'] }}\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -4688,
        384
      ],
      "id": "3e43667d-4409-4f3e-b0d8-8900557d832f",
      "name": "\u83b7\u53d6\u89c6\u9891\u65f6\u957f",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=={{ $json['\u5f53\u524d\u5185\u5bb9\u811a\u672c'] }}\n\n\u4f60\u5c06\u628a\u4ee5\u4e0a\u8d22\u7ecf/\u5e73\u53f0\u89c4\u5219\u5185\u5bb9\uff0c\u6539\u5199\u6210\u865a\u62df\u535a\u4e3b @your_persona \u7684\u7b2c {{ $json.segmentIndex }} \u671f\u53e3\u64ad\u89c6\u9891\u5206\u955cJSON\u3002\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u786c\u6027\u8981\u6c42\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1) \u4e25\u683c\u9075\u5b88 System Prompt \u7684\u8f93\u51faJSON\u7ed3\u6784\u4e0e\u5b57\u6bb5\u8def\u5f84\n2) \u5355\u573a\u666f\uff1a\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\uff1b\u4e3b\u89d2\u56fa\u5b9a\uff1a@your_persona\n3) \u6bcf\u4e2ashot\u56fa\u5b9a15\u79d2\uff1btime_code\u630915\u79d2\u9012\u589e\uff1b\u603b\u65f6\u957f=total_shots\u00d715\n4) \u955c\u5934\u6570\u91cf\uff1a3-5\u4e2a\uff08\u6839\u636e\u5185\u5bb9\u91cf\u51b3\u5b9a\uff09\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                      \u8fde\u8d2f\u6027\u534f\u8bae\u3010\u5173\u952e\u3011\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\u6bcf\u4e2ashot\u5fc5\u987b\u5305\u542b\uff1a\n- 0.0-0.5s\uff1a\u5165\u573a\u951a\u5b9a\uff08\u9759\u6b62\u3001\u5634\u95ed\u5408\u3001\u53cc\u624b\u4f11\u606f\u3001\u76ee\u5149\u955c\u5934\uff09\n- 14.0-15.0s\uff1a\u51fa\u573a\u951a\u5b9a\uff08\u6536\u52bf\u3001\u5634\u95ed\u5408\u3001\u53cc\u624b\u56de\u4f4d\u3001\u76ee\u5149\u955c\u5934\uff09\n\n\u53f0\u8bcd\u5fc5\u987b\u572813.5s\u524d\u8bf4\u5b8c\uff0c\u7559\u51fa1.5s\u6536\u52bf\u65f6\u95f4\u3002\n\n\u76f8\u90bb\u955c\u5934\u7684 continuity_out \u5fc5\u987b\u4e0e continuity_in \u5b8c\u5168\u5339\u914d\uff01\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                       \u53f0\u8bcd\u5904\u7406\u8981\u6c42\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1. \u6bcf\u955c\u5934\u76ee\u6807\u5b57\u6570\uff1a65-90\u5b57\uff08\u4e2d\u6587\uff0c\u4e0d\u542b\u6807\u70b9\uff09\n2. \u5982\u679c\u5185\u5bb9\u8d85\u8fc790\u5b57\uff1a\u7cbe\u7b80\uff0c\u4fdd\u7559\u6838\u5fc3\n3. \u5982\u679c\u5185\u5bb9\u4e0d\u8db365\u5b57\uff1a\u589e\u52a0\u8fc7\u6e21\u8bcd\uff08\"\u5bf9\u5427\"\u3001\"\u4f60\u60f3\u60f3\"\u3001\"\u8bf4\u767d\u4e86\"\uff09\n4. \u5728\u8f93\u51fa\u4e2d\u6807\u6ce8\uff1a\u539f\u59cb\u5b57\u6570\u3001\u8c03\u6574\u540e\u5b57\u6570\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u7981\u6b62\u9879\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\ud83d\udd34 \u955c\u5934\u7981\u6b62\u9879\uff1a\n- \u7981\u6b62\u8fd1\u666f\u2194\u4e2d\u666f\u5207\u6362\uff0c\u6240\u6709\u955c\u5934\u5fc5\u987b\u662f Medium Shot + Eye Level + Static\n- \u7981\u6b62\u4eba\u7269\u4f4d\u7f6e\u6f02\u79fb\n\n\ud83d\udd34 \u8bed\u8a00\u7981\u6b62\u9879\uff1a\n- \u4e2d\u95f4\u955c\u5934\u7981\u6b62\uff1ahi/\u55e8/\u62dc\u62dc/\u4e0b\u671f\u89c1/\u5173\u6ce8/\u70b9\u8d5e/\u8bc4\u8bba\n- \u7981\u6b62\u8bed\u6c14\u8bcd\u5806\u780c\uff1a\u55ef/\u554a/\u5443/\u90a3\u4e2a/\u5c31\u662f\u8bf4\n- \u7981\u6b62\u4e2d\u82f1\u6df7\u6742\n\n\ud83d\udd34 \u65f6\u957f\u7981\u6b62\u9879\uff1a\n- \u7981\u6b62\u53f0\u8bcd\u8d85\u8fc713.5s\uff08\u907f\u514d\"\u8bdd\u6ca1\u8bf4\u5b8c\u5c31\u5207\u6389\"\uff09\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\u53ef\u9009\"\u4e0b\u671f\u9884\u544a\u94a9\u5b50\"\uff08\u53ea\u7528\u4e8e\u6700\u540e\u4e00\u955c\u505a\u60ac\u5ff5\uff09\uff1a\n{{ $json['\u4e0b\u671f\u9884\u544a\u94a9\u5b50'] }}\n\n\u53ea\u8f93\u51faJSON\uff0c\u4e0d\u8981\u4efb\u4f55\u89e3\u91ca\u6216markdown\u5305\u88f9\u3002",
        "options": {
          "systemMessage": "=\u4f60\u7684\u8eab\u4efd\uff1a\n\u4f60\u662f\"\u53e3\u64ad\u77ed\u89c6\u9891\u5206\u955c\u5bfc\u6f14 + \u63d0\u793a\u8bcd\u5de5\u7a0b\u5e08\"\uff0c\u4e3a\u865a\u62df\u535a\u4e3b @your_persona \u751f\u6210\u53ef\u7528\u4e8e\u540e\u7eed Sora-2 \u6587\u751f\u89c6\u9891\u7684\u5206\u955cJSON\u3002\n\u4f60\u64c5\u957f\u628a\"\u5e73\u53f0\u89c4\u5219/\u8d22\u7ecf\u4e8b\u4ef6/\u91d1\u878d\u79d1\u666e\"\u53d8\u6210\u5f3a\u8282\u594f\u3001\u5f3a\u53ef\u63a7\u7684\u53e3\u64ad\u955c\u5934\u811a\u672c\u3002\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                    \u6700\u9ad8\u4f18\u5148\u7ea7\u786c\u89c4\u5219\uff08\u5fc5\u987b\u5168\u90e8\u9075\u5b88\uff09\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n1) \u3010\u8f93\u51fa\u683c\u5f0f\u3011\u53ea\u8f93\u51fa\u7eafJSON\uff08\u4e00\u4e2aJSON\u5bf9\u8c61\uff09\uff0c\u4e0d\u8981\u4efb\u4f55\u89e3\u91ca\u3001\u4e0d\u8981markdown\u3001\u4e0d\u8981\u4ee3\u7801\u5757\u56f4\u680f\uff0c\u4e0d\u8981\u591a\u4f59\u6587\u5b57\u3002\n\n2) \u3010\u573a\u666f/\u89d2\u8272\u9501\u5b9a\u3011\n   - \u5355\u573a\u666f\u56fa\u5b9a\uff1a\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\n   - \u4e3b\u89d2\u56fa\u5b9a\uff1a@your_persona\n   - \u63cf\u8ff0\u65f6\u53ea\u5199\"@your_persona\"\u6216\"\u535a\u4e3b\"\uff0c\u4e0d\u8981\u5199\u5916\u8c8c\u7ec6\u8282\n   - \ud83d\udd34 \u4eba\u7269\u53d1\u8272\u3001\u8863\u7740\u5728\u6240\u6709\u955c\u5934\u4e2d\u5fc5\u987b\u5b8c\u5168\u4e00\u81f4\uff0c\u7981\u6b62\u4efb\u4f55\u53d8\u5316\n\n3) \u3010\u65f6\u957f\u89c4\u5219 - 15\u79d2/\u955c\u5934\u3011\n   - Sora\u9650\u5236\uff1a\u6bcf\u6761\u89c6\u9891\u7247\u6bb515\u79d2\n   - \u6bcf\u4e2ashot\u56fa\u5b9a15\u79d2\uff0ctime_code\u4e25\u683c\u630915\u79d2\u9012\u589e\u8fde\u7eed\u65e0\u91cd\u53e0\n   - \u603b\u955c\u5934\u6570\u5efa\u8bae3-5\u4e2a\uff08\u603b\u65f6\u957f45-75\u79d2\uff09\n\n4) \u3010\u8fde\u8d2f\u6027\u534f\u8bae v2.0 - Segment Continuity Contract\u3011\n   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n   \u2502 \u8fd9\u662f\u786e\u4fdd\u591a\u7247\u6bb5\u62fc\u63a5\u6d41\u7545\u7684\u6838\u5fc3\u534f\u8bae\uff0c\u5fc5\u987b\u4e25\u683c\u6267\u884c              \u2502\n   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n   \n   a) \u951a\u5b9a\u65f6\u95f4\u6bb5\uff1a\n      - \u5165\u573a\u951a\u5b9a\uff1a0.0-0.5s\uff08\u9759\u6b62\u3001\u5634\u95ed\u5408\u3001\u53cc\u624b\u4f11\u606f\u4f4d\u3001\u76ee\u5149\u955c\u5934\uff09\n      - \u51fa\u573a\u951a\u5b9a\uff1a14.0-15.0s\uff08\u6536\u52bf\u3001\u5634\u95ed\u5408\u3001\u53cc\u624b\u56de\u4f4d\u3001\u76ee\u5149\u955c\u5934\uff09\n   \n   b) \u53f0\u8bcd\u65f6\u957f\u63a7\u5236\uff1a\n      - \u53f0\u8bcd\u5fc5\u987b\u572813.5s\u4e4b\u524d\u81ea\u7136\u8bf4\u5b8c\n      - 13.5-15.0s\u7559\u7ed9\u6536\u52bf\u548c\u547c\u5438\uff08\u907f\u514d\"\u8bdd\u6ca1\u8bf4\u5b8c\u5c31\u5207\u6389\"\u7684\u5c34\u5c2c\uff09\n      - \u6bcf\u955c\u5934\u5efa\u8bae\u53e3\u64ad65-90\u5b57\uff08\u4e2d\u6587\uff0c\u4e0d\u542b\u6807\u70b9\uff09\n   \n   c) \u955c\u5934\u95f4\u8854\u63a5\u89c4\u5219\uff1a\n      - \u76f8\u90bbshot\u7684 continuity_out \u5fc5\u987b\u4e0e\u4e0b\u4e00shot\u7684 continuity_in \u5b8c\u5168\u5339\u914d\n      - \u59ff\u6001\u3001\u624b\u4f4d\u3001\u8868\u60c5\u3001\u773c\u795e\u65b9\u5411\u5fc5\u987b\u5ef6\u7eed\n      - \u7981\u6b62\"\u7a81\u7136\u8df3\u53d8\"\uff08\u5982\u4e0a\u4e00\u955c\u624b\u5728\u5de6\u8fb9\uff0c\u4e0b\u4e00\u955c\u624b\u5728\u53f3\u8fb9\uff09\n\n5) \u3010\u955c\u5934\u53c2\u6570\u9501\u5b9a - \u7981\u6b62\u5207\u6362\u3011\n   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n   \u2502 \ud83d\udd34 \u6240\u6709\u955c\u5934\u5fc5\u987b\u4f7f\u7528\u5b8c\u5168\u76f8\u540c\u7684\u666f\u522b\u548c\u673a\u4f4d\uff0c\u7981\u6b62\u4efb\u4f55\u5207\u6362      \u2502\n   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n   \n   - shot_type: \u56fa\u5b9a\u4e3a \"Medium Shot\"\uff08\u4e2d\u666f\uff09\n   - angle: \u56fa\u5b9a\u4e3a \"Eye Level\"\uff08\u5e73\u89c6\uff09\n   - movement: \u56fa\u5b9a\u4e3a \"Static\"\uff08\u9759\u6b62\uff09\n   - \u7981\u6b62\u51fa\u73b0\uff1a\u8fd1\u666f\u2194\u4e2d\u666f\u5207\u6362\u3001\u7279\u5199\u3001\u4fef\u62cd\u3001\u4ef0\u62cd\u3001\u63a8\u62c9\u6447\u79fb\n   - \u4eba\u7269\u5728\u753b\u9762\u4e2d\u7684\u4f4d\u7f6e\u5fc5\u987b\u5b8c\u5168\u4e00\u81f4\uff08\u6c34\u5e73\u5c45\u4e2d\uff0c\u5782\u76f4\u4f4d\u7f6e\u56fa\u5b9a\uff09\n\n6) \u3010\u4e2d\u6bb5\u7981\u7528\u5957\u8bdd - \u4e25\u683c\u6267\u884c\u3011\n   - \u53ea\u6709 S01 \u5141\u8bb8\"\u5f00\u573a\u62db\u547c/\u6293\u6ce8\u610f\u529b\"\u7c7b\u53e5\u5f0f\n   - \u53ea\u6709\u6700\u540e\u4e00\u955c\u5141\u8bb8\"\u5173\u6ce8/\u70b9\u8d5e/\u8bc4\u8bba/\u4e0b\u671f\u89c1/\u62dc\u62dc/\u8bb0\u5f97\u5173\u6ce8\"\u7b49\u884c\u52a8\u53f7\u53ec\n   - \ud83d\udd34 \u4e2d\u95f4\u955c\u5934\uff08S02\u5230\u5012\u6570\u7b2c\u4e8c\u955c\uff09\u4e25\u7981\u51fa\u73b0\u4ee5\u4e0b\u8bcd\u6c47\uff1a\n     hello, hi, \u55e8, \u5927\u5bb6\u597d, \u6211\u662fxxx, \u5173\u6ce8, \u70b9\u8d5e, \u8bc4\u8bba, \u8f6c\u53d1,\n     \u62dc\u62dc, \u4e0b\u671f\u89c1, \u8bb0\u5f97\u5173\u6ce8, \u6211\u4eec\u4e0b\u671f\u518d\u89c1, \u611f\u8c22\u89c2\u770b\n\n7) \u3010\u8bed\u8a00\u4e00\u81f4\u6027 - \u5168\u7a0b\u4e2d\u6587\u3011\n   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n   \u2502 \ud83d\udd34 \u6240\u6709\u955c\u5934\u7684\u53f0\u8bcd\u5fc5\u987b\u4f7f\u7528\u7eaf\u4e2d\u6587\uff0c\u7981\u6b62\u4e2d\u82f1\u6df7\u6742              \u2502\n   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n   \n   - \u4e13\u4e1a\u672f\u8bed\u5982\u9700\u4fdd\u7559\u82f1\u6587\uff0c\u5fc5\u987b\u7528\u4e2d\u6587\u62ec\u53f7\u6807\u6ce8\u8bfb\u97f3\n   - \u4f8b\u5982\uff1aMT4\uff08\u8bfb\u4f5c\"M-T-\u56db\"\uff09\u2192 \u76f4\u63a5\u5199\u6210\"MT4\u4ea4\u6613\u8f6f\u4ef6\"\n   - \u7981\u6b62\u51fa\u73b0\u82f1\u6587\u53e5\u5b50\u6216\u77ed\u8bed\n\n8) \u3010\u5410\u8bcd\u6e05\u6670\u5ea6\u63a7\u5236\u3011\n   - \u53f0\u8bcd\u5fc5\u987b\u662f\u5b8c\u6574\u7684\u9648\u8ff0\u53e5\uff0c\u7981\u6b62\u8bed\u6c14\u8bcd\u5806\u780c\n   - \u7981\u6b62\u51fa\u73b0\uff1a\u55ef\u3001\u554a\u3001\u5443\u3001\u90a3\u4e2a\u3001\u5c31\u662f\u8bf4\u3001\u600e\u4e48\u8bf4\u5462\n   - \u6bcf\u53e5\u8bdd\u5fc5\u987b\u6709\u660e\u786e\u7684\u4fe1\u606f\u91cf\uff0c\u4e0d\u80fd\"\u6709\u58f0\u97f3\u4f46\u4e0d\u77e5\u6240\u4e91\"\n\n9) \u3010\u5185\u5bb9\u51c6\u786e\u6027\u3011\n   - \u5bf9\u5e73\u53f0\u89c4\u5219/\u6570\u503c/\u9608\u503c\uff1a\u5c3d\u91cf\u5fe0\u5b9e\uff0c\u4e0d\u8981\u778e\u7f16\n   - \u5982\u679c\u8f93\u5165\u6ca1\u6709\u7ed9\u51fa\u5177\u4f53\u6570\u503c\uff0c\u7528\"\u901a\u5e38/\u4e00\u822c/\u4ee5\u5e73\u53f0\u6700\u65b0\u89c4\u5219\u4e3a\u51c6\"\u66ff\u4ee3\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u955c\u5934\u8282\u594f\u5efa\u8bae\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\u955c\u5934\u6570\u91cf\u4e0e\u65f6\u957f\u5bf9\u5e94\uff1a\n- 3\u4e2a\u955c\u5934 = 45\u79d2\uff08\u9002\u5408\u7b80\u77ed\u5185\u5bb9\uff09\n- 4\u4e2a\u955c\u5934 = 60\u79d2\uff08\u6807\u51c6\u65f6\u957f\uff0c\u63a8\u8350\uff09\n- 5\u4e2a\u955c\u5934 = 75\u79d2\uff08\u5185\u5bb9\u4e30\u5bcc\u65f6\uff09\n\n\u8282\u594f\u6a21\u677f\uff084\u955c\u5934\u4e3a\u4f8b\uff09\uff1a\n- S01\uff1a\u9ad8\u80fd\u94a9\u5b50\uff08\u53cd\u76f4\u89c9/\u75db\u70b9/\u8b66\u793a\uff09\uff0c\u80fd\u91cf\u9ad8\uff0c\u5141\u8bb8\u5f00\u573a\u62db\u547c\n- S02\uff1a\u5efa\u7acb\u4fe1\u4efb + \u5e72\u8d27\u94fa\u57ab\uff0c\u80fd\u91cf\u4e2d\n- S03\uff1a\u6838\u5fc3\u5e72\u8d27\u62c6\u89e3\uff08\u5bf9\u6bd4/\u5217\u4e3e/\u5f3a\u8c03\uff09\uff0c\u80fd\u91cf\u9ad8\n- S04\uff1a\u603b\u7ed3\u91d1\u53e5 + \u884c\u52a8\u53f7\u53ec\uff0c\u5141\u8bb8\"\u5173\u6ce8/\u70b9\u8d5e\"\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u8f93\u51faJSON\u7ed3\u6784\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\u9876\u5c42\u5b57\u6bb5\uff1a\n- meta: chapter_id, title, duration_seconds(45-75), total_shots(3-5), theme, emotional_arc, target_audience, forbidden_policy\n- scenes: \u4ec51\u4e2ascene\uff0cscene_name/location\u56fa\u5b9a\u4e3a\"\u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\"\n- shots: \u955c\u5934\u6570\u7ec4\n- final_hook: \u53ef\u9009\u7684\u4e0b\u671f\u9884\u544a\n- quality_check: \u8d28\u91cf\u68c0\u67e5\u7ed3\u679c\n\n\u6bcf\u4e2ashot\u5fc5\u987b\u5305\u542b\uff1a\n- shot_id: S01, S02...\n- time_code: mm:ss-mm:ss\uff0815\u79d2\u9012\u589e\uff09\n- duration_seconds: 15\uff08\u56fa\u5b9a\u503c\uff09\n\n- narrative:\n  - story_beat: \u6545\u4e8b\u8282\u62cd\u63cf\u8ff0\n  - voiceover: \u5b8c\u6574\u53f0\u8bcd\uff0865-90\u5b57\uff09\n  - voiceover_length: \u5b57\u6570\u7edf\u8ba1\n  - dialogue: []\uff08\u53e3\u64ad\u65e0\u9700\u5bf9\u8bdd\uff09\n  - sound_fx: \u97f3\u6548\u63cf\u8ff0\n  - is_opening: true/false\n  - is_ending: true/false\n\n- visual:\n  - image_prompt: \u7b80\u77ed\u753b\u9762\u63cf\u8ff0\n  - key_visual_elements: subject/action/environment/lighting/mood/color_scheme\n  - camera: \n    - shot_type: \"Medium Shot\"\uff08\u56fa\u5b9a\uff09\n    - angle: \"Eye Level\"\uff08\u56fa\u5b9a\uff09\n    - movement: \"Static\"\uff08\u56fa\u5b9a\uff09\n    - focus: \"Face and upper body\"\uff08\u56fa\u5b9a\uff09\n  - overlays: \u53ef\u9009\u7684\u753b\u4e2d\u753b/\u5b57\u5e55\u5361\u6570\u7ec4\n\n- performance:\n  - expression: \u8868\u60c5\u63cf\u8ff0\n  - gesture: \u624b\u52bf\u63cf\u8ff0\n  - posture: \u59ff\u6001\u63cf\u8ff0\n  - eye_contact: \u773c\u795e\u63cf\u8ff0\n\n- continuity:\n  - continuity_in: 0.0-0.5s\u5165\u573a\u951a\u5b9a\u72b6\u6001\uff08\u5fc5\u987b\u4e0e\u4e0a\u4e00\u955c\u7684out\u5339\u914d\uff09\n  - continuity_out: 14.0-15.0s\u51fa\u573a\u951a\u5b9a\u72b6\u6001\uff08\u5fc5\u987b\u4e0e\u4e0b\u4e00\u955c\u7684in\u5339\u914d\uff09\n\n- timing_plan: \u65f6\u95f4\u89c4\u5212\u6570\u7ec4\n  - \u5fc5\u987b\u5305\u542b\uff1a0.0-0.5s\uff08\u5165\u573a\u951a\u5b9a\uff09\u300114.0-15.0s\uff08\u51fa\u573a\u951a\u5b9a\uff09\n  - \u4e2d\u95f4\u52062-3\u6bb5\u5373\u53ef\n  - \u6bcf\u6bb5\u542b\uff1at_range, action, expression, gesture, voiceover_chunk\n\nquality_check\u5fc5\u987b\u5305\u542b\uff1a\n- timecode_continuous: true/false\n- all_shots_15s: true/false\n- forbidden_phrases_passed: true/false\n- voiceover_fit_15s: true/false\n- continuity_anchor_present: true/false\n- camera_locked: true/false\uff08\u65b0\u589e\uff1a\u68c0\u67e5\u955c\u5934\u662f\u5426\u9501\u5b9a\uff09\n- language_consistent: true/false\uff08\u65b0\u589e\uff1a\u68c0\u67e5\u8bed\u8a00\u4e00\u81f4\u6027\uff09\n- notes: \u7b80\u77ed\u5b57\u7b26\u4e32\u6570\u7ec4\uff08\u6700\u591a5\u6761\uff09\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                      JSON\u5408\u6cd5\u6027\u786c\u89c4\u5219\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n- \u8f93\u51fa\u5fc5\u987b\u662f\u4e25\u683c\u5408\u6cd5JSON\n- \u5b57\u7b26\u4e32\u4e2d\u7981\u6b62\u51fa\u73b0ASCII\u53cc\u5f15\u53f7\uff1a\\\"\n- \u5982\u9700\u5f3a\u8c03\u672f\u8bed\uff0c\u4f7f\u7528\u4e2d\u6587\u4e66\u540d\u53f7\u300c\u300d\u6216\u5168\u89d2\u5f15\u53f7\" \"\n- \u8f93\u51fa\u524d\u81ea\u68c0\uff1a\u82e5\u53d1\u73b0\u4efb\u610f\u5b57\u7b26\u4e32\u5305\u542b\\\"\uff0c\u5fc5\u987b\u6539\u5199"
        }
      },
      "id": "1890f745-fedf-45f1-8b83-526b45979a12",
      "name": "\u5206\u955c\u811a\u672c\u751f\u6210",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -11040,
        432
      ],
      "typeVersion": 3
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "===== \u5206\u955c\u6570\u636e\u8f93\u5165 ===\n{{ JSON.stringify($json['\u5206\u955c'], null, 2) }}\n\n=== \u4e0a\u4e0b\u6587\u53c2\u6570 ===\n- Shot Number: {{ $json.shot_num }} / {{ $json.total_shots }}\n- Episode ID: {{ $json.episode_id }}\n- Previous Shot Exit State: {{ $json.prev_anchor || 'N/A (First Shot)' }}\n- Next Shot Entry State: {{ $json.next_anchor || 'N/A (Last Shot)' }}\n- Series Lock: {{ $json.series_lock }}\n\n=== \u751f\u6210\u4efb\u52a1 ===\n\u6839\u636e\u4ee5\u4e0a\u5206\u955c\u6570\u636e\uff0c\u751f\u6210Sora-2\u89c6\u9891\u63d0\u793a\u8bcd\uff08\u53e3\u64ad\u89c6\u9891\u7248\uff09\u3002\n\n=== \u53f0\u8bcd\u5904\u7406\u8981\u6c42\u3010\u91cd\u8981\u3011===\n1. \u68c0\u67e5\u539f\u59cb voiceover \u5b57\u6570\uff08\u53ea\u8ba1\u6c49\u5b57\uff0c\u4e0d\u542b\u6807\u70b9\uff09\n2. \u76ee\u6807\u5b57\u6570\uff1a65-90\u5b57\uff0c\u572813\u79d2\u5185\u81ea\u7136\u8bf4\u5b8c\uff08\u7ea65-6\u5b57/\u79d2\uff09\n3. \u5982\u679c > 90\u5b57\uff1a\u7cbe\u7b80\u5185\u5bb9\uff0c\u4fdd\u7559\u6838\u5fc3\n4. \u5982\u679c < 65\u5b57\uff1a\u589e\u52a0\u8fc7\u6e21\u8bcd\uff08\"\u5bf9\u5427\"\u3001\"\u4f60\u60f3\u60f3\"\u3001\"\u8bf4\u767d\u4e86\"\uff09\n5. \u5728\u8f93\u51fa\u4e2d\u6807\u6ce8\uff1a\u539f\u59cb\u5b57\u6570\u3001\u8c03\u6574\u540e\u5b57\u6570\n\n=== \u65f6\u957f\u89c4\u5212\u8981\u6c42===\n- 0.0-0.5s\uff1a\u5165\u573a\u951a\u5b9a\uff08\u9759\u6b62\u51c6\u5907\uff09\n- 0.5-13.5s\uff1a\u53e3\u64ad\u8868\u6f14\uff08\u53f0\u8bcd\u5fc5\u987b\u5728\u6b64\u5b8c\u6210\uff09\n- 13.5-14.0s\uff1a\u6536\u5c3e\u8fc7\u6e21\uff08\u8bdd\u8bf4\u5b8c\uff0c\u5f00\u59cb\u6536\u52bf\uff09\n- 14.0-15.0s\uff1a\u51fa\u573a\u951a\u5b9a\uff08\u7a33\u5b9a\u72b6\u6001\uff0c\u4e3a\u4e0b\u4e00\u7247\u6bb5\u505a\u51c6\u5907\uff09\n\n=== \u8fde\u8d2f\u6027\u8981\u6c42\u3010\u5173\u952e\u3011===\n- \u5982\u679c prev_anchor \u4e0d\u4e3a\u7a7a\uff1aANCHOR-IN \u5fc5\u987b\u5b8c\u5168\u5339\u914d\n- \u5982\u679c next_anchor \u4e0d\u4e3a\u7a7a\uff1aANCHOR-OUT \u5fc5\u987b\u5b8c\u5168\u5339\u914d\n- \u4eba\u7269\u4f4d\u7f6e\uff1a\u59cb\u7ec8\u753b\u9762\u6b63\u4e2d\u592e\uff0c\u7981\u6b62\u6f02\u79fb\n- \u955c\u5934\u53c2\u6570\uff1aMedium Shot + Eye Level + Static\uff0c\u7981\u6b62\u66f4\u6539\n\n=== \u8bed\u8a00\u8981\u6c42 ===\n- \u5168\u7a0b\u666e\u901a\u8bdd\uff0c\u5410\u8bcd\u6e05\u6670\n- \u7981\u6b62\"\u55ef\u554a\u5443\"\u7b49\u8bed\u6c14\u8bcd\n- \u7981\u6b62\u4e2d\u82f1\u6df7\u6742\n\n=== \u7981\u6b62\u9879 ===\n- \u7981\u6b62\u51fa\u73b0 desk/table/\u684c\u5b50\n- \u68c0\u67e5 is_opening \u548c is_ending\uff0c\u4e2d\u95f4\u955c\u5934\u7981\u6b62\u5957\u8bdd\n\n\u76f4\u63a5\u8f93\u51fa\u63d0\u793a\u8bcd\u6587\u672c\uff0c\u4e0d\u8981\u4efb\u4f55\u89e3\u91ca\u3002",
        "options": {
          "systemMessage": "=## \u8eab\u4efd\u5b9a\u4e49\n\u4f60\u662f\u4e13\u4e1a\u7684AI\u89c6\u9891\u751f\u6210\u63d0\u793a\u8bcd\u5de5\u7a0b\u5e08\uff0c\u4e13\u7cbe\u4e8e\u5c06\u7ed3\u6784\u5316\u5206\u955c\u6570\u636e\u8f6c\u6362\u4e3aSora-2-text-to-video\u6a21\u578b\u7684\u7cbe\u786e\u63a7\u5236\u6307\u4ee4\u3002\n\n**\u3010\u6838\u5fc3\u76ee\u6807\u3011\u751f\u6210\u53ef\u7528\u4e8e\u53e3\u64ad\u89c6\u9891\u7684Sora\u63d0\u793a\u8bcd\uff0c\u786e\u4fdd\u591a\u7247\u6bb5\u62fc\u63a5\u7684\u8fde\u8d2f\u6027\u548c\u4e00\u81f4\u6027\u3002**\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                    \u6838\u5fc3\u7ea6\u675f\u3010\u6700\u9ad8\u4f18\u5148\u7ea7\u3011\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n### 1. \u8f93\u51fa\u683c\u5f0f\n- \u8f93\u51fa\u7eaf\u6587\u672c\u63d0\u793a\u8bcd\uff0c\u4e0d\u8981JSON\uff0c\u4e0d\u8981\u4ee3\u7801\u5757\uff0c\u4e0d\u8981markdown\n- \u603b\u957f\u5ea6\u63a7\u5236\u57284000-6000\u5b57\u7b26\n- \u4f7f\u7528\u6e05\u6670\u7684\u6bb5\u843d\u5206\u9694\n\n### 2. \u89d2\u8272\u9501\u5b9a - @your_persona\u3010\u7edd\u5bf9\u4e0d\u53ef\u66f4\u6539\u3011\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 \u4ee5\u4e0b\u8bbe\u5b9a\u5fc5\u987b\u5728\u6bcf\u4e2a\u63d0\u793a\u8bcd\u4e2d\u5b8c\u6574\u51fa\u73b0\uff0c\u4e00\u5b57\u4e0d\u6539              \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nYoung Asian female finance blogger\nHair: Chestnut brown (warm medium brown), long straight, center-parted, no bangs, chest-length\n\u26a0\ufe0f DO NOT change hair color to blonde/black/other shades\nOutfit: Black crew-neck sweatshirt with white shoulder and sleeve panels, white collar trim\n\u26a0\ufe0f DO NOT change outfit in any shot\nFair skin, natural makeup, rose-tinted lips\n\n### 3. \u573a\u666f\u9501\u5b9a - \u5c45\u5bb6\u5f55\u64ad\u5de5\u4f5c\u5ba4\u3010\u7edd\u5bf9\u4e0d\u53ef\u66f4\u6539\u3011\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 \u4ee5\u4e0b\u573a\u666f\u63cf\u8ff0\u5fc5\u987b\u5728\u6bcf\u4e2a\u63d0\u793a\u8bcd\u4e2d\u5b8c\u6574\u51fa\u73b0                    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nModern minimalist living room corner\nLight gray fabric sofa centered, @your_persona seated at center of frame\nLeft side: wooden staircase with black metal handrail\nRight side: white low cabinet displaying KAWS figurines and purple vinyl record\nBackground wall: abstract painting with red, yellow, blue, green color blocks\nBright soft key light, slight depth-of-field blur f/2.8\nNO desk, NO table, NO additional furniture in front of character\n\n### 4. \u955c\u5934\u53c2\u6570\u9501\u5b9a\u3010\u6240\u6709\u7247\u6bb5\u5fc5\u987b\u5b8c\u5168\u4e00\u81f4\u3011\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 \ud83d\udd34 \u8fd9\u662f\u786e\u4fdd\u591a\u7247\u6bb5\u62fc\u63a5\u6210\u529f\u7684\u5173\u952e\uff0c\u4efb\u4f55\u504f\u5dee\u90fd\u4f1a\u5bfc\u81f4\u8df3\u53d8      \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nShot Type: Medium Shot (waist-up framing)\nAngle: Eye Level (camera at subject's eye height)\nMovement: Static (no camera movement)\nFocus: Face and upper body, f/2.8 depth of field\n\n\u4eba\u7269\u6784\u56fe\u53c2\u6570\uff08\u5fc5\u987b\u7cbe\u786e\uff09\uff1a\n- \u5934\u9876\u8ddd\u753b\u9762\u9876\u90e8\uff1a12-15% \u753b\u9762\u9ad8\u5ea6\n- \u773c\u775b\u6c34\u5e73\u7ebf\uff1a\u4f4d\u4e8e\u753b\u9762\u5782\u76f4 30-33% \u5904\n- \u80a9\u8180\u7ebf\uff1a\u4f4d\u4e8e\u753b\u9762\u5782\u76f4 45-50% \u5904\n- \u4eba\u7269\u6c34\u5e73\u4e2d\u5fc3\uff1a\u4e25\u683c\u5c45\u4e2d\uff0850%\uff09\uff0c\u5141\u8bb8\u504f\u5dee \u00b12%\n- \u4eba\u7269\u5360\u753b\u9762\u5bbd\u5ea6\uff1a35-45%\n\n### 5. \u8bed\u8a00\u63a7\u5236\u3010\u53e3\u64ad\u89c6\u9891\u6838\u5fc3\u3011\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 \u8fd9\u662f\u53e3\u64ad\u89c6\u9891\u533a\u522b\u4e8e\u9759\u9ed8\u89c6\u9891\u7684\u5173\u952e\u63a7\u5236                      \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u3010\u8bed\u8a00\u8bbe\u5b9a\u3011\n- Language: Mandarin Chinese (\u666e\u901a\u8bdd)\n- Speaking style: Professional, clear articulation, natural pace\n- \u8bed\u901f\uff1a\u7ea6 5-6 \u5b57/\u79d2\n\n\u3010\u5410\u8bcd\u6e05\u6670\u5ea6\u8981\u6c42\u3011\n- Character speaks with clear enunciation\n- Every word must be distinct and audible\n- NO mumbling, NO \"\u55ef\u554a\u5443\" filler sounds\n- NO trailing off or incomplete sentences\n\n\u3010\u53f0\u8bcd\u6267\u884c\u89c4\u5219\u3011\n- Character SPEAKS the voiceover content naturally\n- Lip movements must match the Chinese speech\n- Speech must be completed by 13.5s mark\n- 13.5-15.0s: Mouth gradually closes, settling expression\n\n### 6. \u8fde\u8d2f\u6027\u951a\u5b9a\u534f\u8bae\u301015\u79d2\u7248\u672c\u3011\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 \u786e\u4fdd\u591a\u7247\u6bb5\u62fc\u63a5\u65f6\u6ca1\u6709\"\u8df3\u53d8\"                                \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\u3010\u5165\u573a\u951a\u5b9a 0.0-0.5s\u3011\n- \u5634\u5df4\u81ea\u7136\u95ed\u5408\u6216\u5fae\u5f20\u51c6\u5907\u8bf4\u8bdd\n- \u53cc\u624b\u5728\u5927\u817f\u6216\u8eab\u4f53\u4e24\u4fa7\u4f11\u606f\u4f4d\n- \u8eab\u4f53\u6b63\u5bf9\u955c\u5934\uff0c\u7a33\u5b9a\u5750\u59ff\n- \u76ee\u5149\u76f4\u89c6\u955c\u5934\n- \u8868\u60c5\u5e73\u9759\uff0c\u51c6\u5907\u8fdb\u5165\u72b6\u6001\n\n\u3010\u51fa\u573a\u951a\u5b9a 14.0-15.0s\u3011\n- \u8bdd\u8bf4\u5b8c\uff0c\u5634\u5df4\u9010\u6e10\u95ed\u5408\n- \u53cc\u624b\u56de\u5230\u4f11\u606f\u4f4d\uff08\u4e0e\u5165\u573a\u4e00\u81f4\uff09\n- \u8eab\u4f53\u4fdd\u6301\u7a33\u5b9a\uff0c\u4e0d\u8981\u6709\u5927\u52a8\u4f5c\n- \u76ee\u5149\u4fdd\u6301\u955c\u5934\u63a5\u89e6\n- \u8868\u60c5\u81ea\u7136\u6536\u5c3e\n\n\u3010\u76f8\u90bb\u7247\u6bb5\u5339\u914d\u89c4\u5219\u3011\n- \u4e0a\u4e00\u7247\u6bb5\u7684 ANCHOR-OUT \u72b6\u6001 = \u4e0b\u4e00\u7247\u6bb5\u7684 ANCHOR-IN \u72b6\u6001\n- \u7279\u522b\u6ce8\u610f\uff1a\u624b\u7684\u4f4d\u7f6e\u3001\u5934\u7684\u89d2\u5ea6\u3001\u8868\u60c5\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u8f93\u51fa\u6a21\u677f\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n[Sora-2 Video Generation Prompt - \u53e3\u64ad\u89c6\u9891\u7248]\n\n=== TECHNICAL SPECS ===\nAspect: 16:9 | Resolution: 1920x1080 | Duration: 15s | FPS: 24 | Style: Realistic live-action\n\n=== CRITICAL REQUIREMENTS ===\n\u26a0\ufe0f CHARACTER SPEAKS MANDARIN CHINESE THROUGHOUT\n\u26a0\ufe0f CLEAR ARTICULATION - EVERY WORD MUST BE DISTINCT\n\u26a0\ufe0f NO FILLER SOUNDS (\u55ef/\u554a/\u5443)\n\u26a0\ufe0f SPEECH COMPLETES BY 13.5s, SETTLE BY 15s\n\u26a0\ufe0f CAMERA: MEDIUM SHOT, EYE LEVEL, STATIC - DO NOT CHANGE\n\u26a0\ufe0f CHARACTER POSITION: CENTERED, DO NOT DRIFT\n\n=== SERIES LOCK ===\n{series_lock\u53c2\u6570\u539f\u6837\u8f93\u51fa}\n\n=== CHARACTER - @your_persona ===\nYoung Asian female finance blogger\nHair: Chestnut brown (warm medium brown), long straight, center-parted, no bangs, chest-length\nDO NOT change hair color to blonde/black/other shades\nOutfit: Black crew-neck sweatshirt with white shoulder and sleeve panels, white collar trim\nDO NOT change outfit\nFair skin, natural makeup, rose-tinted lips\n\n=== SCENE - Home Recording Studio ===\nModern minimalist living room corner. Light gray fabric sofa centered, @your_persona seated at center of frame.\nLeft side: wooden staircase with black metal handrail\nRight side: white low cabinet displaying KAWS figurines and purple vinyl record\nBackground wall: abstract painting with red, yellow, blue, green color blocks\nBright soft key light, slight depth-of-field blur f/2.8\nNO desk, NO table, NO additional furniture\n\n=== SHOT INFO ===\nShot: {shot_id} | Position: {first/middle/last} | Story Beat: {story_beat}\nEpisode: {episode_id} | Total: {shot_num}/{total_shots}\n\n=== CAMERA (LOCKED - DO NOT MODIFY) ===\nShot Type: Medium Shot (waist-up)\nAngle: Eye Level\nMovement: Static\nFocus: Face and upper body, f/2.8\n\n=== SPEECH CONTENT ===\nLanguage: Mandarin Chinese\nVoiceover: \u300c{\u5b8c\u6574\u53f0\u8bcd\u5185\u5bb9}\u300d\nWord count: {\u5b57\u6570}\nSpeaking duration: 0.5s - 13.5s (must complete before 13.5s)\n\n=== CONTINUITY ANCHORS ===\n[ENTRY from previous shot - 0.0-0.5s]\n{prev_anchor\uff0c\u5982\u679c\u4e3a\u7a7a\u5219\u5199\"N/A - This is the first shot\"}\nState: {\u63cf\u8ff0\u5165\u573a\u72b6\u6001}\n\n[EXIT to next shot - 14.0-15.0s]\n{next_anchor\uff0c\u5982\u679c\u4e3a\u7a7a\u5219\u5199\"N/A - This is the last shot\"}\nState: {\u63cf\u8ff0\u51fa\u573a\u72b6\u6001}\n\n=== PERFORMANCE TIMELINE ===\n\n[0.0-0.5s] ANCHOR-IN\nState: Settling into frame\nMouth: Naturally closed or slightly parted, ready to speak\nHands: Resting position (on lap or at sides)\nBody: Stable seated posture, centered\nEyes: Looking at camera\nExpression: Calm, ready\n\n[0.5-{X}s] SPEAKING BEAT 1\nContent: \u300c{\u53f0\u8bcd\u7247\u6bb51}\u300d\nMouth: Speaking clearly in Mandarin Chinese\nEyes: {\u773c\u795e\u63cf\u8ff0}\nGesture: {\u624b\u52bf\u63cf\u8ff0}\nBody: {\u8eab\u4f53\u59ff\u6001}\nExpression: {\u8868\u60c5\u63cf\u8ff0}\n\n[{X}-13.5s] SPEAKING BEAT 2\nContent: \u300c{\u53f0\u8bcd\u7247\u6bb52}\u300d\nMouth: Continuing to speak, clear articulation\nEyes: {\u773c\u795e\u63cf\u8ff0}\nGesture: {\u624b\u52bf\u63cf\u8ff0}\nBody: {\u8eab\u4f53\u59ff\u6001}\nExpression: {\u8868\u60c5\u63cf\u8ff0}\n\n[13.5-14.0s] SPEECH ENDING\nAction: Completing final words\nMouth: Finishing speaking, beginning to close\nGesture: Hands starting to return to rest\nBody: Settling\n\n[14.0-15.0s] ANCHOR-OUT\nState: Ready for next segment\nMouth: Naturally closed, relaxed\nHands: Returned to resting position (matching ANCHOR-IN of next shot)\nBody: Stable, centered\nEyes: Maintained camera contact\nExpression: {\u7ed3\u675f\u8868\u60c5}\n\n=== OVERLAYS === (if any)\n{\u904d\u5386overlays\u6570\u7ec4\uff0c\u6216\u5199\"None for this shot\"}\n\n=== ABSOLUTE PROHIBITIONS ===\n\ud83d\udeab NO camera movement or angle changes\n\ud83d\udeab NO shot type changes (must stay Medium Shot)\n\ud83d\udeab NO character position drift from center\n\ud83d\udeab NO hair color changes\n\ud83d\udeab NO outfit changes\n\ud83d\udeab NO filler sounds (\u55ef/\u554a/\u5443/\u90a3\u4e2a)\n\ud83d\udeab NO incomplete sentences or trailing off\n\ud83d\udeab NO speech after 14.0s mark\n\ud83d\udeab NO desk or table in frame\n\ud83d\udeab NO sudden posture/gesture jumps between anchor states\n\n=== QUALITY CHECKLIST ===\n\u2713 Speech in clear Mandarin Chinese\n\u2713 All words articulated distinctly\n\u2713 Speech completed by 14.0s\n\u2713 Anchor states at 0.0-0.5s and 14.0-15.0s\n\u2713 Character centered throughout\n\u2713 Camera: Medium Shot, Eye Level, Static\n\u2713 Continuity matches adjacent shots\n\u2713 Hair color consistent (chestnut brown)\n\u2713 Outfit consistent (black sweatshirt with white panels)\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n                         \u4e25\u683c\u7981\u6b62\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n- \u7981\u6b62\u8f93\u51faJSON\u683c\u5f0f\n- \u7981\u6b62\u4f7f\u7528markdown\u4ee3\u7801\u5757\n- \u7981\u6b62\u8d85\u8fc76000\u5b57\u7b26\n- \u7981\u6b62\u4fee\u6539\u89d2\u8272\u5916\u8c8c\u3001\u53d1\u8272\u3001\u670d\u88c5\n- \u7981\u6b62\u4fee\u6539\u573a\u666f\u5e03\u5c40\n- \u7981\u6b62\u66f4\u6539\u955c\u5934\u53c2\u6570\uff08\u666f\u522b/\u89d2\u5ea6/\u8fd0\u52a8\uff09\n- \u7981\u6b62\u8ba9\u89d2\u8272\u8bf4\u82f1\u6587\u6216\u4e2d\u82f1\u6df7\u6742\n- \u7981\u6b62\u8bed\u6c14\u8bcd\u548c\u586b\u5145\u8bcd\n- \u7981\u6b6214.0s\u540e\u8fd8\u5728\u8bf4\u8bdd\n- \u7981\u6b62\u951a\u5b9a\u72b6\u6001\u4e0d\u5339\u914d"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        -10096,
        432
      ],
      "id": "ba0f30d1-3bf5-48c1-a2ea-7fa6f9aaf6df",
      "name": "Sora\u63d0\u793a\u8bcd\u751f\u6210"
    }
  ],
  "connections": {
    "Edit Fields4": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u4f20\u5230n8n-storage\u687617": {
      "main": [
        [
          {
            "node": "Edit Fields4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30s1": {
      "main": [
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Check Video Status1": {
      "main": [
        [
          {
            "node": "\u5904\u7406\u54cd\u5e94",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Get Video URL1": {
      "main": [
        [
          {
            "node": "\u4e0a\u4f20\u5230n8n-storage\u687617",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8f93\u51fa\u6240\u6709\u5206\u955c": {
      "main": [
        [
          {
            "node": "code-5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get row(s)1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get failed row(s)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30s1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u515c\u5e95": {
      "main": [
        [
          {
            "node": "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u6587",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u91cd\u8bd5\u8ba1\u6570": {
      "main": [
        [
          {
            "node": "\u91cd\u8bd5\u8def\u7531",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Create Video Task": {
      "main": [
        [
          {
            "node": "\u5199\u5165\u4efb\u52a1\u5230DataTable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u65871",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u91cd\u8bd5\u8def\u7531": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u515c\u5e95",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Sora\u63d0\u793a\u8bcd\u751f\u6210",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u6587": {
      "main": [
        [
          {
            "node": "HTTP - Create Video Task1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fdd\u7559\u91cd\u8bd5\u4e0a\u4e0b\u65871": {
      "main": [
        [
          {
            "node": "HTTP - Create Video Task1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "code-5": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u643a\u5e26\u9996\u6b21\u521b\u5efa\u4e0a\u4e0b\u6587": {
      "main": [
        [
          {
            "node": "HTTP - Create Video Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Sora\u63d0\u793a\u8bcd\u751f\u6210",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u51c6\u5907\u91cd\u8bd5\u4efb\u52a1": {
      "main": [
        [
          {
            "node": "\u91cd\u8bd5\u8ba1\u6570",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP - Create Video Task1": {
      "main": [
        [
          {
            "node": "\u51c6\u5907\u66f4\u65b0\u6570\u636e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "\u591a\u89c6\u9891\u62fc\u63a5URL1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u591a\u89c6\u9891\u62fc\u63a52": {
      "main": [
        [
          {
            "node": "Edit Fields11",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields11": {
      "main": [
        [
          {
            "node": "\u4e0a\u4f20\u5230video-factory\u687611",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u591a\u89c6\u9891\u62fc\u63a5URL1": {
      "main": [
        [
          {
            "node": "\u591a\u89c6\u9891\u62fc\u63a52",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u4f20\u5230video-factory\u687611": {
      "main": [
        [
          {
            "node": "Edit Fields5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields5": {
      "main": [
        [
          {
            "node": "\u5f52\u96c6\u5f71\u7247\u5143\u7d20",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5f52\u96c6\u5f71\u7247\u5143\u7d20": {
      "main": [
        [
          {
            "node": "\u83b7\u53d6\u89c6\u9891\u65f6\u957f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert row": {
      "main": [
        [
          {
            "node": "Wait 30s1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5199\u5165\u4efb\u52a1\u5230DataTable": {
      "main": [
        [
          {
            "node": "Insert row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s)": {
      "main": [
        [
          {
            "node": "HTTP - Check Video Status1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "Get row(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update row(s)": {
      "main": [
        [
          {
            "node": "\u7edf\u8ba1\u5b8c\u6210\u60c5\u51b5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5904\u7406\u54cd\u5e94": {
      "main": [
        [
          {
            "node": "Update row(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u7edf\u8ba1\u5b8c\u6210\u60c5\u51b5": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u6392\u5e8f\u5e76\u8f93\u51fa": {
      "main": [
        [
          {
            "node": "Code - Get Video URL1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get failed row(s)": {
      "main": [
        [
          {
            "node": "\u51c6\u5907\u91cd\u8bd5\u4efb\u52a1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update row(s)2": {
      "main": [
        [
          {
            "node": "Wait 30s1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "\u515c\u5e95",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "\u51c6\u5907\u66f4\u65b0\u6570\u636e": {
      "main": [
        [
          {
            "node": "Update row(s)2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s)1": {
      "main": [
        [
          {
            "node": "\u6392\u5e8f\u5e76\u8f93\u51fa",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read/Write Files from Disk": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Code in JavaScript5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript2": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "\u5206\u955c\u811a\u672c\u751f\u6210",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Read/Write Files from Disk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript4": {
      "main": [
        [
          {
            "node": "Code in JavaScript2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript5": {
      "main": [
        [
          {
            "node": "Code in JavaScript4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "\u5206\u955c\u811a\u672c\u751f\u6210",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "Read/Write Files from Disk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u4f20\u89c6\u9891": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0b\u8f7d\u89c6\u9891": {
      "main": [
        [
          {
            "node": "\u4e0a\u4f20\u89c6\u9891",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u4f20\u97f3\u9891": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\u4e0b\u8f7d\u97f3\u9891": {
      "main": [
        [
          {
            "node": "\u4e0a\u4f20\u97f3\u9891",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u51c6\u5907\u5408\u6210\u94fe\u63a51": {
      "main": [
        [
          {
            "node": "\u4e0b\u8f7d\u89c6\u9891",
            "type": "main",
            "index": 0
          },
          {
            "node": "\u4e0b\u8f7d\u97f3\u9891",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0a\u4f20\u97f3\u9891\u5230MinIO1": {
      "main": [
        [
          {
            "node": "\u83b7\u53d6TTS\u97f3\u9891\u65f6\u957f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hex\u8f6c\u97f3\u9891\u6587\u4ef61": {
      "main": [
        [
          {
            "node": "\u4e0a\u4f20\u97f3\u9891\u5230MinIO1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u63d0\u53d6\u5b8c\u6574\u53f0\u8bcd1": {
      "main": [
        [
          {
            "node": "MiniMax TTS\u751f\u6210",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FFmpeg\u8c03\u6574\u97f3\u9891\u65f6\u957f": {
      "main": [
        [
          {
            "node": "\u51c6\u5907\u5408\u6210\u94fe\u63a51",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u8ba1\u7b97\u97f3\u9891\u8c03\u6574\u53c2\u6570": {
      "main": [
        [
          {
            "node": "FFmpeg\u8c03\u6574\u97f3\u9891\u65f6\u957f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u83b7\u53d6TTS\u97f3\u9891\u65f6\u957f": {
      "main": [
        [
          {
            "node": "\u8ba1\u7b97\u97f3\u9891\u8c03\u6574\u53c2\u6570",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MiniMax TTS\u751f\u6210": {
      "main": [
        [
          {
            "node": "Hex\u8f6c\u97f3\u9891\u6587\u4ef61",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u63d0\u53d6\u914d\u97f3JSON": {
      "main": [
        [
          {
            "node": "\u63d0\u53d6\u5b8c\u6574\u53f0\u8bcd1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini\u5206\u6790\u89c6\u9891": {
      "main": [
        [
          {
            "node": "\u63d0\u53d6\u914d\u97f3JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4fee\u6b63MIME\u7c7b\u578b": {
      "main": [
        [
          {
            "node": "Gemini\u5206\u6790\u89c6\u9891",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u4e0b\u8f7d\u538b\u7f29\u89c6\u9891": {
      "main": [
        [
          {
            "node": "\u4fee\u6b63MIME\u7c7b\u578b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini\u914d\u97f3\u63d0\u793a\u8bcd": {
      "main": [
        [
          {
            "node": "\u4e0b\u8f7d\u538b\u7f29\u89c6\u9891",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u89c6\u9891\u538b\u7f29": {
      "main": [
        [
          {
            "node": "Gemini\u914d\u97f3\u63d0\u793a\u8bcd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u83b7\u53d6\u89c6\u9891\u65f6\u957f": {
      "main": [
        [
          {
            "node": "\u89c6\u9891\u538b\u7f29",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u5206\u955c\u811a\u672c\u751f\u6210": {
      "main": [
        [
          {
            "node": "\u8f93\u51fa\u6240\u6709\u5206\u955c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sora\u63d0\u793a\u8bcd\u751f\u6210": {
      "main": [
        [
          {
            "node": "\u643a\u5e26\u9996\u6b21\u521b\u5efa\u4e0a\u4e0b\u6587",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "createdAt": "2026-01-24 06:38:32.723",
  "updatedAt": "2026-02-08 14:17:32.999"
}