🚀 快速入门
iSamurai API 为我们的 AI 视频与图像处理工具套件提供了编程访问能力。无论您是在构建内容创作平台、在您的应用中集成换脸技术,还是添加电影级慢动作效果,我们的 RESTful API 都能让这一切变得简单。
基础 URL
https://isamur.ai/api/
快速开始步骤
积分系统:所有处理操作都会消耗积分。在提交任务前,请通过 /api/user-credits/ 查看您的余额。查看我们的价格方案以购买积分包。
📦 SDK 与工具
借助我们的官方客户端库和代码示例,加速您的开发进程。
🔐 身份验证
所有 API 端点都需要进行身份验证。请在每次请求的 Authorization 请求头中包含您的凭证。
API 密钥认证(推荐)
对于服务器到服务器的集成,API 密钥是推荐的身份验证方式。密钥永不过期,并为访问所有端点提供了一种简单、安全的方式。
curl -H "Authorization: Api-Key isk_your_api_key_here" \
https://isamur.ai/api/user-credits/
🎭 换脸 API
换脸 API可让您在视频和图像中无缝地进行换脸。请先使用预览端点用单帧进行测试,然后再处理完整视频。
快速预览(单帧)
/api/preview-swap-api/
在处理完整视频之前,生成换脸效果的单帧预览。使用 base64 编码的图像。消耗约 1-2 积分。
请求体(JSON)
| 参数 | 类型 | 是否必需 | 说明 |
|---|---|---|---|
source_image_base64 | string | 必需 | Base64 编码的源人脸图像 |
target_image_base64 | string | 必需 | Base64 编码的目标帧(来自视频或图像) |
instance | UUID | 可选 | 已存在的 FaceSwap 实例 ID |
enhance | boolean | 可选 | 是否应用人脸增强(默认:false) |
import requests
import base64
API_KEY = "isk_your_api_key_here"
BASE_URL = "https://isamur.ai/api"
# 将图像转换为 base64
def to_base64(file_path):
with open(file_path, "rb") as f:
return base64.b64encode(f.read()).decode()
# 生成预览
response = requests.post(
f"{BASE_URL}/preview-swap-api/",
headers={
"Authorization": f"Api-Key {API_KEY}",
"Content-Type": "application/json"
},
json={
"source_image_base64": to_base64("face.jpg"),
"target_image_base64": to_base64("target_frame.jpg"),
"enhance": False
}
)
# 保存预览图像
preview_base64 = response.json()["image_base64"]
with open("preview.jpg", "wb") as f:
f.write(base64.b64decode(preview_base64))
响应
{
"image_base64": "/9j/4AAQSkZJRgABAQAAAQ...",
"preview_id": "abc123"
}
完整视频处理(合并上传与处理)
/api/full-process-swap/
在一次请求中上传文件并立即开始处理。这是自动化工作流推荐使用的端点。每分钟视频扣除约 50 积分。
请求参数(multipart/form-data)
| 参数 | 类型 | 是否必需 | 说明 |
|---|---|---|---|
source_image | File | 必需 | 人脸图像文件(JPG/PNG) |
target_media | File | 必需 | 视频文件(MP4/MOV)或图像 |
gquality | string | 必需 | 480p、720p 或 1080p |
name | string | 可选 | 任务名称(最多 20 个字符) |
description | string | 可选 | 描述(最多 20 个字符) |
import requests
API_KEY = "isk_your_api_key_here"
BASE_URL = "https://isamur.ai/api"
# 上传本地文件并开始处理
with open("face.jpg", "rb") as source, open("video.mp4", "rb") as target:
response = requests.post(
f"{BASE_URL}/full-process-swap/",
headers={"Authorization": f"Api-Key {API_KEY}"},
files={
"source_image": ("face.jpg", source, "image/jpeg"),
"target_media": ("video.mp4", target, "video/mp4")
},
data={
"gquality": "720p",
"name": "My Swap",
"description": "Demo"
}
)
result = response.json()
instance_id = result["faceswap"]["id"]
print(f"Processing started: {instance_id}")
查询进度
/api/swap-progress/?id={instance_id}
轮询此端点以监控任务进度,直到状态变为 Done。
状态值
| 状态 | 说明 |
|---|---|
Queued | 排队等待中 |
Processing | 正在处理 |
Done | 已完成 - 输出结果可用 |
Failed | 发生错误 |
Cancelled | 用户已取消 |
import time
while True:
response = requests.get(
f"{BASE_URL}/swap-progress/",
headers={"Authorization": f"Api-Key {API_KEY}"},
params={"id": instance_id}
)
data = response.json()
print(f"Status: {data['status']} - {data.get('progress_percentage', 0)}%")
if data["status"] == "Done":
print(f"Output: {data['output_media_url']}")
break
elif data["status"] in ["Failed", "Cancelled"]:
print(f"Error: {data.get('error')}")
break
time.sleep(5)
停止/取消任务
/api/stop-job/
取消正在运行的任务。您将获得 50% 的积分退还。
{"id": "instance_uuid", "type": "faceswap"}
👥 多人换脸 API
在同一个视频中替换多张人脸。先分析画面帧以检测所有人脸,为每张人脸分配对应的源图像,然后再进行处理。
步骤 1:分析画面帧(检测人脸)
/api/analyse-frame/
检测视频画面帧中的所有人脸。请发送来自目标视频的 base64 编码帧。
请求体(JSON)
| 参数 | 类型 | 说明 |
|---|---|---|
target_image_base64 | string | 来自目标视频的 base64 编码帧 |
import base64
# 从视频中捕获一帧(可使用 OpenCV、ffmpeg 等工具)
with open("frame.jpg", "rb") as f:
frame_b64 = base64.b64encode(f.read()).decode()
response = requests.post(
f"{BASE_URL}/analyse-frame/",
headers={
"Authorization": f"Api-Key {API_KEY}",
"Content-Type": "application/json"
},
json={"target_image_base64": frame_b64}
)
faces = response.json()["analysis"]
for face in faces:
print(f"Face detected: {face['person_id']}")
响应
{
"analysis": [
{"person_id": "P1", "thumbnail": "base64...", "bbox": [x, y, w, h]},
{"person_id": "P2", "thumbnail": "base64...", "bbox": [x, y, w, h]}
]
}
步骤 2:预览多人换脸(可选)
/api/multi-preview-swap-api/
在进行完整处理之前,先在单帧上预览多人换脸效果。
请求体(JSON)
{
"target_image_base64": "base64_frame...",
"analysis_results": [
{
"person_id": "P1",
"thumbnail": "base64...",
"source_image": "base64_of_source_face_1"
},
{
"person_id": "P2",
"thumbnail": "base64...",
"source_image": "base64_of_source_face_2"
}
],
"enhance": false
}
响应
{"preview_image": "base64_result..."}
步骤 3:完整多人换脸处理
/api/multiple-face-swap/
使用全部人脸映射关系处理完整视频。请使用 multipart/form-data。
请求参数(multipart/form-data)
| 参数 | 类型 | 说明 |
|---|---|---|
target_media | File | 视频文件(MP4/MOV) |
gquality | string | 480p、720p 或 1080p |
analysis_results | JSON string | 包含每张人脸 source_image base64 数据的数组 |
步骤 4:查询进度
/api/swap-progress/?id={instance_id}&multi=True
轮询查询进度。对于多人换脸任务,请添加 multi=True 参数。
⏱️ 慢动作与帧率提升 API
使用 AI 帧插值技术制作精美的慢动作视频。我们的慢动作技术会在现有帧之间生成新的帧,让您可以将画面最多减速至 8 倍,同时保持流畅、自然的运动效果。
积分价格
| 倍数 | 每秒成本 | 使用场景 |
|---|---|---|
| 2 倍慢速 | 2 积分/秒 | 平滑慢动作 |
| 4 倍超级 | 3 积分/秒 | 戏剧化慢动作 |
| 8 倍极致 | 7 积分/秒 | 极限慢动作 |
创建慢动作项目
/api/slowmotion/
上传视频并配置慢动作参数。
请求参数(multipart/form-data)
| 参数 | 类型 | 可选值 | 说明 |
|---|---|---|---|
source_video | File | - | 需要减速的视频(MP4/MOV) |
slowdown_factor | int | 2、4、8 | 减速倍数 |
quality | string | 480p、720p、1080p | 输出画质 |
mode | string | slowmo、fps | slowmo = 更慢的视频,fps = 更流畅的视频 |
with open("action_clip.mp4", "rb") as video:
response = requests.post(
f"{BASE_URL}/slowmotion/",
headers={"Authorization": f"Api-Key {API_KEY}"},
files={"source_video": video},
data={
"slowdown_factor": 4,
"quality": "720p",
"mode": "slowmo"
}
)
project = response.json()["slowmotion"]
print(f"Project ID: {project['id']}")
开始处理
/api/faceswap/slowmotion/process/
开始慢动作处理。
{ "project_id": "uuid" }
/api/faceswap/slowmotion/progress/{project_id}/
查询慢动作处理进度。
✨ 图像修复与增强 API
使用我们 AI 驱动的图像修复工具,修复老旧、损坏的照片,或增强人脸画质。非常适合为老照片注入新生命,或提升低分辨率人脸图像的质量。
/api/restore-image/
使用 AI 修复或增强功能处理图像。
请求参数(multipart/form-data)
| 参数 | 类型 | 可选值 |
|---|---|---|
image | File | JPG/PNG 图像 |
mode | string | restore 或 face_enhance |
响应
{
"url": "/api/media/restored/output.jpg",
"image_base64": "/9j/4AAQSkZ...",
"status": "success"
}
💳 用户与积分 API
监控您的积分余额和账户状态。请在提交任务前查看您的积分,以确保余额充足。查看我们的价格方案以购买更多积分。
/api/user-credits/
获取您当前的积分余额与套餐信息。
响应
{
"user_id": 123,
"user_credits": 9500,
"plan_id": 5,
"plan_name": "Samurai"
}
🖼️ 素材库 API
管理您已上传的源图像。上传一次图像后,即可在多个换脸任务中重复使用。
上传源图像
/api/gallery/sources/
将一张或多张源图像上传到您的素材库。请使用 multipart/form-data,并配合 images 字段。
请求参数(multipart/form-data)
| 参数 | 类型 | 说明 |
|---|---|---|
images | File(s) | 一个或多个图像文件(JPG/PNG)。如需上传多个文件,请重复该字段。 |
import requests
API_KEY = "isk_your_api_key_here"
BASE_URL = "https://isamur.ai/api"
# 上传多张图像
files = [
("images", ("face1.jpg", open("face1.jpg", "rb"), "image/jpeg")),
("images", ("face2.jpg", open("face2.jpg", "rb"), "image/jpeg")),
]
response = requests.post(
f"{BASE_URL}/gallery/sources/",
headers={"Authorization": f"Api-Key {API_KEY}"},
files=files
)
result = response.json()
print(f"Uploaded: {result['message']}")
for img in result["images"]:
print(f" ID: {img['id']} - {img['name']}")
响应
{
"message": "2 images uploaded successfully",
"images": [
{"id": "uuid-1", "name": "face1.jpg", "url": "/media/sources/..."},
{"id": "uuid-2", "name": "face2.jpg", "url": "/media/sources/..."}
]
}
获取源图像列表
/api/gallery/sources/
分页列出您已上传的源图像。
查询参数
| 参数 | 默认值 | 说明 |
|---|---|---|
page | 1 | 页码 |
per_page | 20 | 每页数量(最多 50) |
响应
{
"images": [{"id": "uuid", "name": "face.jpg", "url": "..."}],
"has_next": true,
"total": 45
}
删除源图像
/api/gallery/sources/{image_id}/
根据 ID 删除单张源图像。
/api/gallery/sources/bulk-delete/
一次性删除多张源图像。
{"ids": ["uuid-1", "uuid-2", "uuid-3"]}
预览(已生成的换脸结果)
/api/gallery/previews/
列出您在换脸操作中保存的预览图像。
⚠️ 错误处理
所有 API 错误都会返回统一的 JSON 结构,并附带错误信息。请使用 HTTP 状态码来判断错误类型。
| 状态码 | 含义 | 处理方式 |
|---|---|---|
| 400 | 请求错误 | 检查请求参数 |
| 401 | 未授权 | 检查 API 密钥是否有效 |
| 403 | 禁止访问 | 积分或权限不足 |
| 404 | 未找到 | 资源不存在 |
| 500 | 服务器错误 | 请联系支持团队 |
错误响应格式
{
"error": "Insufficient credits: need 500, have 200",
"success": false
}
🚦 速率限制
每位用户同一时间只能运行一个任务。请等待当前任务完成后再提交新任务。如果在有任务正在处理时提交新任务,该任务将被加入队列。
📚 完整代码示例
常见使用场景的完整可运行示例。
Python:完整换脸工作流
import requests
import time
API_KEY = "isk_your_key_here"
BASE_URL = "https://isamur.ai/api"
HEADERS = {"Authorization": f"Api-Key {API_KEY}"}
def face_swap(source_path, target_path, quality="720p"):
# 步骤 1:上传
with open(source_path, "rb") as src, open(target_path, "rb") as tgt:
resp = requests.post(f"{BASE_URL}/faceswap/", headers=HEADERS,
files={"source_image": src, "target_media": tgt},
data={"gquality": quality})
job_id = resp.json()["faceswap"]["id"]
# 步骤 2:处理
requests.post(f"{BASE_URL}/process-swap/",
headers={**HEADERS, "Content-Type": "application/json"},
json={"instance": job_id})
# 步骤 3:等待完成
while True:
resp = requests.get(f"{BASE_URL}/swap-progress/",
headers=HEADERS, params={"id": job_id})
data = resp.json()
print(f"Progress: {data.get('progress_percentage', 0)}%")
if data["status"] == "Done":
return data["output_media_url"]
elif data["status"] == "Failed":
raise Exception(data.get("error"))
time.sleep(3)
# 使用方法
output = face_swap("face.jpg", "video.mp4")
print(f"Result: https://isamur.ai{output}")
JavaScript:完整换脸工作流
const API_KEY = "isk_your_key_here";
const BASE_URL = "https://isamur.ai/api";
async function faceSwap(sourceFile, targetFile, quality = "720p") {
// 步骤 1:上传
const formData = new FormData();
formData.append("source_image", sourceFile);
formData.append("target_media", targetFile);
formData.append("gquality", quality);
let resp = await fetch(`${BASE_URL}/faceswap/`, {
method: "POST",
headers: { "Authorization": `Api-Key ${API_KEY}` },
body: formData
});
const jobId = (await resp.json()).faceswap.id;
// 步骤 2:处理
await fetch(`${BASE_URL}/process-swap/`, {
method: "POST",
headers: {
"Authorization": `Api-Key ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ instance: jobId })
});
// 步骤 3:轮询等待完成
while (true) {
resp = await fetch(`${BASE_URL}/swap-progress/?id=${jobId}`, {
headers: { "Authorization": `Api-Key ${API_KEY}` }
});
const data = await resp.json();
console.log(`Progress: ${data.progress_percentage || 0}%`);
if (data.status === "Done") return data.output_media_url;
if (data.status === "Failed") throw new Error(data.error);
await new Promise(r => setTimeout(r, 3000));
}
}