jimeng-api.md 13 KB

即梦 API 通道(jimeng)

本文件是 skill-mv 唯一真实可用的生成通道的完整参考。 来源:kb-raw/07-即梦API工具箱/(脚本 + 参考文档/即梦AI技能汇总.md + 参考文档/README_v2.md), 并已在 2026-10-13 于本容器实测复核(见 out/verify-*.log)。 代码实现:lib/jimeng.mjs(底层)+ lib/providers.mjs 的 jimeng provider。


一、为什么是即梦

技能仓原先的两条生成通道都不可用:

原通道 端点 实测结果
AI 音乐 /suno/submit/music 503 Task request failed(渠道未开通)
图生视频 /v1/video/generations 503 No available channel for model doubao-seedance-1-0-pro
唇形驱动 — 网关无此路由(返回前端兜底页)
TTS /v1/audio/speech 网关无此路由

即梦通道(https://server.fmode.cn/api/volcengine/jimeng)全部实测可用,并且一次覆盖四个缺口: 文生图、图生图、图生视频、数字人/动作模仿(后两者直接替代了唇形驱动)。


二、三段式调用(所有即梦能力的通用范式)

任何即梦生成任务都走同样的三步。记住它,就掌握了全部 20 个端点。

① 提交 → 拿 workId

POST https://server.fmode.cn/api/volcengine/jimeng/<endpoint>
Content-Type: application/json

{ "...业务参数": "...", "token": "Bearer <sessionToken>" }

成功响应:

{ "code": 200, "data": { "workId": "5mn57IrZRg" } }

② 轮询 → 等 isFinish

POST https://server.fmode.cn/api/volcengine/jimeng/getDataByTask02
Content-Type: application/json

{ "workId": "5mn57IrZRg", "routerName": "getImgV4", "token": "Bearer <sessionToken>" }

响应:

{ "code": 200, "data": { "tip": "生成成功", "isFinish": true } }

生成中:

{ "code": 200, "data": { "tip": "生成中,请等待...", "isFinish": false } }

数字人例外:查询走 /getOhDateByTask(不是 getDataByTask02), 且步骤①主体识别用 isContinue 而非 isFinish 表示「可进下一步」。

③ 取产物 → 拿直链

GET https://server.fmode.cn/parse/classes/ImagineWork/{workId}
X-Parse-Application-Id: ncloudmaster

响应(只列关键字段):

{
  "objectId": "5mn57IrZRg",
  "images": ["https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/aigc/imagine/5mn57IrZRg-0.png"],
  "videos": null,
  "usage": { "cost": 0.2, "credit": 2 },
  "credit": 2,
  "provider": "volcengine"
}
  • 图片任务 → images[];视频任务 → videos[]。
  • 直链在华为云 OBS,永久有效,可直接 wget(无需鉴权头)。
  • usage.cost 是实扣金额(元),credit 是平台积分(1 credit = ¥0.1)。 → 本技能的费用台账优先采信 usage.cost,而不是预估。

三、端点与费用总表

端点 key path 费用 单位 说明
text2imgV3 /getText2ImgV3 ¥0.20 张 文生图3.0
text2imgV31 /getText2ImgV31 ¥0.20 张 文生图3.1(美感更强)
imgV4 /getImgV4 ¥0.22 张 图片生成4.0(文生图 / 多图组合)
img2imgV3 /getImg2ImgV3 ¥0.20 张 图生图3.0 智能参考
imgV4Goods /getImgV4_goods ¥0.22 张 商品提取
imgV4Pod /getImgV4_pod ¥0.22 张 素材提取
clothesV2 /getClothesV2 ¥0.22 张 虚拟换装v2
inpaint /getInpaint ¥0.20 张 局部重绘 / 消除笔
superRes /getSuperResolution ¥0.40 张 智能超清
actor /getActor ¥0.50 秒 动作模仿1.0(单条 ¥4~6,最低 ¥4)
actorV2 /getActorV2 ¥0.40 秒 动作模仿2.0(单条 ¥3.2~5,最低 ¥3.2)
video720 /getVideoV3_720p ¥0.28 秒 图生视频3.0 720p(主力)
video1080 /getVideoV3_1080p ¥0.63 秒 图生视频3.0 1080p
videoPro /getVideoV3_Pro ¥1.00 秒 图生视频3.0 Pro(多镜头叙事)
ohIdentify /getOhIdentifyMain 免费 次 数字人·主体识别
ohDetect /getOhDetectMain 免费 次 数字人·主体检测(可选)
omniHuman /getOmniHuman ¥1.00 秒 数字人·视频生成

费用表与 KB 即梦AI技能汇总.md 一致,usage.cost 已实测校验。


四、鉴权

所有请求 body 必须带 token,格式 "Bearer <sessionToken>"。 缺失时返回 HTTP 403:

{ "error": { "message": "请输入API_KEY或用户sessionToken" } }

sessionToken 的取法(运行时读取,绝不硬编码):

// lib/jimeng.mjs
const sess = process.env.FMODE_SESSION_TOKEN
  || JSON.parse(fs.readFileSync('/opt/data/fmode-identity.json', 'utf8')).session_token;
const TOKEN = 'Bearer ' + sess;

⚠️ KB 里的原始脚本把 token 硬编码成了 Bearer r:f03...。 本技能仓一律改为运行时读取,任何文件、日志、产物里都不出现明文 token。


五、参数细节(踩过坑的部分)

5.1 尺寸 sizeDate —— 不同端点约束不同

端点 面积约束 宽高比 推荐尺寸
text2imgV3 / text2imgV31 / img2imgV3 [512², 2048²] [1/3, 3] 1K:1664×936(16:9)、1328×1328(1:1)、1472×1104(4:3);2K:2560×1440、2048×2048、2304×1728
imgV4 / imgV4_goods / imgV4_pod [1024², 4096²] [1/3, 3] 2K:2560×1440(16:9)、2048×2048(1:1)、2304×1728(4:3);4K:5404×3040(16:9)、4096×4096

实测踩坑(本次修复):给 getImgV4 传 1280×720(面积 921,600 < 1,048,576)时, 提交阶段返回 200 + workId,轮询 15 秒后才报错:

> {"algo_code":100199,"algo_msg":"run comfyui pipeline error:
>   nodeid:[155], node_type:[BADataProcessingTransform], message: height or width invalid "}
> ```
> 因此 `lib/jimeng.mjs` 的 `assertValidSize()` 会在**本地**先卡住,避免白等一轮。
> 用 `resolveSize(endpoint, aspect, tier)` 取推荐尺寸。

### 5.2 视频 frames —— 必须 ≡ 1 (mod 24)

jsonc { "prompt": "…", // ≤400 字(建议),最长 800 字 "frames": 121, // ★ 范围 [121, 241],且 frames % 24 === 1 "method": "2", // '2'=首帧 '3'=首尾帧 "config": { "image_urls": [ "https://…/first.png" ] } // method=3 时传 [首, 尾] 两张 }


> **实测踩坑(本次修复)**:`frames=122` 被拒
> `x2v pipeline: frames % 24 should be 1`;`frames=49` 被拒 `frames 取值范围为[121,241]`。
> 合法值只有 **121 / 145 / 169 / 193 / 217 / 241**,对应 **5 / 6 / 7 / 8 / 9 / 10 秒**。
> 也就是说:**图生视频单镜只能是 5~10 秒的整数秒**,不存在 3 秒或 13 秒的镜头。

### 5.3 首帧图片要求

- 图片长边与短边比例必须在 **3 以内**(即 `max(w,h)/min(w,h) ≤ 3`)。
- `method=3`(首尾帧)的**尾帧必须与首帧同比例**。
- 输出视频的**画幅跟随输入图**,不跟随 `sizeDate`。

### 5.4 参考图数量

`getImgV4` 的 `image_urls` 支持 **0~10 张**,因此可以一次塞多张参考:

- **人物资产流程**:`[上一步的成品图]` 1 张
- **场景 + 人物关键帧**:`[场景图, 人物多视图]` 2 张(本技能 `scene` 工序的做法)
- **`scale`**:文本影响程度 `[0,1]`,默认 0.5。要在保留参考图特征的同时较多体现 prompt,用 0.5~0.7。

---

## 六、图片预处理与公网化(图生图/图生视频的必经步骤)

即梦只吃**公网 URL**,不吃本地文件。所以任何本地图都要先上传七牛。

### 6.1 压缩(避免体积超限)

KB 的踩坑记录:即梦二进制输入限制约 **4~5MB**(base64 字符串),大 PNG 直传报
`Image Decode Error: invalid binary data file size`。

js // 本技能的实现:lib/jimeng.mjs 的 prepareImageUrl() // 原图 ≤3MB 直接上传;否则 ffmpeg 压到 1280×720 JPEG q4(≈150~300KB) ffmpeg -y -v error -i in.png \ -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" \ -q:v 4 out.jpg


> 经验值:`2560×1440 PNG (~5.6MB)` → `1280×720 JPEG (~200KB)`,base64 从 ~750 万字符降到 ~28 万字符。

### 6.2 上传七牛(拿公网直链)

① POST https://server.fmode.cn/parse/functions/qiniu_uptoken headers: X-Parse-Application-Id: ncloudmaster body: { "company": "XlTE6uWQEQ" } → { "result": { "uptoken": "...", "domain": "https://file-cloud.fmode.cn/",

               "zoneUrl": "https://upload-z2.qiniup.com/", "max_file_size": 400 } }

② POST {zoneUrl} (multipart/form-data) fields: token={uptoken}, key={key}, file={二进制} → { "hash": "...", "key": "storage/company/XlTE6uWQEQ/20261013/…-photo.jpg" }

③ 公网直链 = {domain} + {key} = https://file-cloud.fmode.cn/storage/company/XlTE6uWQEQ/20261013/…-photo.jpg


`key` 命名规则(照抄 KB):`storage/company/{cid}/{yyyymmdd}/{hhmmss}-{rand6}-{filename}`

> **注意**:`company` 必须是**真实存在的公司 ID**,传错会返回
> `{"code":141,"error":"Object not found."}`。
> 本仓默认用 KB 里的 `XlTE6uWQEQ`(实测可用),可用 `FMODE_CDN_COMPANY` 覆盖。

---

## 七、数字人 v1.5 完整流程

① getOhIdentifyMain body: { image_url } → workId 轮询 /getOhDateByTask { workId, routerName:'getOhIdentifyMain' } 注意:成功标志是 data.isContinue,不是 isFinish

② getOhDetectMain body: { workId } (可选,返回 mask 图)

③ getOmniHuman body: { workId, audio_url, prompt?, pe_fast_mode:true } 轮询 /getOhDateByTask { workId, routerName:'getOmniHuman' } → ImagineWork.videos[0]


- 图片与音频都要先上传公网。
- 费用 ¥1/秒。
- **并发限制**:并发过高返回 `error.message.errmsg.status === 50430`,
  需退避重试(KB 的做法:`10000 * (retry + 1)` 毫秒,最多 5 次)。

---

## 八、错误码与陷阱速查

| 现象 | 原因 | 处理 |
|---|---|---|
| HTTP 403 `请输入API_KEY或用户sessionToken` | token 缺失/失效 | 检查 `FMODE_SESSION_TOKEN` |
| 提交 200 但轮询报 `height or width invalid` | `getImgV4` 面积 < 1024² | 用 `resolveSize('imgV4', …)` |
| `frames % 24 should be 1` | frames 非法 | 只用 121/145/169/193/217/241 |
| `frames 取值范围为[121,241]` | 想生成 <5s 或 >10s | 单镜固定 5~10 秒 |
| `Object not found.` (HTTP 500) | workId 不存在 | 核对 workId;探活用这个报错判断鉴权 OK |
| `50430` / `Concurrent Limit` | 并发限制 | 退避重试;批量任务之间 sleep |
| 轮询返回 `<!DOCTYPE html>` | 服务端错误 | 不解析,等下一轮重试 |
| `isFinish=true` 但 `videos` 为空 | 偶发 | 再查一次 `ImagineWork` 记录 |
| `Image Decode Error: invalid binary data file size` | 参考图/首帧图过大 | 先压缩到 ≤3MB |
| URL 返回带引号 | 偶发 | 下载前 `url.trim().replace(/^["']|["']$/g, '')` |

---

## 九、命令行速查(本技能封装)

bash fmode-mv jimeng --status # 通道状态(不花钱) fmode-mv jimeng --endpoints # 端点 + 费用表 fmode-mv jimeng --work # 查已有任务的产物直链 fmode-mv jimeng --test # 真跑一张最小文生图(¥0.20)

fmode-mv jimeng text2img --prompt "..." --width 1024 --height 1024 fmode-mv jimeng img2img --prompt "..." --ref a.png --ref b.png --scale 0.6 fmode-mv jimeng img2video --first a.png --last b.png --prompt "..." --seconds 5 fmode-mv jimeng upscale --ref a.png --resolution 4k fmode-mv jimeng actor --ref a.png --video-url "https://….mp4" fmode-mv jimeng digital-human --ref a.png --audio a.mp3 --prompt "固定机位,自然微动" fmode-mv jimeng upload --ref a.png # 只上传拿直链 ```

所有调用都会先打印预估费用,跑完打印实扣/耗时/产物路径与字节数。


十、本技能仓的封装位置

文件 职责
lib/jimeng.mjs 三段式调用、尺寸/帧数本地校验、七牛上传、数字人流程、费用台账
lib/providers.mjs → jimeng 统一接口:text2img / img2img / img2video / actor / digitalHuman / upscale
scripts/jimeng.mjs CLI 直调
scripts/character-sheet.mjs 人物资产四步流水线(用 text2img + img2img)
scripts/scene.mjs 场景图(text2img)+ 关键帧(img2img 多图参考)
scripts/video.mjs 图生视频(img2video,含 method=3 → method=2 降级)