self-media-james/doc/passport/即梦.md
邓文兵 9408daeeff feat(jimeng): 添加即梦AI视频生成功能
- 新增 scripts/jimeng_video_gen.py 脚本支持文生视频和图生视频
- 实现 t2v 和 i2v 两种生成模式,支持多种分辨率和宽高比
- 添加轮询任务状态和视频下载功能
- 更新即梦AI文档,补充视频生成API接口说明
- 新增 .claude/commands/generate-video.md 命令使用指南
- 扩展即梦API文档,包含视频生成参数配置和调用示例
2026-03-12 19:52:07 +08:00

355 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 即梦 AI API图片生成 & 视频生成)
## 密钥
Access Key IDAKLTOWVjYmE2NGVhZTFhNDQ2OThiYTNhZDdjZTZiYTc3ZTQ
Secret Access KeyWXpVd016azFPVEF3TURjNE5EbGxOV0psTlRNek1qaGpaalEyWkdKa1kyRQ==
## API 基本信息
| 项目 | 值 |
|------|------|
| Endpoint | `https://visual.volcengineapi.com` |
| Region | `cn-north-1` |
| Service | `cv` |
| 签名算法 | HMAC-SHA256 (V4) |
| Content-Type | `application/json` |
## 接口列表
### 1. 文生图 - 提交任务(异步)
```
POST https://visual.volcengineapi.com?Action=CVSync2AsyncSubmitTask&Version=2022-08-31
```
请求体:
```json
{
"req_key": "jimeng_t2i_v40",
"prompt": "一只卡通龙虾站在电路板上,科技感,扁平插画风格",
"width": 1024,
"height": 1024
}
```
返回:
```json
{
"code": 10000,
"data": {
"task_id": "7392616336519610409"
},
"message": "Success",
"request_id": "20240720103939AF0029465CF6A74E51EC",
"time_elapsed": "104.852309ms"
}
```
### 2. 查询任务结果
```
POST https://visual.volcengineapi.com?Action=CVSync2AsyncGetResult&Version=2022-08-31
```
请求体:
```json
{
"req_key": "jimeng_t2i_v40",
"task_id": "7392616336519610409"
}
```
### 3. 同步调用(小任务)
```
POST https://visual.volcengineapi.com?Action=CVProcess&Version=2022-08-31
```
## Python 调用方法
### 方式一SDK 调用(推荐)
```bash
pip install volcengine-python-sdk
```
```python
from volcengine.visual.VisualService import VisualService
visual_service = VisualService()
visual_service.set_ak('AKLTOWVjYmE2NGVhZTFhNDQ2OThiYTNhZDdjZTZiYTc3ZTQ')
visual_service.set_sk('WXpVd016azFPVEF3TURjNE5EbGxOV0psTlRNek1qaGpaalEyWkdKa1kyRQ==')
# 提交文生图任务
resp = visual_service.cv_sync2async_submit_task({
"req_key": "jimeng_t2i_v40",
"prompt": "一只卡通龙虾站在电路板上,科技感,扁平插画风格",
"width": 1024,
"height": 1024
})
print(resp)
task_id = resp["data"]["task_id"]
# 查询结果
import time
time.sleep(10) # 等待生成
result = visual_service.cv_sync2async_get_result({
"req_key": "jimeng_t2i_v40",
"task_id": task_id
})
print(result)
```
### 方式二HTTP 签名调用
```python
import json
import sys
import datetime
import hashlib
import hmac
import requests
# ===== 配置 =====
ACCESS_KEY = 'AKLTOWVjYmE2NGVhZTFhNDQ2OThiYTNhZDdjZTZiYTc3ZTQ'
SECRET_KEY = 'WXpVd016azFPVEF3TURjNE5EbGxOV0psTlRNek1qaGpaalEyWkdKa1kyRQ=='
HOST = 'visual.volcengineapi.com'
ENDPOINT = 'https://visual.volcengineapi.com'
REGION = 'cn-north-1'
SERVICE = 'cv'
def sign(key, msg):
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
def get_signature_key(key, date_stamp, region_name, service_name):
k_date = sign(key.encode('utf-8'), date_stamp)
k_region = sign(k_date, region_name)
k_service = sign(k_region, service_name)
k_signing = sign(k_service, 'request')
return k_signing
def format_query(parameters):
return '&'.join(f'{k}={parameters[k]}' for k in sorted(parameters))
def jimeng_request(action, body_params):
"""发送即梦API请求"""
t = datetime.datetime.utcnow()
current_date = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d')
query_params = format_query({'Action': action, 'Version': '2022-08-31'})
req_body = json.dumps(body_params)
payload_hash = hashlib.sha256(req_body.encode('utf-8')).hexdigest()
signed_headers = 'content-type;host;x-content-sha256;x-date'
canonical_headers = (
f'content-type:application/json\n'
f'host:{HOST}\n'
f'x-content-sha256:{payload_hash}\n'
f'x-date:{current_date}\n'
)
canonical_request = f'POST\n/\n{query_params}\n{canonical_headers}\n{signed_headers}\n{payload_hash}'
credential_scope = f'{datestamp}/{REGION}/{SERVICE}/request'
string_to_sign = (
f'HMAC-SHA256\n{current_date}\n{credential_scope}\n'
+ hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
)
signing_key = get_signature_key(SECRET_KEY, datestamp, REGION, SERVICE)
signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()
authorization = (
f'HMAC-SHA256 Credential={ACCESS_KEY}/{credential_scope}, '
f'SignedHeaders={signed_headers}, Signature={signature}'
)
headers = {
'X-Date': current_date,
'Authorization': authorization,
'X-Content-Sha256': payload_hash,
'Content-Type': 'application/json'
}
r = requests.post(f'{ENDPOINT}?{query_params}', headers=headers, data=req_body)
return r.json()
def generate_image(prompt, width=1024, height=1024):
"""文生图:提交任务并轮询获取结果"""
# 1. 提交任务
submit_resp = jimeng_request('CVSync2AsyncSubmitTask', {
'req_key': 'jimeng_t2i_v40',
'prompt': prompt,
'width': width,
'height': height
})
if submit_resp.get('code') != 10000:
print(f"提交失败: {submit_resp}")
return None
task_id = submit_resp['data']['task_id']
print(f"任务已提交, task_id: {task_id}")
# 2. 轮询查询结果
import time
for i in range(30):
time.sleep(5)
result = jimeng_request('CVSync2AsyncGetResult', {
'req_key': 'jimeng_t2i_v40',
'task_id': task_id
})
if result.get('code') == 10000 and result.get('data', {}).get('status') == 'done':
print("生成完成!")
return result
print(f"等待中... ({i+1}/30)")
print("超时")
return None
if __name__ == '__main__':
result = generate_image("一只卡通龙虾站在电路板上,科技感,扁平插画风格")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
---
## 视频生成接口
### 模型与 req_key 对照表
| 功能 | req_key | 分辨率 | 说明 |
|------|---------|--------|------|
| 文生视频 | `jimeng_t2v_v30` | 720P | 文本提示词生成视频 |
| 文生视频 | `jimeng_t2v_v30_1080p` | 1080P | 文本提示词生成高清视频 |
| 图生视频-首帧 | `jimeng_i2v_first_v30` | 720P | 首帧图片+提示词生成视频 |
### 通用参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `req_key` | string | 是 | 模型标识,见上表 |
| `prompt` | string | 是 | 视频描述提示词 |
| `frames` | int | 否 | 视频帧数,默认 121约5秒 |
| `aspect_ratio` | string | 否 | 宽高比:`16:9`、`4:3`、`1:1`、`3:4`、`9:16`、`21:9` |
| `seed` | int | 否 | 随机种子,-1 为随机 |
### 图生视频额外参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `image_urls` | string[] | 首帧图片 URL 列表 |
| `binary_data_base64` | string[] | 首帧图片 Base64 编码(与 image_urls 二选一) |
### 文生视频 - 提交任务
```
POST https://visual.volcengineapi.com?Action=CVSync2AsyncSubmitTask&Version=2022-08-31
```
请求体:
```json
{
"req_key": "jimeng_t2v_v30",
"prompt": "一只橘猫趴在键盘上打字,桌面上有一杯咖啡,温暖的灯光",
"frames": 121,
"aspect_ratio": "16:9",
"seed": -1
}
```
返回:
```json
{
"code": 10000,
"data": {
"task_id": "9675314167630911764"
},
"message": "Success"
}
```
### 查询视频结果
```
POST https://visual.volcengineapi.com?Action=CVSync2AsyncGetResult&Version=2022-08-31
```
请求体:
```json
{
"req_key": "jimeng_t2v_v30",
"task_id": "9675314167630911764"
}
```
返回(完成时):
```json
{
"code": 10000,
"data": {
"status": "done",
"video_url": "https://v11-aiop.aigc-cloud.com/...",
"aigc_meta_tagged": false
},
"message": "Success"
}
```
### 图生视频-首帧 - 提交任务
```json
{
"req_key": "jimeng_i2v_first_v30",
"prompt": "猫咪缓缓转头看向镜头",
"image_urls": ["https://example.com/cat.jpg"],
"frames": 121,
"seed": -1
}
```
### Prompt 技巧
- **基础结构**:主体 + 背景 + 镜头 + 动作
- **运镜词汇**:镜头切换、平移、推轨、环形跟踪、特写、俯拍、航拍
- **多镜头叙事**支持描述连贯场景切换3.0 Pro 特性)
### Python 调用
```bash
source .venv/bin/activate
# 文生视频 (720P)
python scripts/jimeng_video_gen.py "一只橘猫趴在键盘上打字" output.mp4
# 文生视频 (1080P)
python scripts/jimeng_video_gen.py "一只橘猫趴在键盘上打字" output.mp4 --resolution 1080p
# 图生视频-首帧
python scripts/jimeng_video_gen.py "猫咪转头看镜头" output.mp4 --mode i2v --image first_frame.jpg
# 指定宽高比和帧数
python scripts/jimeng_video_gen.py "描述" output.mp4 --aspect-ratio 9:16 --frames 121
```
## 参考文档
### 图片生成
- [即梦AI图片生成4.0 产品介绍](https://www.volcengine.com/docs/85621/1820192)
- [即梦AI图片生成4.0 接口文档](https://www.volcengine.com/docs/85621/1817045)
### 视频生成
- [即梦AI视频生成3.0 Pro 产品介绍](https://www.volcengine.com/docs/85621/1783678)
- [即梦AI视频生成3.0 Pro 接口文档](https://www.volcengine.com/docs/85621/1777001)
- [即梦AI视频生成3.0 720P 接口文档](https://www.volcengine.com/docs/85621/1792710)
- [即梦AI视频生成3.0 1080P 接口文档](https://www.volcengine.com/docs/85621/1792711)
### 通用
- [Python SDK (GitHub)](https://github.com/volcengine/volc-sdk-python)
- [SDK 使用说明](https://www.volcengine.com/docs/6444/1340578)
- [HTTP 请求示例](https://www.volcengine.com/docs/6444/1390583)