跳至主要內容
LocoPal AiLocoPal Ai
素材庫

使用指南

人像素材與參考影片接入流程

從建立分組、圖片入庫到提交多圖加參考影片的完整可執行流程

檢視 Markdown

人像素材與參考影片接入流程

本頁提供一條可以直接落地的伺服器端呼叫順序。每一步的欄位、範例和錯誤碼在介面頁裡,這裡只示範先後關係與完整程式碼:

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

呼叫順序

虛擬素材

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}

真人素材

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

建立 real 分組不代表平台代替真人本人完成授權;涉及真人本人時,仍必須由本人完成採集和授權。

一、虛擬人像入庫

  1. 建立分組:POST /api/v1/materials/groups,type 傳 virtual,儲存回應裡的 data.group.id。欄位與範例見素材分組。
  2. 提交圖片:POST /api/v1/materials/assets,用 group_id + image_url(或 data_url),儲存 data.asset_id。title 可以留空,平台會依檔名自動命名。
  3. 輪詢狀態:GET /api/v1/materials/assets/{asset_id},建議 5~10 秒查一次,只查同一個素材 ID。
data.asset.status處理方式
Processing稍後查詢同一個 asset_id
Active可以在影片請求裡使用 asset://asset-id
Failed讀取 error_message,修正圖片後建立新的素材

二、真人素材掃碼授權

  1. POST /api/v1/materials/portrait/sessions 取得 authorization_url 和 session_token,把位址轉成 QR 碼交給真人本人掃碼。
  2. 本人完成採集後呼叫 POST /api/v1/materials/portrait/resolve(帶 session_token),取得真人分組 group.id。
  3. POST /api/v1/materials/sync 同步一次,再查詢素材清單讀取真人素材的 asset_id 與 status。

參數、回應和錯誤碼見真人素材授權。

三、多圖 + 參考影片提交

「多圖 + 深度影片」在公開介面裡的格式是:每張圖片各佔一個 content 元素,參考影片使用 video_url 和 role: "reference_video",沒有獨立的 deep_video 欄位。

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())

如果圖片已經透過素材庫審核,把圖片 URL 換成 asset://<asset_id> 即可,每張圖片仍然要單獨佔用一個 content 元素。參考圖片數量、參考影片能力、解析度、時長和音訊能力以 /v1/models 傳回的模型能力和實際錯誤為準。

四、完整 Node.js 範例

下面的程式碼串起「建立分組 → 提交圖片 → 輪詢狀態 → 提交影片」,API Key 從環境變數讀取。

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())

五、完整 Node.js 真人授權範例

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

六、模型切換與錯誤處理

虛擬素材繼續使用同一個 asset://<asset_id>,換模型時只改 model 欄位。真人素材只能提交到支援真人素材庫的模型;目前模型不支援時介面會傳回可讀錯誤,不能把真人素材改成一般圖片 URL 繞過限制。

  • 401:檢查 API Key 是否缺少、錯誤或失效;
  • 400:檢查請求內容欄位和工作階段 Token 是否完整;
  • 404:檢查素材 ID、分組 ID 是否屬於目前帳號;
  • 503:素材或真人授權服務暫時不可用,保留請求資訊後聯絡平台支援;
  • Processing:繼續查詢同一個素材 ID,不要重複入庫;
  • Failed:讀取 error_message,修正來源檔案後建立新的素材。
這一頁有幫助嗎?

本頁目錄