faceswap

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Face Swap (HeyGen API)

视频换脸(HeyGen API)

Swap a face from a source image into a target video using GPU-accelerated AI processing. The source image provides the face to swap in, and the target video receives the new face.
利用GPU加速的AI处理技术,将源图片中的人脸替换到目标视频中。源图片提供待替换的人脸,目标视频将应用这张新人脸。

Authentication

身份验证

All requests require the
X-Api-Key
header. Set the
HEYGEN_API_KEY
environment variable.
bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workflow_type": "FaceswapNode", "input": {"source_image_url": "https://example.com/face.jpg", "target_video_url": "https://example.com/video.mp4"}}'
所有请求都需要携带
X-Api-Key
请求头。请设置
HEYGEN_API_KEY
环境变量。
bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workflow_type": "FaceswapNode", "input": {"source_image_url": "https://example.com/face.jpg", "target_video_url": "https://example.com/video.mp4"}}'

Default Workflow

默认工作流

  1. Call
    POST /v1/workflows/executions
    with
    workflow_type: "FaceswapNode"
    , a source face image, and a target video
  2. Receive a
    execution_id
    in the response
  3. Poll
    GET /v1/workflows/executions/{id}
    every 10 seconds until status is
    completed
  4. Use the returned
    video_url
    from the output
  1. 调用
    POST /v1/workflows/executions
    接口,指定
    workflow_type: "FaceswapNode"
    ,并传入源人脸图片和目标视频
  2. 从响应中获取
    execution_id
  3. 每10秒轮询一次
    GET /v1/workflows/executions/{id}
    ,直到状态变为
    completed
  4. 使用返回结果中的
    video_url
    获取处理后的视频

Execute Face Swap

执行换脸操作

Endpoint

接口地址

POST https://api.heygen.com/v1/workflows/executions
POST https://api.heygen.com/v1/workflows/executions

Request Fields

请求参数

FieldTypeReqDescription
workflow_type
stringYMust be
"FaceswapNode"
input.source_image_url
stringYURL of the face image to swap in
input.target_video_url
stringYURL of the video to apply the face swap to
字段类型必填描述
workflow_type
string必须设置为
"FaceswapNode"
input.source_image_url
string待替换人脸的图片URL
input.target_video_url
string要应用换脸的目标视频URL

curl

curl示例

bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_type": "FaceswapNode",
    "input": {
      "source_image_url": "https://example.com/face-photo.jpg",
      "target_video_url": "https://example.com/original-video.mp4"
    }
  }'
bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_type": "FaceswapNode",
    "input": {
      "source_image_url": "https://example.com/face-photo.jpg",
      "target_video_url": "https://example.com/original-video.mp4"
    }
  }'

TypeScript

TypeScript示例

typescript
interface FaceswapInput {
  source_image_url: string;
  target_video_url: string;
}

interface ExecuteResponse {
  data: {
    execution_id: string;
    status: "submitted";
  };
}

async function faceswap(input: FaceswapInput): Promise<string> {
  const response = await fetch("https://api.heygen.com/v1/workflows/executions", {
    method: "POST",
    headers: {
      "X-Api-Key": process.env.HEYGEN_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_type: "FaceswapNode",
      input,
    }),
  });

  const json: ExecuteResponse = await response.json();
  return json.data.execution_id;
}
typescript
interface FaceswapInput {
  source_image_url: string;
  target_video_url: string;
}

interface ExecuteResponse {
  data: {
    execution_id: string;
    status: "submitted";
  };
}

async function faceswap(input: FaceswapInput): Promise<string> {
  const response = await fetch("https://api.heygen.com/v1/workflows/executions", {
    method: "POST",
    headers: {
      "X-Api-Key": process.env.HEYGEN_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_type: "FaceswapNode",
      input,
    }),
  });

  const json: ExecuteResponse = await response.json();
  return json.data.execution_id;
}

Python

Python示例

python
import requests
import os

def faceswap(source_image_url: str, target_video_url: str) -> str:
    payload = {
        "workflow_type": "FaceswapNode",
        "input": {
            "source_image_url": source_image_url,
            "target_video_url": target_video_url,
        },
    }

    response = requests.post(
        "https://api.heygen.com/v1/workflows/executions",
        headers={
            "X-Api-Key": os.environ["HEYGEN_API_KEY"],
            "Content-Type": "application/json",
        },
        json=payload,
    )

    data = response.json()
    return data["data"]["execution_id"]
python
import requests
import os

def faceswap(source_image_url: str, target_video_url: str) -> str:
    payload = {
        "workflow_type": "FaceswapNode",
        "input": {
            "source_image_url": source_image_url,
            "target_video_url": target_video_url,
        },
    }

    response = requests.post(
        "https://api.heygen.com/v1/workflows/executions",
        headers={
            "X-Api-Key": os.environ["HEYGEN_API_KEY"],
            "Content-Type": "application/json",
        },
        json=payload,
    )

    data = response.json()
    return data["data"]["execution_id"]

Response Format

响应格式

json
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "submitted"
  }
}
json
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "submitted"
  }
}

Check Status

检查任务状态

Endpoint

接口地址

GET https://api.heygen.com/v1/workflows/executions/{execution_id}
GET https://api.heygen.com/v1/workflows/executions/{execution_id}

curl

curl示例

bash
curl -X GET "https://api.heygen.com/v1/workflows/executions/node-gw-f1s2w3p4" \
  -H "X-Api-Key: $HEYGEN_API_KEY"
bash
curl -X GET "https://api.heygen.com/v1/workflows/executions/node-gw-f1s2w3p4" \
  -H "X-Api-Key: $HEYGEN_API_KEY"

Response Format (Completed)

