mcpField
F
faceswap

faceswap

github.com/calesthio创意与媒体73.0k1.1k 次安装1 天前更新
代码仓库

关于 faceswap

faceswap 是通过 HeyGen API 将来源图像中的人脸替换到目标视频中的技能,适用于需要异步处理并获取输出视频链接的工作流。

主要功能

  1. 01将来源人脸替换到目标视频
  2. 02通过 HeyGen API 提交任务
  3. 03轮询任务执行状态
  4. 04获取输出视频链接

适用场景

  1. 01为 Avatar 视频替换自定义人脸
  2. 02将照片中的人脸应用到录制视频

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/calesthio/openmontage --skill faceswap

安装后在 Claude Code 中输入/faceswap确认已加载。

详细介绍

人脸交换(HeyGen API)

使用 GPU 加速的 AI 处理,将源图像中的人脸交换到目标视频中。源图像提供要交换进去的人脸,目标视频则会换上这张新脸。

身份验证

所有请求都需要 X-Api-Key 标头。请设置 HEYGEN_API_KEY 环境变量。

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"}}'

默认工作流

  1. 调用 POST /v1/workflows/executions,并传入 workflow_type: "FaceswapNode"、源人脸图像和目标视频
  2. 在响应中获取 execution_id
  3. 每隔 10 秒轮询一次 GET /v1/workflows/executions/{id},直到状态为 completed
  4. 使用输出中返回的 video_url

执行人脸交换

端点

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

请求字段
字段类型必填描述
workflow_typestringY必须为 "FaceswapNode"
input.source_image_urlstringY要交换进去的人脸图像 URL
input.target_video_urlstringY要应用人脸交换的视频 URL
curl
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
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
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"]
响应格式
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "submitted"
  }
}

检查状态

端点

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

curl
curl -X GET "https://api.heygen.com/v1/workflows/executions/node-gw-f1s2w3p4" \
  -H "X-Api-Key: $HEYGEN_API_KEY"
响应格式(已完成)
{
  "data": {
    "execution_id": "node-gw-f1s2w3p4",
    "status": "completed",
    "output": {
      "video_url": "https://resource.heygen.ai/faceswap/output.mp4"
    }
  }
}

轮询直至完成

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");
}

使用示例

基本人脸交换
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"
    }
  }'
与头像视频串联

先生成头像视频,然后交换为自定义人脸:

import time

# Step 1: Generate avatar video
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
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
faceswap_execution_id = faceswap(
    source_image_url="https://example.com/custom-face.jpg",
    target_video_url=avatar_video_url,
)

最佳实践

  1. 使用清晰的正面人脸照片 — 源图像应展示一张光线良好的人脸
  2. 人脸交换需要大量 GPU 资源 — 预计处理时间为 1-3 分钟,每隔 10 秒轮询一次
  3. 源图像质量很重要 — 分辨率更高的人脸照片能带来更好的效果
  4. 每张源图像仅包含一张人脸 — 源图像应恰好包含一张要交换进去的人脸
  5. 适用于任何视频 — 目标视频可以是头像视频、录制视频,或任何包含可见人脸的视频
  6. 与其他工作流串联 — 先生成头像视频,然后交换为自定义人脸,实现个性化

评论

支持 Markdown