# SEE2AI 视频抽帧

> SEE2AI video frame extraction. Submit a video URL, then poll for stable hosted frame image URLs. Defaults to extracting the first frame.

## 📖 接入指引

**Endpoint**: `POST /api/v1/actions/see2ai_video_frame_extract_v1`

**认证方式**: Bearer Token (租户 API Key)

### Endpoints

| Method | Path | Purpose |
| --- | --- | --- |
| `POST` | `/api/v1/actions/see2ai_video_frame_extract_v1` | Submit the standard action request. |

> **⚠️ 重要提示**
> 
> 本 API 是 SEE2AI 平台标准化封装后的接口，**参数格式与任何上游 API 不同**。
> 请直接使用下方 Schema 中定义的参数，无需参考其他文档。
> 
> *例如：*
> *- 文本模型参数可能是 `query` 而不是 `messages` 数组*
> *- 视频模型参数可能是 `brief` (创意简报) 而不是复杂的配置项*

## 📥 输入参数 (Input Schema)

```json
{
  "properties": {
    "video_url": {
      "description": "Public HTTP(S) input video URL.",
      "title": "Video Url",
      "type": "string"
    },
    "snapshot_type": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Extraction strategy: TimeInterval, SpecifiedTime, SpecifiedFrames, or SceneChange. Defaults to SpecifiedFrames.",
      "title": "Snapshot Type"
    },
    "time_interval": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Seconds between frames when snapshot_type is TimeInterval.",
      "title": "Time Interval"
    },
    "specified_time": {
      "anyOf": [
        {
          "items": {},
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Second offsets when snapshot_type is SpecifiedTime.",
      "title": "Specified Time"
    },
    "specified_frames": {
      "anyOf": [
        {
          "items": {},
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Frame selectors when snapshot_type is SpecifiedFrames. Use 0 for first frame and -1 for last frame. Defaults to [0].",
      "title": "Specified Frames"
    },
    "scene_change_threshold": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Sensitivity when snapshot_type is SceneChange. Lower values are more sensitive; default is 0.1.",
      "title": "Scene Change Threshold"
    },
    "snapshot_limit": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Maximum frame count for TimeInterval and SceneChange, 1..1000. Defaults to 100 for unbounded strategies.",
      "title": "Snapshot Limit"
    },
    "enable_sprite": {
      "default": false,
      "description": "Whether to combine extracted frames into sprite image output.",
      "title": "Enable Sprite",
      "type": "boolean"
    },
    "sprite_rows": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Sprite row count when enable_sprite is true.",
      "title": "Sprite Rows"
    },
    "sprite_cols": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Sprite column count when enable_sprite is true.",
      "title": "Sprite Cols"
    },
    "scale_long": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Optional per-frame long-side scale.",
      "title": "Scale Long"
    },
    "scale_short": {
      "anyOf": [
        {},
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Optional per-frame short-side scale.",
      "title": "Scale Short"
    },
    "sync": {
      "default": false,
      "description": "Whether to wait synchronously. This Action currently supports async submit+poll; keep false.",
      "title": "Sync",
      "type": "boolean"
    }
  },
  "required": [
    "video_url"
  ],
  "title": "ActionInput",
  "type": "object"
}
```

### 参数说明

| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| `video_url` | string | ✅ 是 | `-` | Public HTTP(S) input video URL. |
| `snapshot_type` | string / null | ❌ 否 | `-` | Extraction strategy: TimeInterval, SpecifiedTime, SpecifiedFrames, or SceneChange. Defaults to SpecifiedFrames. |
| `time_interval` | object / null | ❌ 否 | `-` | Seconds between frames when snapshot_type is TimeInterval. |
| `specified_time` | array / null | ❌ 否 | `-` | Second offsets when snapshot_type is SpecifiedTime. |
| `specified_frames` | array / null | ❌ 否 | `-` | Frame selectors when snapshot_type is SpecifiedFrames. Use 0 for first frame and -1 for last frame. Defaults to [0]. |
| `scene_change_threshold` | object / null | ❌ 否 | `-` | Sensitivity when snapshot_type is SceneChange. Lower values are more sensitive; default is 0.1. |
| `snapshot_limit` | object / null | ❌ 否 | `-` | Maximum frame count for TimeInterval and SceneChange, 1..1000. Defaults to 100 for unbounded strategies. |
| `enable_sprite` | boolean | ❌ 否 | `False` | Whether to combine extracted frames into sprite image output. |
| `sprite_rows` | object / null | ❌ 否 | `-` | Sprite row count when enable_sprite is true. |
| `sprite_cols` | object / null | ❌ 否 | `-` | Sprite column count when enable_sprite is true. |
| `scale_long` | object / null | ❌ 否 | `-` | Optional per-frame long-side scale. |
| `scale_short` | object / null | ❌ 否 | `-` | Optional per-frame short-side scale. |
| `sync` | boolean | ❌ 否 | `False` | Whether to wait synchronously. This Action currently supports async submit+poll; keep false. |

## 📤 输出结果 (Output Schema)