完成状态下的响应格式

json
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "completed",
    "output": {
      "video_url": "https://resource.heygen.ai/faceswap/output.mp4"
    }
  }
}
json
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "completed",
    "output": {
      "video_url": "https://resource.heygen.ai/faceswap/output.mp4"
    }
  }
}

Polling for Completion

轮询等待任务完成

typescript
async function faceswapAndWait(
  input: FaceswapInput,
  maxWaitMs = 600000,
  pollIntervalMs = 10000
): Promise<string> {
  const executionId = await faceswap(input);
  console.log(`Submitted face swap: ${executionId}`);

  const startTime = Date.now();
  while (Date.now() - startTime < maxWaitMs) {
    const response = await fetch(
      `https://api.heygen.com/v1/workflows/executions/${executionId}`,
      { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } }
    );
    const { data } = await response.json();

    switch (data.status) {
      case "completed":
        return data.output.video_url;
      case "failed":
        throw new Error(data.error?.message || "Face swap failed");
      case "not_found":
        throw new Error("Workflow not found");
      default:
        await new Promise((r) => setTimeout(r, pollIntervalMs));
    }
  }

  throw new Error("Face swap timed out");
}
typescript
async function faceswapAndWait(
  input: FaceswapInput,
  maxWaitMs = 600000,
  pollIntervalMs = 10000
): Promise<string> {
  const executionId = await faceswap(input);
  console.log(`Submitted face swap: ${executionId}`);

  const startTime = Date.now();
  while (Date.now() - startTime < maxWaitMs) {
    const response = await fetch(
      `https://api.heygen.com/v1/workflows/executions/${executionId}`,
      { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } }
    );
    const { data } = await response.json();

    switch (data.status) {
      case "completed":
        return data.output.video_url;
      case "failed":
        throw new Error(data.error?.message || "Face swap failed");
      case "not_found":
        throw new Error("Workflow not found");
      default:
        await new Promise((r) => setTimeout(r, pollIntervalMs));
    }
  }

  throw new Error("Face swap timed out");
}

Usage Examples

使用示例

Basic Face Swap

基础换脸操作

bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_type": "FaceswapNode",
    "input": {
      "source_image_url": "https://example.com/headshot.jpg",
      "target_video_url": "https://example.com/presentation.mp4"
    }
  }'
bash
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_type": "FaceswapNode",
    "input": {
      "source_image_url": "https://example.com/headshot.jpg",
      "target_video_url": "https://example.com/presentation.mp4"
    }
  }'

Chain with Avatar Video

与虚拟人视频生成流程结合

Generate an avatar video first, then swap in a custom face:
python
import time
先生成虚拟人视频,再替换为自定义人脸:
python
import time

Step 1: Generate avatar video

步骤1:生成虚拟人视频

avatar_execution_id = requests.post( "https://api.heygen.com/v1/workflows/executions", headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"], "Content-Type": "application/json"}, json={ "workflow_type": "AvatarInferenceNode", "input": { "avatar": {"avatar_id": "Angela-inblackskirt-20220820"}, "audio_list": [{"audio_url": "https://example.com/speech.mp3"}], }, }, ).json()["data"]["execution_id"]
avatar_execution_id = requests.post( "https://api.heygen.com/v1/workflows/executions", headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"], "Content-Type": "application/json"}, json={ "workflow_type": "AvatarInferenceNode", "input": { "avatar": {"avatar_id": "Angela-inblackskirt-20220820"}, "audio_list": [{"audio_url": "https://example.com/speech.mp3"}], }, }, ).json()["data"]["execution_id"]

Step 2: Wait for avatar video to complete

步骤2:等待虚拟人视频生成完成

while True: status = requests.get( f"https://api.heygen.com/v1/workflows/executions/{avatar_execution_id}", headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"]}, ).json()["data"] if status["status"] == "completed": avatar_video_url = status["output"]["video"]["video_url"] break time.sleep(10)
while True: status = requests.get( f"https://api.heygen.com/v1/workflows/executions/{avatar_execution_id}", headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"]}, ).json()["data"] if status["status"] == "completed": avatar_video_url = status["output"]["video"]["video_url"] break time.sleep(10)

Step 3: Swap in a custom face

步骤3:替换为自定义人脸

faceswap_execution_id = faceswap( source_image_url="https://example.com/custom-face.jpg", target_video_url=avatar_video_url, )
undefined
faceswap_execution_id = faceswap( source_image_url="https://example.com/custom-face.jpg", target_video_url=avatar_video_url, )
undefined

Best Practices

最佳实践

  1. Use a clear, front-facing face photo — the source image should show a single face with good lighting
  2. Face swap is GPU-intensive — expect 1-3 minutes processing time, poll every 10 seconds
  3. Source image quality matters — higher resolution face photos produce better results
  4. One face per source image — the source should contain exactly one face to swap in
  5. Works with any video — the target video can be an avatar video, a recording, or any video with visible faces
  6. Chain with other workflows — generate an avatar video first, then swap in a custom face for personalization
  1. 使用清晰的正面人脸照片 —— 源图片应展示单张人脸,且光线良好
  2. 换脸操作GPU消耗大 —— 处理时间预计为1-3分钟,建议每10秒轮询一次状态
  3. 源图片质量至关重要 —— 分辨率更高的人脸照片会带来更好的换脸效果
  4. 每张源图片仅含一张人脸 —— 源图片中应恰好包含一张待替换的人脸
  5. 支持任意视频 —— 目标视频可以是虚拟人视频、录制视频或任何包含清晰人脸的视频
  6. 与其他工作流结合 —— 先生成虚拟人视频,再替换为自定义人脸以实现个性化需求