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

# Sora 2 角色接口

> 通过角色接口实现角色一致性 - 真实人物、虚拟角色出镜，适用于电商、动漫等场景

## 概述

Sora 2 角色接口（Character API）允许您通过视频创建可复用的角色，并在后续视频生成中保持角色的一致性。通过在提示词中引用 `@id`（唯一性的 Cameo 出镜秀 ID 或角色 Character ID），您可以让特定角色在不同视频中反复出镜。

<Info>
  由于 API 禁止直接放入人脸，角色接口提供了一个合规的解决方案：先将角色创建为虚拟角色，然后在提示词中通过 `@id` 引用该角色即可。
</Info>

## 核心要义

角色接口的核心工作原理：

1. **创建角色**：通过视频 URL 创建一个唯一的角色 ID
2. **引用角色**：在视频生成的提示词中加入 `@角色ID` 或 `@username`
3. **保持一致性**：角色在不同视频中保持外观、特征的一致性

## 为什么需要角色？

<Warning>
  重要限制：真人出镜不可行。API 不允许直接上传包含真实人脸的视频作为角色。
</Warning>

角色接口的典型应用场景：

### 电商场景

<Card title="商品角色化" icon="shopping-cart">
  将电商商品包装做成角色，固定商品包装上的品牌标识、文字信息等元素。在后续视频生成时，通过 `@角色ID` 植入该商品，确保商品在不同场景下保持一致的外观和品牌信息。
</Card>

**示例应用**：

* 产品展示视频：同一款商品在不同场景（户外、室内、工作场景）中出现
* 品牌营销视频：品牌吉祥物在多个短视频中保持一致形象
* 包装展示：商品包装上的 Logo、文字在多角度展示中保持清晰和一致

### 动漫场景

<Card title="虚拟人物" icon="wand-sparkles">
  虚拟人物、卡通角色、动漫角色都非常适合做成角色。创建后可以让角色在不同剧情、场景中反复登场，保持角色设定的一致性。
</Card>

**示例应用**：

* 系列动画短片：主角在多集中保持相同外观
* 品牌 IP 角色：虚拟代言人在不同营销视频中出镜
* 教育内容：教学类虚拟讲师在多个视频中保持形象

### 其他场景

* **游戏资产**：游戏角色的宣传视频制作
* **虚拟主播**：虚拟 UP 主的系列视频内容
* **IP 衍生**：已有 IP 角色的视频化内容创作

## 端点地址

```
https://api.apiyi.com/sora/v1/characters
```

## 请求参数

| 参数           | 类型     | 必填 | 说明                                                                                     |
| ------------ | ------ | -- | -------------------------------------------------------------------------------------- |
| `model`      | string | ✅  | 固定值：`sora-character`                                                                   |
| `url`        | string | ✅  | 视频 URL 地址，视频中应包含需要创建的角色                                                                |
| `timestamps` | string | ✅  | 角色出现的时间范围（单位：秒），格式：`"起始秒,结束秒"`<br />例如：`"1,3"` 表示视频的 1-3 秒<br />**范围差值**：最小 1 秒，最大 3 秒 |

### 参数说明

<AccordionGroup>
  <Accordion title="url - 视频 URL 要求">
    * **视频长度**：15 秒以内
    * **格式**：MP4、MOV 等常见格式
    * **内容**：不得包含真实人脸或明显的人体轮廓
    * **可访问性**：URL 必须可公开访问（支持 CDN 地址）

    **推荐实践**：

    * 使用 CDN 托管视频以提高创建成功率
    * 确保视频清晰度足够（建议 720p 或以上）
    * 角色在视频中应有明显的特征（颜色、形状、纹理等）
  </Accordion>

  <Accordion title="timestamps - 时间范围设置">
    * **格式**：字符串类型，例如 `"1,3"`
    * **含义**：指定视频中角色出现的时间段（从视频的第几秒到第几秒）
    * **单位**：秒（整数或小数均可）
    * **视频总长度**：视频可以是 15 秒以内的任意长度
    * **时间段限制**：
      * 时间段长度（结束秒数 - 起始秒数）：最小 1 秒，最大 3 秒
      * 起始时间不能小于 0
      * 结束时间不能超过视频总长度

    **举例说明**：

    * 视频总长 15 秒，`timestamps: "1,3"` 表示使用视频第 1-3 秒的内容作为角色（时间段长度 2 秒）
    * 视频总长 15 秒，`timestamps: "8,11"` 表示使用视频第 8-11 秒的内容作为角色（时间段长度 3 秒）
    * 视频总长 10 秒，`timestamps: "5,6"` 表示使用视频第 5-6 秒的内容作为角色（时间段长度 1 秒）

    **选择建议**：

    * 在视频中找到角色特征最明显的时间段
    * 避免选择角色被遮挡或运动模糊的时间段
    * 时间段长度可以根据实际情况选择 1-3 秒，通常 2 秒左右效果较好
  </Accordion>

  <Accordion title="未来支持：通过异步任务 ID 创建">
    **当前状态**：未上线

    未来将支持直接使用 Sora 2 异步视频生成任务的 `video_id` 创建角色，无需先下载视频再上传到 CDN。这将大大简化工作流程。

    预计参数格式：

    ```json theme={null}
    {
      "model": "sora-character",
      "video_id": "video_abc123def456",
      "timestamps": "1,3"
    }
    ```
  </Accordion>
