Chuyển đến nội dung chính
LocoPal AiLocoPal Ai
Thư viện tư liệu

Hướng dẫn

Quy trình tích hợp tư liệu chân dung và video tham chiếu

Quy trình hoàn chỉnh có thể chạy từ tạo nhóm, nhập hình ảnh vào thư viện đến gửi nhiều ảnh kèm video tham chiếu

Xem Markdown

Quy trình tích hợp tư liệu chân dung và video tham chiếu

Trang này đưa ra một trình tự gọi phía máy chủ có thể áp dụng trực tiếp. Trường, ví dụ và mã lỗi của từng bước nằm ở trang API; ở đây chỉ minh họa thứ tự và mã hoàn chỉnh:

https://locopalai.com
Authorization: Bearer <API_KEY>
Content-Type: application/json

Thứ tự gọi

Tư liệu ảo

POST /api/v1/materials/groups
  → POST /api/v1/materials/assets
  → GET  /api/v1/materials/assets/{asset_id}   轮询到 status 为 Active
  → POST /v1/video/generations
  → GET  /v1/video/generations/{task_id}

Tư liệu người thật

POST /api/v1/materials/groups {"type":"real"}
  → POST /api/v1/materials/portrait/sessions   拿到二维码链接
  → 真人本人扫码并完成手机采集
  → POST /api/v1/materials/portrait/resolve
  → POST /api/v1/materials/sync
  → GET  /api/v1/materials/assets?group_id=...
  → POST /v1/video/generations

Tạo nhóm real không có nghĩa là nền tảng thay người thật hoàn tất ủy quyền; khi liên quan đến bản thân người thật, vẫn phải do người đó hoàn tất thu thập và ủy quyền.

Một, nhập chân dung ảo vào thư viện

  1. Tạo nhóm: POST /api/v1/materials/groups, truyền type là virtual, lưu data.group.id trong phản hồi. Trường và ví dụ xem Nhóm tư liệu.
  2. Gửi hình ảnh: POST /api/v1/materials/assets, dùng group_id + image_url (hoặc data_url), lưu data.asset_id. title có thể để trống, nền tảng sẽ tự đặt tên theo tên tệp.
  3. Truy vấn trạng thái: GET /api/v1/materials/assets/{asset_id}, khuyến nghị truy vấn mỗi 5~10 giây, chỉ truy vấn cùng một ID tư liệu.
data.asset.statusCách xử lý
ProcessingTruy vấn lại cùng asset_id sau
ActiveCó thể dùng asset://asset-id trong yêu cầu video
FailedĐọc error_message, sửa ảnh rồi tạo tư liệu mới

Hai, ủy quyền quét mã cho tư liệu người thật

  1. POST /api/v1/materials/portrait/sessions lấy authorization_url và session_token, chuyển địa chỉ thành mã QR giao cho người thật quét.
  2. Sau khi bản thân người thật hoàn tất thu thập, gọi POST /api/v1/materials/portrait/resolve (kèm session_token), lấy group.id của nhóm người thật.
  3. POST /api/v1/materials/sync đồng bộ một lần, rồi truy vấn danh sách tư liệu để đọc asset_id và status của tư liệu người thật.

Tham số, phản hồi và mã lỗi xem Ủy quyền tư liệu người thật.

Ba, gửi nhiều ảnh + video tham chiếu

「Nhiều ảnh + video độ sâu」trong API công khai có định dạng là: mỗi hình ảnh chiếm một phần tử content, video tham chiếu dùng video_url và role: "reference_video", không có trường deep_video riêng.

export LOCOPAL_API_KEY="sk-你的APIKey"
export LOCOPAL_VIDEO_MODEL_ID="从 /v1/models 返回的视频模型 ID"
export LOCOPAL_PERSON_IMAGE_URL="https://你的对象存储域名/person.png"
export LOCOPAL_PRODUCT_IMAGE_URL="https://你的对象存储域名/product.png"
export LOCOPAL_REFERENCE_VIDEO_URL="https://你的对象存储域名/motion.mp4"
const origin = 'https://locopalai.com'
const apiKey = process.env.LOCOPAL_API_KEY!
const model = process.env.LOCOPAL_VIDEO_MODEL_ID!
const personImage = process.env.LOCOPAL_PERSON_IMAGE_URL!
const productImage = process.env.LOCOPAL_PRODUCT_IMAGE_URL!
const referenceVideo = process.env.LOCOPAL_REFERENCE_VIDEO_URL!

const response = await fetch(`${origin}/v1/video/generations`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model,
    content: [
      { type: 'text', text: '以图片1的人物为主体,参考图片2的产品外观,按照参考视频的动作节奏和运镜生成视频。' },
      { type: 'image_url', role: 'reference_image', image_url: { url: personImage } },
      { type: 'image_url', role: 'reference_image', image_url: { url: productImage } },
      { type: 'video_url', role: 'reference_video', video_url: { url: referenceVideo } },
    ],
    resolution: '720p',
    ratio: '16:9',
    duration: 5,
    generate_audio: true,
    watermark: false,
  }),
})

const created = (await response.json()) as { id?: string; error?: { message?: string } }
if (!response.ok || !created.id) throw new Error(created.error?.message ?? `创建视频失败:HTTP ${response.status}`)

