{
  "name": "万川 API｜视频生视频（H.264 MP4 原始视频直传）",
  "nodes": [
    {
      "parameters": {},
      "id": "d93ecf6c-0dcf-4d3f-a344-0a37285b6191",
      "name": "手动触发",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1340,
        220
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cf707f02-b7bc-445c-a0f6-c4a317d7ae82",
              "name": "input_file",
              "value": "D:/n8n-input/reference.mp4",
              "type": "string"
            },
            {
              "id": "14cda259-f032-407d-aeb6-46e78702966a",
              "name": "model",
              "value": "bytedance/seedance-2.5-high-speed",
              "type": "string"
            },
            {
              "id": "5ba1fd83-e304-49ed-9af4-d36e9960a386",
              "name": "prompt",
              "value": "保持原视频主体、动作连续性和画面结构，生成自然稳定的风格变化。",
              "type": "string"
            },
            {
              "id": "eb47d751-e135-489c-9b93-657f93d7fa85",
              "name": "duration",
              "value": 4,
              "type": "number"
            },
            {
              "id": "31afe5dc-64cd-4e27-b905-021c05f7fa21",
              "name": "resolution",
              "value": "480p",
              "type": "string"
            },
            {
              "id": "e57f3b5e-b0f7-4aaf-9d2f-ae75ad519c5e",
              "name": "aspect_ratio",
              "value": "auto",
              "type": "string"
            },
            {
              "id": "cbaea48b-af21-4420-92f6-7a01b586e586",
              "name": "idempotency_nonce",
              "value": "REPLACE_WITH_UNIQUE_RUN_NONCE_MIN_8_CHARS",
              "type": "string"
            },
            {
              "id": "924896c3-7fb8-431d-af8f-dc607aee643f",
              "name": "provider_processing_acknowledged",
              "value": false,
              "type": "boolean"
            },
            {
              "id": "4afde411-9be9-4936-9495-eddd5c1d6725",
              "name": "poll_limit",
              "value": 360,
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "id": "eeb1e350-c755-451a-91b8-140e441859d1",
      "name": "万川｜运行配置",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1120,
        220
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "fileSelector": "={{ $node[\"万川｜运行配置\"].json.input_file }}",
        "options": {}
      },
      "id": "9dc2ccfc-c301-43ed-b8f6-ae61c540e7a0",
      "name": "万川｜读取参考视频",
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1,
      "position": [
        -900,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "const item = $input.first();\nconst config = $node['万川｜运行配置'].json;\nif (!item.binary?.data) throw new Error('缺少 binary.data 参考视频');\nif (config.provider_processing_acknowledged !== true) {\n  throw new Error('请在阅读万川所选模型的数据处理说明后，在“万川｜运行配置”中明确开启处理确认');\n}\nconst nonce = String(config.idempotency_nonce || '').trim();\nif (!/^[A-Za-z0-9._:-]{8,96}$/.test(nonce) || nonce.startsWith('REPLACE_')) {\n  throw new Error('请为本次逻辑任务设置 8–96 位唯一 idempotency_nonce；响应超时后重跑必须保持不变，新任务必须更换');\n}\nconst binary = item.binary.data;\nconst contentType = String(binary.mimeType || '').trim().toLowerCase();\nif (contentType !== 'video/mp4') throw new Error('参考视频必须预先转换为 H.264 MP4，MIME type 必须是 video/mp4');\nif (!binary.id) throw new Error('大视频必须使用 n8n filesystem 或企业 external binary mode；本模板拒绝把 inline binary 全量载入内存');\nconst metadata = await this.helpers.getBinaryMetadata(binary.id);\nconst contentLength = Number(metadata?.fileSize);\nif (!Number.isSafeInteger(contentLength) || contentLength <= 0) throw new Error('无法从 n8n binary metadata 取得准确视频字节数');\nif (contentLength > 500 * 1024 * 1024) throw new Error('参考视频不能超过万川 500 MiB 接收上限');\nconst duration = Number(config.duration);\nif (!Number.isInteger(duration) || duration < 4 || duration > 30) throw new Error('运行配置 duration 必须是 4 到 30 的整数');\nconst pollLimit = Number(config.poll_limit);\nif (!Number.isInteger(pollLimit) || pollLimit < 1 || pollLimit > 1440) throw new Error('运行配置 poll_limit 必须是 1 到 1440 的整数');\nconst model = String(config.model || '').trim();\nconst prompt = String(config.prompt || '').trim();\nif (!model || !prompt) throw new Error('运行配置 model 和 prompt 不能为空');\nreturn [{\n  json: {\n    content_type: contentType,\n    content_length: contentLength,\n    idempotency_nonce: nonce,\n    model,\n    prompt,\n    duration,\n    resolution: String(config.resolution || '').trim(),\n    aspect_ratio: String(config.aspect_ratio || '').trim(),\n    poll_limit: pollLimit\n  },\n  binary: item.binary\n}];"
      },
      "id": "e761057d-d204-4a2b-866c-e8e0a10382a6",
      "name": "万川｜准备视频上传",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -680,
        220
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.wanchuanapi.com/v1/media/inputs",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "={{ ('n8n-video-input-' + $node[\"万川｜准备视频上传\"].json.idempotency_nonce).slice(0, 128) }}"
            },
            {
              "name": "Content-Type",
              "value": "={{ $json.content_type }}"
            },
            {
              "name": "Content-Length",
              "value": "={{ String($json.content_length) }}"
            }
          ]
        },
        "sendBody": true,
        "contentType": "binaryData",
        "inputDataFieldName": "data",
        "options": {
          "timeout": 600000
        }
      },
      "id": "2c6766b7-cc3f-40d7-b01a-c11c52cbce8d",
      "name": "万川｜上传媒体输入",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -440,
        100
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_WANCHUAN_CREDENTIAL_ID",
          "name": "万川 API Bearer（导入后选择）"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.wanchuanapi.com/v1/media/jobs",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "={{ ('n8n-video-job-' + $node[\"万川｜准备视频上传\"].json.idempotency_nonce).slice(0, 128) }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ kind: 'video_generation', model: $node[\"万川｜准备视频上传\"].json.model, prompt: $node[\"万川｜准备视频上传\"].json.prompt, parameters: { input_asset_ids: [$node[\"万川｜上传媒体输入\"].json.input.id], duration: $node[\"万川｜准备视频上传\"].json.duration, resolution: $node[\"万川｜准备视频上传\"].json.resolution, ...($node[\"万川｜准备视频上传\"].json.aspect_ratio && $node[\"万川｜准备视频上传\"].json.aspect_ratio !== 'auto' ? { aspect_ratio: $node[\"万川｜准备视频上传\"].json.aspect_ratio } : {}), generate_audio: false, provider_processing_acknowledged: true } }) }}",
        "options": {
          "timeout": 45000
        }
      },
      "id": "dc23d364-a09e-4305-9363-d3d355033106",
      "name": "万川｜创建视频生视频任务",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        520,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_WANCHUAN_CREDENTIAL_ID",
          "name": "万川 API Bearer（导入后选择）"
        }
      }
    },
    {
      "parameters": {
        "amount": 5,
        "unit": "seconds"
      },
      "id": "153a6218-b6a8-4659-a47f-3cdbf5dd9922",
      "name": "等待 5 秒",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        760,
        220
      ],
      "webhookId": "6bce63c9-0eb4-43d0-b4fc-aa59a585eb2d"
    },
    {
      "parameters": {
        "url": "={{ 'https://api.wanchuanapi.com/v1/media/jobs/' + encodeURIComponent($node[\"万川｜创建视频生视频任务\"].json.id) }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 45000
        }
      },
      "id": "f5cf6f32-d4b9-4a4c-b3cf-afbdb3c4bd08",
      "name": "万川｜查询任务",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1000,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_WANCHUAN_CREDENTIAL_ID",
          "name": "万川 API Bearer（导入后选择）"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const job = $input.first().json;\nconst status = String(job.status || '').toLowerCase();\nif (['failed', 'cancelled', 'canceled', 'expired', 'submission_uncertain'].includes(status)) {\n  const safeMessage = String(job.error_message || '未返回详情').replace(/https?:\\/\\/\\S+/gi, '[redacted-url]').slice(0, 500);\n  throw new Error(`万川任务失败（${job.error_code || status}）：${safeMessage}`);\n}\nconst done = ['succeeded', 'completed', 'success'].includes(status);\nconst pollLimit = Number($node['万川｜运行配置'].json.poll_limit);\nconst pollCount = $runIndex + 1;\nif (!done && pollCount >= pollLimit) throw new Error(`已达到万川轮询上限 ${pollLimit} 次；工作流不会自动重提收费任务`);\nif (done && !job.asset_id) {\n  throw new Error('任务已完成但没有返回 asset_id；为避免绕开万川连接，本模板不会改连其他下载节点');\n}\nreturn [{ json: { ...job, output_url: undefined, poll_count: pollCount, done } }];"
      },
      "id": "e033e732-7739-417a-b4b8-5fa462c047a7",
      "name": "万川｜检查任务状态",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        220
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "e6b8b25a-335d-4f33-86c7-887090aed910",
              "leftValue": "={{ $json.done }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "8d025e2d-61a6-4f1a-817f-e08d66d0dc90",
      "name": "万川｜是否完成",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1480,
        220
      ]
    },
    {
      "parameters": {
        "url": "={{ 'https://api.wanchuanapi.com/v1/media/assets/' + encodeURIComponent($json.asset_id) }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "data"
            }
          },
          "timeout": 120000
        }
      },
      "id": "52055643-1e3c-4152-b11b-05dc4f215077",
      "name": "万川｜下载生成结果",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1720,
        120
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_WANCHUAN_CREDENTIAL_ID",
          "name": "万川 API Bearer（导入后选择）"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "手动触发": {
      "main": [
        [
          {
            "node": "万川｜运行配置",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜运行配置": {
      "main": [
        [
          {
            "node": "万川｜读取参考视频",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜读取参考视频": {
      "main": [
        [
          {
            "node": "万川｜准备视频上传",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜准备视频上传": {
      "main": [
        [
          {
            "node": "万川｜上传媒体输入",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜上传媒体输入": {
      "main": [
        [
          {
            "node": "万川｜创建视频生视频任务",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜创建视频生视频任务": {
      "main": [
        [
          {
            "node": "等待 5 秒",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "等待 5 秒": {
      "main": [
        [
          {
            "node": "万川｜查询任务",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜查询任务": {
      "main": [
        [
          {
            "node": "万川｜检查任务状态",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜检查任务状态": {
      "main": [
        [
          {
            "node": "万川｜是否完成",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "万川｜是否完成": {
      "main": [
        [
          {
            "node": "万川｜下载生成结果",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "等待 5 秒",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveDataErrorExecution": "none",
    "saveDataSuccessExecution": "none",
    "saveManualExecutions": false,
    "saveExecutionProgress": false,
    "redactionPolicy": "all"
  },
  "versionId": "f839801f-f0fd-4311-b6de-048605475520",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