</AccordionGroup>

## 代码示例

### cURL 示例

```bash cURL theme={null}
curl -X POST "https://api.apiyi.com/sora/v1/characters" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "sora-character",
    "url": "https://mycdn-gg.oss-us-west-1.aliyuncs.com/sora/64ba6b88-8540-4b73-bf05-7bd2e96bebd1.mp4",
    "timestamps": "1,3"
  }'
```

### Python 示例

<CodeGroup>
  ```python Python 基础示例 theme={null}
  import requests
  import json

  # API 配置
  API_URL = "https://api.apiyi.com/sora/v1/characters"
  API_KEY = "YOUR_API_KEY"

  # 请求参数
  payload = {
      "model": "sora-character",
      "url": "https://mycdn-gg.oss-us-west-1.aliyuncs.com/sora/64ba6b88-8540-4b73-bf05-7bd2e96bebd1.mp4",
      "timestamps": "1,3"
  }

  # 发送请求
  headers = {
      "Content-Type": "application/json",
      "Authorization": f"Bearer {API_KEY}"
  }

  response = requests.post(API_URL, headers=headers, json=payload)
  result = response.json()

  # 输出结果
  print(f"角色ID: {result['id']}")
  print(f"用户名: {result['username']}")
  print(f"展示名称: {result['display_name']}")
  print(f"主页链接: {result['permalink']}")
  print(f"封面图片: {result['profile_picture_url']}")
  ```

  ```python Python 完整示例（带重试） theme={null}
  import requests
  import json
  import time

  # API 配置
  API_URL = "https://api.apiyi.com/sora/v1/characters"
  API_KEY = "YOUR_API_KEY"

  def create_character(video_url, start_time, end_time, max_retries=3):
      """
      创建角色，支持自动重试

      Args:
          video_url: 视频 URL
          start_time: 起始时间（秒）
          end_time: 结束时间（秒）
          max_retries: 最大重试次数

      Returns:
          dict: 角色信息或 None（失败时）
      """

      # 参数验证
      time_diff = end_time - start_time
      if time_diff < 1 or time_diff > 3:
          print(f"❌ 时间范围错误：{time_diff}秒（允许范围：1-3秒）")
          return None

      payload = {
          "model": "sora-character",
          "url": video_url,
          "timestamps": f"{start_time},{end_time}"
      }

      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {API_KEY}"
      }

      # 重试逻辑
      for attempt in range(1, max_retries + 1):
          try:
              print(f"\n🔄 尝试创建角色... (第 {attempt}/{max_retries} 次)")
              print(f"   视频: {video_url}")
              print(f"   时间范围: {start_time}-{end_time} 秒")

              response = requests.post(API_URL, headers=headers, json=payload, timeout=30)

              if response.status_code == 200:
                  result = response.json()
                  print(f"\n✅ 角色创建成功!")
                  print(f"   角色ID: {result['id']}")
                  print(f"   用户名: @{result['username']}")
                  print(f"   展示名称: {result['display_name']}")
                  print(f"   主页: {result['permalink']}")
                  print(f"   封面: {result['profile_picture_url']}")
                  return result
              else:
                  error_msg = response.text
                  print(f"❌ 创建失败 (HTTP {response.status_code}): {error_msg}")

                  # 如果是客户端错误（4xx），不重试
                  if 400 <= response.status_code < 500:
                      print("⚠️  客户端错误，不进行重试")
                      return None

          except requests.exceptions.Timeout:
              print(f"⏱️  请求超时")
          except requests.exceptions.RequestException as e:
              print(f"❌ 网络错误: {str(e)}")
          except Exception as e:
              print(f"❌ 未知错误: {str(e)}")

          # 如果不是最后一次尝试，等待后重试
          if attempt < max_retries:
              wait_time = 2 ** attempt  # 指数退避：2s, 4s, 8s
              print(f"⏳ 等待 {wait_time} 秒后重试...")
              time.sleep(wait_time)

      print(f"\n❌ 创建角色失败：已达到最大重试次数 ({max_retries})")
      return None


  # 使用示例
  if __name__ == "__main__":
      # 示例：创建一个虚拟角色
      character = create_character(
          video_url="https://mycdn-gg.oss-us-west-1.aliyuncs.com/sora/64ba6b88-8540-4b73-bf05-7bd2e96bebd1.mp4",
          start_time=1,
          end_time=3,
          max_retries=3
      )

      if character:
          print("\n" + "=" * 60)
          print("🎉 角色已创建，可在视频生成时使用：")
          print("=" * 60)
          print(f"提示词示例：")
          print(f"  \"@{character['username']} 在森林中奔跑，阳光透过树叶洒在身上\"")
          print(f"  \"让 @{character['username']} 和一只小鸟一起玩耍\"")
  ```

  ```python Python 批量创建角色 theme={null}
  import requests
  import json
  import time
  from concurrent.futures import ThreadPoolExecutor, as_completed

  API_URL = "https://api.apiyi.com/sora/v1/characters"
  API_KEY = "YOUR_API_KEY"

  def create_single_character(video_info):
      """创建单个角色（用于并发）"""
      payload = {
          "model": "sora-character",
          "url": video_info["url"],
          "timestamps": video_info["timestamps"]
      }

      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {API_KEY}"
      }

      try:
          response = requests.post(API_URL, headers=headers, json=payload, timeout=30)
          if response.status_code == 200:
              return {
                  "success": True,
                  "name": video_info["name"],
                  "data": response.json()
              }
          else:
              return {
                  "success": False,
                  "name": video_info["name"],
                  "error": f"HTTP {response.status_code}: {response.text}"
              }
      except Exception as e:
          return {
              "success": False,
              "name": video_info["name"],
              "error": str(e)
          }

  def batch_create_characters(video_list, max_workers=3):
      """
      批量创建角色

      Args:
          video_list: 视频信息列表，每项包含 name, url, timestamps
          max_workers: 最大并发数
      """
      print(f"开始批量创建 {len(video_list)} 个角色...\n")

      results = {
          "success": [],
          "failed": []
      }

      with ThreadPoolExecutor(max_workers=max_workers) as executor:
          # 提交所有任务
          future_to_video = {
              executor.submit(create_single_character, video): video
              for video in video_list
          }

          # 处理完成的任务
          for future in as_completed(future_to_video):
              video = future_to_video[future]
              try:
                  result = future.result()

                  if result["success"]:
                      print(f"✅ {result['name']}: 创建成功")
                      print(f"   @{result['data']['username']}")
                      results["success"].append(result)
                  else:
                      print(f"❌ {result['name']}: 创建失败")
                      print(f"   {result['error']}")
                      results["failed"].append(result)

              except Exception as e:
                  print(f"❌ {video['name']}: 异常 - {str(e)}")
                  results["failed"].append({
                      "success": False,
                      "name": video["name"],
                      "error": str(e)
                  })

      # 汇总结果
      print("\n" + "=" * 60)
      print(f"批量创建完成:")
      print(f"  成功: {len(results['success'])} 个")
      print(f"  失败: {len(results['failed'])} 个")
      print("=" * 60)

      return results

  # 使用示例
  if __name__ == "__main__":
      videos = [
          {
              "name": "商品包装角色",
              "url": "https://example.com/product-video.mp4",
              "timestamps": "1,3"
          },
          {
              "name": "品牌吉祥物",
              "url": "https://example.com/mascot-video.mp4",
              "timestamps": "0,2"
          },
          {
              "name": "虚拟主播角色",
              "url": "https://example.com/vtuber-video.mp4",
              "timestamps": "2,4"
          }
      ]

      results = batch_create_characters(videos, max_workers=3)

      # 打印成功创建的角色信息
      if results["success"]:
          print("\n成功创建的角色列表：")
          for item in results["success"]:
              char = item["data"]
              print(f"  - {item['name']}: @{char['username']}")
  ```
