{
  "name": "万川 API｜图片生视频（原始图片直传）",
  "nodes": [
    {
      "parameters": {},
      "id": "1f34d824-6e1d-4b77-b137-e8c3232567f0",
      "name": "手动触发",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1340,
        220
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "142a01d3-10a6-481d-bc60-7a2e30c6a217",
              "name": "input_file",
              "value": "D:/n8n-input/reference.png",
              "type": "string"
            },
            {
              "id": "c8ac6890-0955-4c26-8111-91a982cfec2c",
              "name": "model",
              "value": "bytedance/seedance-2.5-high-speed",
              "type": "string"
            },
            {
              "id": "005e38a7-a3e9-4257-8677-f139dd190b07",
              "name": "prompt",
              "value": "保持主体和商品外观一致，生成自然、稳定的镜头运动。",
              "type": "string"
            },
            {
              "id": "38acfa88-4009-42bb-b830-5df1fbcd6966",
              "name": "duration",
              "value": 4,
              "type": "number"
            },
            {
              "id": "1f6cfbed-fc98-4a8e-bc4e-8fbc00932358",
              "name": "resolution",
              "value": "480p",
              "type": "string"
            },
            {
              "id": "325cc632-2030-4a23-848d-90abcb8f1cb1",
              "name": "aspect_ratio",
              "value": "16:9",
              "type": "string"
            },
            {
              "id": "bf22b489-79c3-45df-a607-a448be77143e",
              "name": "idempotency_nonce",
              "value": "REPLACE_WITH_UNIQUE_RUN_NONCE_MIN_8_CHARS",
              "type": "string"
            },
            {
              "id": "7c4ccb71-6ff3-46a6-a54c-829e19af6af5",
              "name": "provider_processing_acknowledged",
              "value": false,
              "type": "boolean"
            },
            {
              "id": "b1cf8874-c4f4-46c4-8502-c3d21ac17cf7",
              "name": "poll_limit",
              "value": 360,
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "id": "99b6622e-2e40-4d97-8533-b3a82cae75c8",
      "name": "万川｜运行配置",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1120,
        220
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "fileSelector": "={{ $node[\"万川｜运行配置\"].json.input_file }}",
        "options": {}
      },
      "id": "c9a4fb86-5bc5-4fc6-b040-566a4a062783",
      "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 (!['image/png', 'image/jpeg', 'image/webp'].includes(contentType)) throw new Error('参考图必须是 PNG、JPEG 或 WebP');\nlet contentLength;\nif (binary.id) {\n  const metadata = await this.helpers.getBinaryMetadata(binary.id);\n  contentLength = Number(metadata?.fileSize);\n} else {\n  const bytes = await this.helpers.getBinaryDataBuffer(0, 'data');\n  contentLength = bytes.length;\n}\nif (!Number.isSafeInteger(contentLength) || contentLength <= 0) throw new Error('无法从 n8n binary metadata 取得准确图片字节数');\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": "2c68730b-5785-4945-8ce6-5ee7930c318f",
      "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-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": "da209f7b-f497-45e0-b9fc-ae924a682b1d",
      "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-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, aspect_ratio: $node[\"万川｜准备图片上传\"].json.aspect_ratio, generate_audio: false, provider_processing_acknowledged: true } }) }}",
        "options": {
          "timeout": 45000
        }
      },
      "id": "104a78d8-a83b-4023-998c-348f70c1ae8e",
      "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": "c6eb88a5-ddde-4514-af5d-c95adfcd5c27",
      "name": "等待 5 秒",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        760,
        220
      ],
      "webhookId": "23fa8d34-773d-4a39-befa-90f9c393b5d4"
    },
    {
      "parameters": {
        "url": "={{ 'https://api.wanchuanapi.com/v1/media/jobs/' + encodeURIComponent($node[\"万川｜创建图片生视频任务\"].json.id) }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 45000
        }
      },
      "id": "533580b7-a0b5-4acd-a112-e7cad6ab8f95",
      "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": "ffac0b00-cb59-4604-97e6-a54d52714d7b",
      "name": "万川｜检查任务状态",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        220
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "debcf047-bdd0-4a15-84f9-6b15520202be",
              "leftValue": "={{ $json.done }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "2756625d-4b4b-4218-971c-22cb88d66ea3",
      "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": "665149c1-7634-4af0-89d2-d3b245223cb1",
      "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": "85df3c7c-fc5e-446c-860a-675504b432a6",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
