Руководство
Процесс подключения материалов с изображением человека и референсного видео
Полный рабочий процесс — от создания группы и добавления изображений в библиотеку до отправки нескольких изображений с референсным видео
Процесс подключения материалов с изображением человека и референсного видео
На этой странице приведена готовая к практическому применению последовательность серверных вызовов. Поля, примеры и коды ошибок для каждого шага приведены на страницах интерфейсов; здесь показаны только порядок действий и полный код:
- интерфейсы, связанные с библиотекой материалов, см. в разделе Обзор интерфейсов библиотеки материалов;
- интерфейсы, связанные с видеозадачами, см. в разделе Создание видеозадачи.
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 не означает, что платформа выполнит авторизацию вместо самого человека; если речь идёт о реальном человеке, сбор данных и авторизацию по-прежнему должен выполнить он сам.
I. Добавление виртуального портрета в библиотеку
- Создайте группу:
POST /api/v1/materials/groups, передайтеvirtualвtypeи сохранитеdata.group.idиз ответа. Поля и пример см. в разделе Группы материалов. - Отправьте изображение:
POST /api/v1/materials/assets, используяgroup_id+image_url(илиdata_url), и сохранитеdata.asset_id.titleможно оставить пустым — платформа автоматически присвоит название по имени файла. - Опрашивайте статус:
GET /api/v1/materials/assets/{asset_id}, рекомендуется проверять раз в 5–10 секунд, только один и тот же ID материала.
data.asset.status | Способ обработки |
|---|---|
Processing | Запросите тот же asset_id позже |
Active | Можно использовать asset://asset-id в запросе видео |
Failed | Прочитайте error_message, исправьте изображение и создайте новый материал |
II. Авторизация материалов реального человека по QR-коду
POST /api/v1/materials/portrait/sessions— получитеauthorization_urlиsession_token, преобразуйте адрес в QR-код и передайте самому человеку для сканирования.- После завершения сбора данных человеком вызовите
POST /api/v1/materials/portrait/resolve(сsession_token) и получитеgroup.idгруппы реального человека. - Вызовите
POST /api/v1/materials/syncдля однократной синхронизации, затем запросите список материалов, чтобы получитьasset_idиstatusматериалов реального человека.
Параметры, ответы и коды ошибок см. в разделе Авторизация материалов реальных людей.
III. Отправка нескольких изображений + референсного видео
Формат «несколько изображений + видео с глубиной» в публичном интерфейсе таков: каждое изображение занимает отдельный элемент 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, и фактическими сообщениями об ошибках.
IV. Полный пример на 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())V. Полный пример авторизации реального человека на 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 })VI. Смена модели и обработка ошибок
Виртуальные материалы продолжают использовать тот же asset://<asset_id>; при смене модели меняется только поле model. Материалы реальных людей можно отправлять только в модели, поддерживающие библиотеку материалов с реальными людьми; если текущая модель их не поддерживает, интерфейс вернёт понятную ошибку, и нельзя заменять материалы реального человека обычным URL изображения, чтобы обойти ограничение.
401: проверьте, не отсутствует ли API Key, не ошибочен ли он или не истёк ли его срок;400: проверьте полноту полей тела запроса и токена сессии;404: проверьте, принадлежат ли ID материала и ID группы текущей учётной записи;503: сервис материалов или авторизации реальных людей временно недоступен; сохраните информацию о запросе и обратитесь в поддержку платформы;Processing: продолжайте запрашивать тот же ID материала, не добавляйте материал повторно;Failed: прочитайтеerror_message, исправьте исходный файл и создайте новый материал.
Частые вопросы по библиотеке материалов
Принадлежность групп, время проверки, частота опроса и требования к адресам изображений
Описание нескольких изображений и референсного видео
Несколько референсных изображений, референсное видео, видео с глубиной, аудио, границы возможностей, восстановление задачи и оплата
