> ## Documentation Index
> Fetch the complete documentation index at: https://docs-vip.apigo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Seedance 视频生成示例

> 导入参考素材，使用 Seedance 2.0 生成视频并获取结果。

## 调用流程

1. [CreateAssetGroup](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/create-asset-group.md) 创建素材组，取得 `Result.Id`。
2. [CreateAsset](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/create-asset.md) 通过 URL 导入素材，取得 `Result.Id`。
3. [GetAsset](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/get-asset.md) 轮询到 `Status=Active`。
4. [创建视频生成任务](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/create-task.md)，以 `asset://<素材ID>` 引用素材，取得 `id`。
5. [查询视频生成任务](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/get-task.md) 轮询到 `status=succeeded`，下载 `content.video_url`。

第 1–3 步使用 HMAC-SHA256 签名，第 4–5 步使用 Bearer，两者使用同一个 API Key。

## 完整示例

Python 3.9+，仅使用标准库。

```python seedance_demo.py theme={null}
import hashlib
import hmac
import json
import os
import time
from datetime import datetime, timezone
from urllib.error import HTTPError
from urllib.request import Request, urlopen

API_KEY = os.environ["APIGO_API_KEY"]
HOST = "api-vip.apigo.ai"
MODEL = "dreamina-seedance-2-0-260128"
IMAGE_URL = "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg"


def send(request):
    try:
        with urlopen(request, timeout=60) as resp:
            return json.loads(resp.read())
    except HTTPError as e:
        raise SystemExit(f"HTTP {e.code}: {e.read().decode('utf-8', 'replace')}")


def asset_api(action, body):
    """素材库管理接口：HMAC-SHA256 签名。"""
    payload = json.dumps(body, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
    x_date = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    day = x_date[:8]
    query = f"Action={action}&Version=2024-01-01"
    body_hash = hashlib.sha256(payload).hexdigest()
    signed_headers = "content-type;host;x-content-sha256;x-date"
    canonical_request = "\n".join([
        "POST", "/", query,
        f"content-type:application/json\nhost:{HOST}\n"
        f"x-content-sha256:{body_hash}\nx-date:{x_date}\n",
        signed_headers, body_hash,
    ])
    scope = f"{day}/ap-southeast-1/ark/request"
    string_to_sign = "\n".join([
        "HMAC-SHA256", x_date, scope,
        hashlib.sha256(canonical_request.encode("utf-8")).hexdigest(),
    ])
    signing_key = API_KEY.encode("utf-8")
    for part in (day, "ap-southeast-1", "ark", "request"):
        signing_key = hmac.new(signing_key, part.encode("utf-8"), hashlib.sha256).digest()
    signature = hmac.new(signing_key, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()

    return send(Request(f"https://{HOST}/?{query}", data=payload, method="POST", headers={
        "Content-Type": "application/json",
        "X-Date": x_date,
        "X-Content-Sha256": body_hash,
        "Authorization": f"HMAC-SHA256 Credential={API_KEY}/{scope}, "
                         f"SignedHeaders={signed_headers}, Signature={signature}",
    }))["Result"]


def task_api(method, path, body=None):
    """视频生成接口：Bearer 鉴权。"""
    data = json.dumps(body).encode("utf-8") if body is not None else None
    return send(Request(f"https://{HOST}{path}", data=data, method=method, headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }))


# 1. 创建素材组
group_id = asset_api("CreateAssetGroup", {"Name": "demo-assets", "GroupType": "AIGC"})["Id"]
print("group:", group_id)

# 2. 导入图片素材
asset_id = asset_api("CreateAsset", {
    "GroupId": group_id,
    "URL": IMAGE_URL,
    "AssetType": "Image",
    "Name": "tea-reference",
})["Id"]
print("asset:", asset_id)

# 3. 等待素材就绪
while True:
    asset = asset_api("GetAsset", {"Id": asset_id})
    print("asset status:", asset["Status"])
    if asset["Status"] == "Active":
        break
    if asset["Status"] == "Failed":
        raise SystemExit(f"素材处理失败: {asset.get('Error')}")
    time.sleep(5)

# 4. 创建视频生成任务
task_id = task_api("POST", "/api/v3/contents/generations/tasks", {
    "model": MODEL,
    "content": [
        {"type": "text", "text": "让图片1中的茶杯缓缓升起热气，镜头轻微推近。"},
        {"type": "image_url", "role": "reference_image", "image_url": {"url": f"asset://{asset_id}"}},
    ],
    "duration": 5,
    "resolution": "720p",
    "ratio": "16:9",
    "generate_audio": False,
    "watermark": False,
})["id"]
print("task:", task_id)

# 5. 轮询任务结果
while True:
    task = task_api("GET", f"/api/v3/contents/generations/tasks/{task_id}")
    print("task status:", task["status"])
    if task["status"] not in ("queued", "running"):
        break
    time.sleep(10)

if task["status"] != "succeeded":
    raise SystemExit(f"任务结束: {task['status']} {task.get('error')}")

with urlopen(task["content"]["video_url"], timeout=300) as resp, open("output.mp4", "wb") as f:
    f.write(resp.read())
print("saved: output.mp4")
```

运行：

```bash theme={null}
export APIGO_API_KEY="你的 API Key"
python3 seedance_demo.py
```

## cURL 示例

素材库管理接口需要签名，无法直接用 cURL 手写，签名方法见[鉴权与通用约定](https://docs-vip.apigo.ai/api-reference/endpoints/seedance/asset-overview.md#鉴权)。视频生成接口使用 Bearer，可直接调用：

```bash theme={null}
curl https://api-vip.apigo.ai/api/v3/contents/generations/tasks \
  -H "Authorization: Bearer $APIGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dreamina-seedance-2-0-260128",
    "content": [
      {"type": "text", "text": "让图片1中的茶杯缓缓升起热气，镜头轻微推近。"},
      {"type": "image_url", "role": "reference_image", "image_url": {"url": "asset://<素材ID>"}}
    ],
    "duration": 5,
    "resolution": "720p",
    "ratio": "16:9",
    "generate_audio": false,
    "watermark": false
  }'
```

```bash theme={null}
curl https://api-vip.apigo.ai/api/v3/contents/generations/tasks/<任务ID> \
  -H "Authorization: Bearer $APIGO_API_KEY"
```

## 其他参考媒体组合

> [tab] 图片 + 音频
>
> 音频需搭配图片或视频使用。使用参考音频时 `generate_audio` 传 `true`。
>
> ```json theme={null}
> {
>   "model": "dreamina-seedance-2-0-260128",
>   "content": [
>     {"type": "text", "text": "以图片1为画面参考，使用音频1作为配乐，不要增加对白。"},
>     {"type": "image_url", "role": "reference_image", "image_url": {"url": "asset://<图片素材ID>"}},
>     {"type": "audio_url", "role": "reference_audio", "audio_url": {"url": "asset://<音频素材ID>"}}
>   ],
>   "duration": 5,
>   "ratio": "16:9",
>   "generate_audio": true,
>   "watermark": false
> }
> ```

> [tab] 视频（含原声）
>
> 参考视频需包含可听的声音，`generate_audio` 传 `true`。
>
> ```json theme={null}
> {
>   "model": "dreamina-seedance-2-0-260128",
>   "content": [
>     {"type": "text", "text": "以视频1为画面和声音参考，保留主体、场景及原声特征。"},
>     {"type": "video_url", "role": "reference_video", "video_url": {"url": "asset://<视频素材ID>"}}
>   ],
>   "duration": 5,
>   "ratio": "16:9",
>   "generate_audio": true,
>   "watermark": false
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.