AIMoCap

文档

快速开始、视频动捕、体型管理、API 与订阅说明。

AIMoCap Docs

API 接口说明

AIMoCap 异步视频动捕 API 的上行字段、下行字段与 Python 调用示例。

异步流程

1. 创建任务

POST /api/v1/mocap/jobs

请求体:

{
  "title": "tennis-02",
  "sourceType": "upload",
  "sourceFilename": "tennis_02.mp4",
  "sourceBytes": 24500812,
  "sourceDurationSec": 18.4,
  "trimStartSec": 1.2,
  "trimEndSec": 13.8,
  "targetId": "default"
}

字段说明:

字段 类型 必填 说明
title string 可选任务标题
sourceType string 首版固定为 upload
sourceFilename string 原始文件名
sourceBytes number 文件大小,单位字节
sourceDurationSec number 原始视频总时长
trimStartSec number 选中的起始时间
trimEndSec number 选中的结束时间
targetId string defaultunitree_g1avatar:{avatarId}

返回:

{
  "jobId": "mocap_xxx",
  "status": "draft",
  "uploadUrl": "https://...",
  "sourceKey": "..."
}

2. 上传源文件

对返回的 uploadUrl 发起 PUT,上传视频二进制内容。

3. 完成准入

POST /api/v1/mocap/jobs/{jobId}/complete-upload

如果 admission 成功:

  • 任务进入队列
  • API v-credit 在这一刻扣减

4. 轮询任务状态

GET /api/v1/mocap/jobs/{jobId}

示例返回:

{
  "job": {
    "id": "mocap_xxx",
    "status": "processing",
    "targetIds": ["default"]
  },
  "events": [],
  "result": null
}

5. 获取最终结果

GET /api/v1/mocap/jobs/{jobId}/result

公共字段:

字段 说明
jobId 任务 ID
status 最终状态
targetId 输出目标
previewVideoUrl 预览视频链接
manifestUrl 结果 manifest 链接
createdAt 创建时间
updatedAt 更新时间
completedAt 完成时间

按目标区分的结果字段:

目标 resultType 返回字段
default fbx fbxUrl
avatar:{avatarId} fbx fbxUrl
unitree_g1 robot_motion_json motionJsonUrl

Python 调用示例

import time
import requests

BASE_URL = "https://aimocap.net"
API_KEY = "sk-your-api-key"
VIDEO_PATH = "tennis_02.mp4"

headers = {
    "Authorization": f"Bearer {API_KEY}",
}

with open(VIDEO_PATH, "rb") as f:
    video_bytes = f.read()

create_payload = {
    "title": "tennis-02",
    "sourceType": "upload",
    "sourceFilename": "tennis_02.mp4",
    "sourceBytes": len(video_bytes),
    "sourceDurationSec": 18.4,
    "trimStartSec": 1.2,
    "trimEndSec": 13.8,
    "targetId": "default",
}

create_resp = requests.post(
    f"{BASE_URL}/api/v1/mocap/jobs",
    json=create_payload,
    headers=headers,
)
create_resp.raise_for_status()
create_data = create_resp.json()["data"]

upload_resp = requests.put(
    create_data["uploadUrl"],
    data=video_bytes,
    headers={"Content-Type": "video/mp4"},
)
upload_resp.raise_for_status()

complete_resp = requests.post(
    f"{BASE_URL}/api/v1/mocap/jobs/{create_data['jobId']}/complete-upload",
    headers=headers,
)
complete_resp.raise_for_status()

while True:
    job_resp = requests.get(
        f"{BASE_URL}/api/v1/mocap/jobs/{create_data['jobId']}",
        headers=headers,
    )
    job_resp.raise_for_status()
    job_data = job_resp.json()["data"]
    status = job_data["job"]["status"]
    if status in {"completed", "failed", "canceled"}:
        break
    time.sleep(5)

result_resp = requests.get(
    f"{BASE_URL}/api/v1/mocap/jobs/{create_data['jobId']}/result",
    headers=headers,
)
result_resp.raise_for_status()
result = result_resp.json()["data"]

print("result type:", result["resultType"])
print("preview:", result.get("previewVideoUrl"))
print("fbx:", result.get("fbxUrl"))
print("motion json:", result.get("motionJsonUrl"))