- 新增 scripts/jimeng_video_gen.py 脚本支持文生视频和图生视频 - 实现 t2v 和 i2v 两种生成模式,支持多种分辨率和宽高比 - 添加轮询任务状态和视频下载功能 - 更新即梦AI文档,补充视频生成API接口说明 - 新增 .claude/commands/generate-video.md 命令使用指南 - 扩展即梦API文档,包含视频生成参数配置和调用示例
355 lines
9.3 KiB
Markdown
355 lines
9.3 KiB
Markdown
# 即梦 AI API(图片生成 & 视频生成)
|
||
|
||
## 密钥
|
||
|
||
Access Key ID:AKLTOWVjYmE2NGVhZTFhNDQ2OThiYTNhZDdjZTZiYTc3ZTQ
|
||
Secret Access Key:WXpVd016azFPVEF3TURjNE5EbGxOV0psTlRNek1qaGpaalEyWkdKa1kyRQ==
|
||
|
||
## 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)
|