</CodeGroup>

## 响应格式

### 成功响应

```json theme={null}
{
  "id": "char_abc123def456",
  "username": "my_character_2024",
  "display_name": "我的虚拟角色",
  "permalink": "https://api.apiyi.com/characters/my_character_2024",
  "profile_picture_url": "https://cdn.apiyi.com/characters/char_abc123def456/profile.jpg"
}
```

### 响应字段说明

| 字段                    | 类型     | 说明                                                               |
| --------------------- | ------ | ---------------------------------------------------------------- |
| `id`                  | string | 角色的唯一标识符（Character ID）<br />在视频生成提示词中可使用 `@char_abc123def456` 引用 |
| `username`            | string | 角色的用户名（唯一性）<br />在视频生成提示词中可使用 `@my_character_2024` 引用            |
| `display_name`        | string | 角色的展示名称（可重复）<br />仅用于展示，不能用于引用                                   |
| `permalink`           | string | 角色主页的永久链接地址                                                      |
| `profile_picture_url` | string | 角色主页的封面图片 URL                                                    |

<Tip>
  **推荐使用方式**：在视频生成时，使用 `@username` 更简洁易读，例如：`"@my_character_2024 在公园里散步"`
</Tip>

## 定价

| 项目   | 价格         | 说明      |
| ---- | ---------- | ------- |
| 角色创建 | \$0.01 / 次 | 限免期特惠价格 |

