提炼自
kb-raw/04-SOP工作流/…/flow/4-视频生成prompt.md(含降级策略与图片压缩), 参数约束以本仓实测为准(见references/jimeng-api.md)。这是 VOC-SOP 阶段 4b 的提示词与参数规范:把关键帧变成 AI 视频片段。 本技能对应
fmode-mv video。
| 参数 | 约束 | 说明 |
|---|---|---|
frames |
[121, 241] 且 ≡ 1 (mod 24) |
合法值只有 121/145/169/193/217/241 |
| 单镜时长 | 只能是 5~10 秒的整数秒 | frames = 24 × 秒数 + 1 |
method |
'2' 首帧 / '3' 首尾帧 |
'3' 需要 2 张同比例图 |
config.image_urls |
method=2 → 1 张;method=3 → [首帧, 尾帧] 2 张 |
|
| 首帧图比例 | 长边 / 短边 ≤ 3 | 否则被拒 |
| 尾帧图比例 | 必须与首帧相同(method=3) | |
| 分辨率 | 统一 720p(¥0.28/秒)省成本 | 1080p ¥0.63/秒;Pro ¥1/秒 |
| prompt 长度 | 建议 ≤400 字,最长 800 字 | |
| 输出画幅 | 跟随输入图,不跟随 sizeDate |
⚠️ KB 只说「范围 [121,241]」,实测还要求
frames % 24 === 1。 传 122 会被拒:x2v pipeline: frames % 24 should be 1。 所以不存在 3 秒或 13 秒的镜头 —— 这一点会反过来约束分镜设计。
即梦只吃公网 URL,且对二进制体积有限制(约 4–5MB base64 字符串)。
大 PNG 直传报 Image Decode Error: invalid binary data file size。
// KB 的 sharp 版
const sharp = require('sharp');
await sharp(inputPath).resize(1280, 720).jpeg({ quality: 80 }).toFile(outputPath);
// 2560×1440 PNG (~5.6MB) → 1280×720 JPEG (~200KB);base64 从 ~750万字符降到 ~28万字符
// 本技能仓的零依赖版(lib/jimeng.mjs 的 prepareImageUrl()):ffmpeg 压缩 + 七牛上传
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
// 再 POST /parse/functions/qiniu_uptoken 拿 uptoken → multipart 上传 → 返回 https 直链
法一需要
npm i sharp;本仓选法二(保持零 npm 依赖)。
| 位置 | 方式 | 理由 |
|---|---|---|
| 第 1 段 | method=3(首尾帧) |
用第 2 镜的关键帧做尾帧,做「空间推进」转场 |
| 其余段 | method=2(首帧) |
更稳、更省,失败率低 |
| 末段(可选) | method=3 |
与首帧呼应闭环(KB 版本4 的做法:仅第 1、9 段用 method=3) |
| 场景跨度大的段 | 必须 method=2 |
室内→室外、人物→空镜这类两帧会崩坏 |
method=3 只用于这三种情况:
其余一律 method=2。
KB 原话:method=3 比 method=2 更容易失败 —— 两张图数据量翻倍、首尾帧对画面一致性要求更高。
async function generateVideo(data) {
if (data.method === '3') {
const result = await submitVideo({ ...data, method: '3' });
if (result.data?.workId) return pollAndDownload(result.data.workId);
console.log('method=3 失败,降级为 method=2');
}
// 降级:只传首帧
return submitVideo({ ...data, method: '2' });
}
降级后必须做两件事:
degraded: true + 日志写明「已从 method=3 降级」)绝不静默降级。 用户必须能分清哪些镜头是首尾帧、哪些是退而求其次的首帧。
| 运镜 | 适用 |
|---|---|
| 固定机位静止 | 强调等待/结果/冲击;AI 最稳,优先使用 |
| 缓慢推近 | 靠近情绪、紧张升级 |
| 缓慢拉远 | 释放空间、收尾 |
| 横向跟随 | 跟随主体位移 |
| 缓慢上摇 / 下摇 | 揭示垂直空间 |
| 手持轻微晃动 | 真实感、临场感 |
禁止:「推 + 环绕 + 上摇」叠加;环绕镜头一律不用。
每个视频的 prompt 中必须包含背景音效描述。
示例:温暖氛围音乐|励志管弦乐|科技感电子音|雨声与远处车流|钢琴单音| 海浪与环境风声|咖啡馆背景人声|心跳声渐强|低沉的弦乐 drone
视频侧从「画面真实」转向「运动真实」,prompt 里强制加:
consistent identity & lighting{{主体动作,一句话}},
{{镜头运动:slow push in / pull back / pan left / handheld micro-shake}},
{{运动真实约束:gentle natural motion, subtle handheld micro-shake, natural breathing,
hair strands catching the light, motion blur, consistent identity and lighting}},
{{音效描述:warm ambient piano / tense low strings / rain and distant traffic}},
{{画质词:4k, cinematic, film grain, shallow depth of field}}
中文示例(改写为英文后投喂):
女子在窗边缓缓转头看向镜头,阳光掠过发丝; 镜头缓慢推近;手持轻微晃动,自然呼吸节奏,发丝随风轻摆,运动模糊自然; 温暖氛围钢琴;4k 高清,电影感,胶片颗粒
{
id: 1,
name: '第1段视频 - 开场推镜',
method: '3', // '3'=首尾帧(第一段), '2'=首帧
frames: 121, // 5 秒;必须 ∈ {121,145,169,193,217,241}
resolution: '720p', // 省钱统一 720p
firstImage: 'photo1.png',
lastImage: 'photo2.png', // 仅 method=3
prompt: '完整的情景描述 + 运镜 + 音效 + 4k 画质词'
}
提交体:
// method=2
await postJson('/getVideoV3_720p', {
prompt: PROMPT, frames: 121, method: '2',
config: { image_urls: [firstFrameUrl] },
});
// method=3 —— 必须传数组,[首帧, 尾帧]
await postJson('/getVideoV3_720p', {
prompt: PROMPT, frames: 121, method: '3',
config: { image_urls: [firstFrameUrl, lastFrameUrl] },
});
| 要求 | 做法 |
|---|---|
| 幂等 | 生成前、下载前都检查文件是否已存在,存在即跳过(fs.existsSync) |
| workId 留痕 | 记到日志,格式:[时间戳] 类型 \| workId: xxx \| 内容: xxx |
| 段间隔防限流 | 每段之间 await sleep(15000) |
| 并发退避 | 遇 50430 / Concurrent Limit:退避 10000 × (retry + 1),上限 5 次 |
| HTML 检测 | 轮询返回以 <!DOCTYPE / <html 开头 → 不解析,等 30 秒重试 |
| 结果兜底 | isFinish=true 但 videos 为空 → 改查 GET /parse/classes/ImagineWork/{workId} |
| 异常隔离 | 单个 fetch failed 只记日志并 continue,不中断整批 |
| 超时 | 统一 600 秒(10 分钟);数字人放宽到 900 秒;超时保留 workId 供手工重查 |
| 本地预检 | 提交前校验 frames 是否 ∈ {121…241} 且 ≡1 mod 24;图片比例 ≤3 |
以上九条在本技能仓中全部已实现:见
lib/jimeng.mjs(submit/poll/assertValidFrames) 与scripts/video.mjs(幂等、workId 日志、降级留痕)。
photo1 → 视频1(首帧), 视频1(尾帧)
photo3 → 视频2(首帧)
photo4 → 视频3(首帧)
...
踩坑记录:某项目 photo1(楼外场景)生成了但没有对应视频,后期才发现需要补生成。
| 分辨率 | 单价 | 5 秒单镜 | 8 镜整片(每镜 5s) |
|---|---|---|---|
| 720p | ¥0.28/秒 | ¥1.41(实测实扣) | ≈ ¥11 |
| 1080p | ¥0.63/秒 | ¥3.15 | ≈ ¥25 |
| Pro | ¥1.00/秒 | ¥5.00 | ≈ ¥40 |
试跑省钱:
fmode-mv video --from work/storyboard.json --limit 1(1 镜,¥1.41) 零费用验证:--mode still(Ken Burns 兜底,不调 API)