```json
{
  "properties": {
    "input_tokens": {
      "default": 0,
      "description": "输入消耗的词元数量",
      "title": "Input Tokens",
      "type": "integer"
    },
    "output_tokens": {
      "default": 0,
      "description": "输出消耗的词元数量",
      "title": "Output Tokens",
      "type": "integer"
    },
    "total_tokens": {
      "default": 0,
      "description": "总消耗的词元数量",
      "title": "Total Tokens",
      "type": "integer"
    },
    "model": {
      "default": "",
      "description": "实际使用的 SEE2AI 化身模型名称（由各 action 显式填写）",
      "title": "Model",
      "type": "string"
    },
    "source": {
      "default": "see2ai",
      "description": "服务来源（统一 `see2ai`；真实路由仅平台内部可见）",
      "title": "Source",
      "type": "string"
    },
    "cost_points": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "预先计算的扣费词元（如果插件内部已经计算好费用，则直接使用此值，忽略基于词元的计算）",
      "title": "Cost Points"
    },
    "task_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "SEE2AI platform task id for status polling.",
      "title": "Task Id"
    },
    "status": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Task status: running, success, or failed.",
      "title": "Status"
    },
    "snapshot_type": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Frame extraction strategy.",
      "title": "Snapshot Type"
    },
    "result_urls": {
      "description": "Stable SEE2AI hosted frame or sprite URLs.",
      "items": {
        "type": "string"
      },
      "title": "Result Urls",
      "type": "array"
    },
    "image_urls": {
      "description": "Stable SEE2AI hosted frame or sprite URLs.",
      "items": {
        "type": "string"
      },
      "title": "Image Urls",
      "type": "array"
    },
    "first_frame_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "First returned frame URL, convenient for cover-image workflows.",
      "title": "First Frame Url"
    },
    "sprite_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Stable sprite URL when sprite output is enabled and returned as one image.",
      "title": "Sprite Url"
    },
    "snapshot_count": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Provider-reported frame count, when available.",
      "title": "Snapshot Count"
    },
    "estimated_cost": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Estimated platform token cost for submit.",
      "title": "Estimated Cost"
    },
    "warnings": {
      "anyOf": [
        {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "List of non-blocking optimization suggestions produced by validation.",
      "title": "Warnings"
    }
  },
  "title": "ActionOutput",
  "type": "object"
}
```

### 输出字段说明

| 字段名 | 类型 | 说明 |
|--------|------|------|
| `input_tokens` | integer | 输入消耗的词元数量 |
| `output_tokens` | integer | 输出消耗的词元数量 |
| `total_tokens` | integer | 总消耗的词元数量 |
| `model` | string | 实际使用的 SEE2AI 化身模型名称（由各 action 显式填写） |
| `source` | string | 服务来源（统一 `see2ai`；真实路由仅平台内部可见） |
| `cost_points` | integer / null | 预先计算的扣费词元（如果插件内部已经计算好费用，则直接使用此值，忽略基于词元的计算） |
| `task_id` | string / null | SEE2AI platform task id for status polling. |
| `status` | string / null | Task status: running, success, or failed. |
| `snapshot_type` | string / null | Frame extraction strategy. |
| `result_urls` | array | Stable SEE2AI hosted frame or sprite URLs. |
| `image_urls` | array | Stable SEE2AI hosted frame or sprite URLs. |
| `first_frame_url` | string / null | First returned frame URL, convenient for cover-image workflows. |
| `sprite_url` | string / null | Stable sprite URL when sprite output is enabled and returned as one image. |
| `snapshot_count` | integer / null | Provider-reported frame count, when available. |
| `estimated_cost` | integer / null | Estimated platform token cost for submit. |
| `warnings` | array / null | List of non-blocking optimization suggestions produced by validation. |

## 💡 调用示例

### cURL 示例

```bash
curl -X POST "https://see2ai.com/api/v1/actions/see2ai_video_frame_extract_v1" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer sk-your-tenant-api-key" \
     -d '{
  "video_url": "https://example.com/video.mp4",
  "enable_sprite": false,
  "sync": false
}'
```

### Python 示例

```python
import requests

API_KEY = "sk-your-tenant-api-key"
ENDPOINT = "https://see2ai.com/api/v1/actions/see2ai_video_frame_extract_v1"

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

payload = {
  "video_url": "https://example.com/video.mp4",
  "enable_sprite": false,
  "sync": false
}

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

print(f"结果：{result}")
```

## 💰 计费说明

> Each successfully delivered frame is charged from 0.02 CNY per frame. Submit/running/failed tasks are not charged.

**注意**: 所有费用都以词元为单位，系统会自动从租户余额中扣除。

## ⚠️ 常见错误码

| HTTP 状态码 | 错误原因 | 解决方案 |
| --- | --- | --- |
| `401` | Authentication failed or tenant balance is insufficient | 检查 API Key 是否正确，或联系管理员充值 |
| `422` | Input validation failed | 检查请求参数是否符合 Schema 要求 |
| `503` | SEE2AI video frame extraction service is temporarily unavailable | 请稍后重试 |

## 📞 技术支持

- **文档问题**: 查看 [SEE2AI 官方文档](https://see2ai.com/docs)
- **API 状态**: 访问 [服务状态页面](https://see2ai.com/status)
- **问题反馈**: 联系技术支持团队

---

**API 版本**: see2ai_video_frame_extract_v1
**最后更新**: 2026-03-23