<Info>
  当前处于限免期，定价极低。正式定价可能会调整，请关注官方公告。
</Info>

## 在视频生成中使用角色

创建角色后，可以在 Sora 2 视频生成接口中使用：

### 使用方式

在 `prompt` 参数中引用角色：

```python theme={null}
# 方式一：使用 @username
prompt = "@my_character_2024 在森林中奔跑，阳光透过树叶洒在身上"

# 方式二：使用 @id
prompt = "@char_abc123def456 和一只小鸟一起玩耍，温馨有趣"
```

### 完整示例

```python theme={null}
import requests

# 配置
SORA_API_URL = "https://api.apiyi.com/v1/videos"
API_KEY = "YOUR_API_KEY"

# 引用角色生成视频
payload = {
    "model": "sora-2",
    "prompt": "@my_character_2024 在城市街道上滑滑板，背景是繁华的商业区，阳光明媚",
    "size": "1280x720",
    "seconds": "10"
}

headers = {
    "Content-Type": "multipart/form-data",
    "Authorization": f"Bearer {API_KEY}"
}

response = requests.post(SORA_API_URL, headers=headers, files=payload)
result = response.json()

print(f"视频任务ID: {result['id']}")
```

详见：[Sora 2 视频生成文档](/api-capabilities/sora-2-video)

## 注意事项与限制

<Warning>
  **重要限制 - 人脸检测**：视频中不得包含真实人脸或明显的人体轮廓，否则角色创建会失败。请使用虚拟角色、卡通形象、商品、物体等非人脸内容。
</Warning>

### 成功率说明

<CardGroup cols={2}>
  <Card title="影响成功率的因素" icon="triangle-alert">
    * 视频中包含真实人脸或人体
    * 视频质量过低（模糊、抖动）
    * 角色特征不明显
    * iOS 逆向技术的不稳定性
  </Card>

  <Card title="提高成功率的建议" icon="check">
    * 使用清晰的虚拟角色视频
    * 选择角色特征明显的片段
    * 确保视频稳定无抖动
    * 必要时多次重试
  </Card>
</CardGroup>

### 视频要求

| 要求项   | 说明                  |
| ----- | ------------------- |
| 最大长度  | 15 秒以内              |
| 推荐分辨率 | 720p 或以上            |
| 格式    | MP4、MOV 等常见格式       |
| 内容限制  | 不得包含真实人脸、暴力、色情等违规内容 |
| 角色清晰度 | 角色应占据画面合理比例，特征明显    |

### 技术限制说明

<Info>
  由于角色创建基于 iOS 逆向工程技术，可能存在一定的技术不稳定性。如果创建失败，建议：

  1. 检查视频内容是否符合要求
  2. 调整 `timestamps` 时间范围，选择更清晰的片段
  3. 使用重试机制（建议 2-3 次）
  4. 如果持续失败，请联系技术支持
</Info>

## 最佳实践

### 选择合适的视频片段