// 保存 created.id。网络中断后只查询这个 ID,不要重复创建。
const query = await fetch(`${origin}/v1/video/generations/${encodeURIComponent(created.id)}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
})
if (!query.ok) throw new Error(await query.text())
console.log(await query.json())

Nếu hình ảnh đã được kiểm duyệt qua thư viện tư liệu, chỉ cần đổi URL ảnh thành asset://<asset_id>, mỗi hình ảnh vẫn phải chiếm riêng một phần tử content. Số lượng ảnh tham chiếu, khả năng video tham chiếu, độ phân giải, thời lượng và khả năng âm thanh căn cứ vào năng lực mô hình do /v1/models trả về và lỗi thực tế.

Bốn, ví dụ Node.js hoàn chỉnh

Đoạn mã dưới đây nối liền「tạo nhóm → gửi hình ảnh → truy vấn trạng thái → gửi video」, khóa API đọc từ biến môi trường.

const origin = process.env.LOCOPAL_API_ORIGIN ?? 'https://locopalai.com'
const apiKey = process.env.LOCOPAL_API_KEY
const imageUrl = process.env.LOCOPAL_IMAGE_URL
const videoModelId = process.env.LOCOPAL_VIDEO_MODEL_ID

if (!apiKey || !imageUrl || !videoModelId) {
  throw new Error('请设置 LOCOPAL_API_KEY、LOCOPAL_IMAGE_URL、LOCOPAL_VIDEO_MODEL_ID')
}

async function locopal<T>(path: string, init: RequestInit = {}) {
  const response = await fetch(`${origin}${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      ...init.headers,
    },
  })
  const payload = (await response.json()) as { code?: number; data?: T; msg?: string }
  if (!response.ok || payload.code !== 0) throw new Error(payload.msg ?? `请求失败:HTTP ${response.status}`)
  return payload.data as T
}

const group = await locopal<{ group: { id: string } }>('/api/v1/materials/groups', {
  method: 'POST',
  body: JSON.stringify({ name: 'API 人像参考素材', description: '虚拟素材分组', type: 'virtual' }),
})

const asset = await locopal<{ asset_id: string }>('/api/v1/materials/assets', {
  method: 'POST',
  body: JSON.stringify({ group_id: group.group.id, title: '人物参考图', image_url: imageUrl }),
})

const state = await locopal<{ asset: { status: string; error_message?: string | null } }>(
  `/api/v1/materials/assets/${encodeURIComponent(asset.asset_id)}`,
)
if (state.asset.status !== 'Active') {
  throw new Error(state.asset.error_message ?? '素材尚未可用')
}

const video = await fetch(`${origin}/v1/video/generations`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: videoModelId,
    content: [
      { type: 'text', text: '让人物自然转身,保持人物外观一致。' },
      { type: 'image_url', role: 'reference_image', image_url: { url: `asset://${asset.asset_id}` } },
    ],
    resolution: '720p',
    ratio: '16:9',
    duration: 5,
  }),
})
if (!video.ok) throw new Error(await video.text())
console.log(await video.json())

Năm, ví dụ ủy quyền người thật Node.js hoàn chỉnh

const origin = 'https://locopalai.com'
const apiKey = process.env.LOCOPAL_API_KEY!

async function api<T>(path: string, init: RequestInit = {}) {
  const response = await fetch(`${origin}${path}`, {
    ...init,
    headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', ...init.headers },
  })
  const payload = (await response.json()) as { code?: number; data?: T; msg?: string }
  if (!response.ok || payload.code !== 0) throw new Error(payload.msg ?? `请求失败:HTTP ${response.status}`)
  return payload.data as T
}

const created = await api<{ session: { authorization_url: string; session_token: string } }>(
  '/api/v1/materials/portrait/sessions',
  { method: 'POST', body: JSON.stringify({ continuous_create: false }) },
)

// 把 authorization_url 转成二维码展示给真人本人。
// 等用户在手机端完成采集后,再执行下面的解析请求。
const resolved = await api<{ group: { id: string; type: string } }>('/api/v1/materials/portrait/resolve', {
  method: 'POST',
  body: JSON.stringify({ session_token: created.session.session_token }),
})

await api('/api/v1/materials/sync', { method: 'POST', body: '{}' })
const assets = await api<{ assets: Array<{ id: string; status: string }> }>(
  `/api/v1/materials/assets?group_id=${encodeURIComponent(resolved.group.id)}&page=1&page_size=20`,
)
console.log({ group: resolved.group, assets })

Sáu, chuyển mô hình và xử lý lỗi

Tư liệu ảo tiếp tục dùng cùng một asset://<asset_id>, khi đổi mô hình chỉ cần đổi trường model. Tư liệu người thật chỉ có thể gửi tới mô hình hỗ trợ thư viện tư liệu người thật; khi mô hình hiện tại không hỗ trợ, API sẽ trả về lỗi có thể đọc được, không thể đổi tư liệu người thật thành URL ảnh thông thường để vượt qua giới hạn.

  • 401: kiểm tra khóa API có thiếu, sai hoặc hết hiệu lực không;
  • 400: kiểm tra các trường của phần thân yêu cầu và Token phiên có đầy đủ không;
  • 404: kiểm tra ID tư liệu, ID nhóm có thuộc tài khoản hiện tại không;
  • 503: dịch vụ tư liệu hoặc ủy quyền người thật tạm thời không khả dụng, giữ thông tin yêu cầu rồi liên hệ hỗ trợ nền tảng;
  • Processing: tiếp tục truy vấn cùng một ID tư liệu, không nhập lại;
  • Failed: đọc error_message, sửa tệp nguồn rồi tạo tư liệu mới.
Trang này có hữu ích không?

Trong trang này