```python theme={null}
# 推荐：角色特征明显、画面稳定
timestamps = "2,4"  # 选择角色正面、清晰的 2 秒片段

# 避免：角色被遮挡、运动模糊
timestamps = "0,1"  # 开头可能有转场效果，不稳定
```

### 重试策略

```python theme={null}
def create_character_with_retry(video_url, timestamps, max_retries=3):
    """带指数退避的重试策略"""
    for i in range(max_retries):
        try:
            result = create_character(video_url, timestamps)
            return result
        except Exception as e:
            if i == max_retries - 1:
                raise
            wait_time = 2 ** i  # 2s, 4s, 8s
            print(f"重试 {i+1}/{max_retries}，等待 {wait_time} 秒...")
            time.sleep(wait_time)
```

### 角色管理

建议维护一个角色数据库：

```python theme={null}
characters_db = {
    "product_A": {
        "id": "char_abc123",
        "username": "product_a_2024",
        "description": "A产品包装角色",
        "created_at": "2024-01-15"
    },
    "mascot_B": {
        "id": "char_def456",
        "username": "mascot_b_2024",
        "description": "品牌吉祥物",
        "created_at": "2024-01-16"
    }
}
```

## 常见问题

<AccordionGroup>
  <Accordion title="为什么创建角色时提示包含人脸？">
    API 对真实人脸有严格限制。即使是 AI 生成的拟真人脸也可能被检测到。建议使用：

    * 卡通/动漫风格的虚拟角色
    * 商品、物体等非人物内容
    * 抽象艺术风格的角色

    如果必须使用类人角色，建议使用风格化程度较高的设计。
  </Accordion>

  <Accordion title="创建的角色会过期吗？">
    角色一旦创建成功，将长期有效，可以反复在视频生成中使用。但建议保存好角色的 `id` 和 `username` 信息。
  </Accordion>

  <Accordion title="可以修改已创建的角色吗？">
    当前不支持修改已创建的角色。如果需要调整角色，建议：

    1. 创建新的角色
    2. 在新视频生成中使用新角色
    3. 旧角色仍然可用，不会被删除
  </Accordion>

  <Accordion title="如何提高角色在视频中的一致性？">
    * **明确引用**：在提示词开头使用 `@username`
    * **详细描述**：描述角色的动作和场景，但不要重复描述角色外观
    * **示例**：
      ```
      ✅ 好的提示词：
      "@my_character 在公园里奔跑，追逐一只蝴蝶，阳光明媚"

      ❌ 不好的提示词：
      "一个红色的角色在公园里"  # 没有引用角色 ID
      "@my_character 红色的身体在公园"  # 重复描述外观可能导致冲突
      ```
  </Accordion>

  <Accordion title="timestamps 如何选择最佳时间段？">
    选择建议：

    * **观看视频**：先完整观看视频，找到角色最清晰的片段
    * **正面角度**：优先选择角色正面或 3/4 侧面的片段
    * **光线充足**：避免过暗或过曝的片段
    * **无遮挡**：确保角色主体完整，无被遮挡
    * **稳定画面**：避免快速运动或镜头晃动的片段

    **测试方法**：可以尝试不同的时间段，对比创建结果。
  </Accordion>

  <Accordion title="批量创建角色时有什么限制吗？">
    * **速率限制**：请遵守 API 的请求速率限制（具体限制请参考 API 手册）
    * **并发控制**：建议控制在 3-5 个并发，避免触发限流
    * **成本考虑**：虽然当前定价很低（\$0.01/次），但批量创建仍需考虑总成本

    建议使用示例代码中的批量创建函数，它包含了适当的并发控制。
  </Accordion>

  <Accordion title="角色可以在不同的 Sora 模型中使用吗？">
    角色创建后，主要用于 Sora 2 视频生成。未来可能支持在其他 Sora 系列模型中使用，请关注官方更新。
  </Accordion>
</AccordionGroup>

## 相关资源

<CardGroup cols={2}>
  <Card title="Sora 2 视频生成" icon="video" href="/api-capabilities/sora-2-video">
    了解如何在视频生成中使用角色
  </Card>

  <Card title="Sora 2 异步 API" icon="clock" href="/api-capabilities/sora-2-video-async">
    批量生成带角色的视频内容
  </Card>

  <Card title="API 基础手册" icon="code" href="/api-manual">
    了解 API 认证、请求格式等基础知识
  </Card>

  <Card title="常见问题 FAQ" icon="circle-question" href="/faq/model-selection-guide">
    查看更多常见问题解答
  </Card>
</CardGroup>
