Guide
Processus d'intégration des ressources de portrait et des vidéos de référence
Processus complet et exécutable, de la création du groupe et de l'import des images à la soumission multi-images avec vidéo de référence
Processus d'intégration des ressources de portrait et des vidéos de référence
Cette page présente une séquence d'appels côté serveur directement applicable. Les champs, exemples et codes d'erreur de chaque étape se trouvent dans les pages d'interface ; ici, seuls l'ordre des opérations et le code complet sont présentés :
- Les interfaces liées à la bibliothèque de ressources sont décrites dans Vue d'ensemble des interfaces de la bibliothèque de ressources ;
- Les interfaces liées aux tâches vidéo sont décrites dans Créer une tâche vidéo.
https://locopalai.com
Authorization: Bearer <API_KEY>
Content-Type: application/jsonOrdre des appels
Ressources virtuelles
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}Ressources de portrait
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/generationsCréer un groupe real ne signifie pas que la plateforme effectue l'autorisation à la place de la personne concernée ; lorsqu'une personne réelle est concernée, c'est toujours elle qui doit effectuer la collecte et l'autorisation.
1. Import d'un portrait virtuel
- Créer un groupe :
POST /api/v1/materials/groups, passezvirtualàtype, et enregistrez ledata.group.idde la réponse. Les champs et exemples sont décrits dans Groupes de ressources. - Soumettre l'image :
POST /api/v1/materials/assets, avecgroup_id+image_url(oudata_url), et enregistrezdata.asset_id.titlepeut rester vide ; la plateforme le nommera automatiquement d'après le nom de fichier. - Interroger le statut :
GET /api/v1/materials/assets/{asset_id}, de préférence toutes les 5 à 10 secondes, en interrogeant uniquement le même ID de ressource.
data.asset.status | Traitement |
|---|---|
Processing | Interrogez plus tard le même asset_id |
Active | Vous pouvez utiliser asset://asset-id dans la requête vidéo |
Failed | Lisez error_message, corrigez l'image puis créez une nouvelle ressource |
2. Autorisation de ressources de portrait par scan de code QR
POST /api/v1/materials/portrait/sessionspour obtenirauthorization_urletsession_token, puis convertissez l'adresse en code QR et remettez-le à la personne concernée pour qu'elle le scanne.- Une fois la collecte effectuée par la personne elle-même, appelez
POST /api/v1/materials/portrait/resolve(avecsession_token) pour obtenir legroup.iddu groupe de portrait. POST /api/v1/materials/syncpour synchroniser une fois, puis interrogez la liste des ressources pour lire l'asset_idet lestatusde la ressource de portrait.
Les paramètres, réponses et codes d'erreur sont décrits dans Autorisation de ressources de portrait.
3. Soumission multi-images + vidéo de référence
Le format de « multi-images + vidéo de profondeur » dans l'interface publique est le suivant : chaque image occupe un élément content, la vidéo de référence utilise video_url et role: "reference_video", et il n'existe pas de champ deep_video distinct.
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())Si les images ont déjà été validées par la bibliothèque de ressources, remplacez l'URL de l'image par asset://<asset_id> ; chaque image doit toujours occuper un élément content distinct. Le nombre d'images de référence, la capacité de vidéo de référence, la résolution, la durée et les capacités audio dépendent des capacités du modèle renvoyées par /v1/models et des erreurs réelles.
4. Exemple Node.js complet
Le code ci-dessous enchaîne « créer un groupe → soumettre l'image → interroger le statut → soumettre la vidéo » ; la clé API est lue depuis les variables d'environnement.
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())5. Exemple complet d'autorisation de portrait en 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 })6. Changement de modèle et gestion des erreurs
Les ressources virtuelles continuent d'utiliser le même asset://<asset_id> ; lors d'un changement de modèle, seul le champ model change. Les ressources de portrait ne peuvent être soumises qu'à des modèles prenant en charge la bibliothèque de ressources de portrait ; si le modèle actuel ne le prend pas en charge, l'interface renvoie une erreur lisible, et il n'est pas possible de convertir la ressource de portrait en URL d'image ordinaire pour contourner la limitation.
401: vérifiez si la clé API est absente, erronée ou expirée ;400: vérifiez l'intégrité des champs du corps de requête et du jeton de session ;404: vérifiez si l'ID de ressource et l'ID de groupe appartiennent au compte actuel ;503: le service de ressources ou d'autorisation de portrait est temporairement indisponible ; conservez les informations de requête et contactez le support de la plateforme ;Processing: continuez d'interroger le même ID de ressource, ne réimportez pas ;Failed: lisezerror_message, corrigez le fichier source puis créez une nouvelle ressource.
Questions fréquentes sur la bibliothèque de ressources
Appartenance des groupes, durée de validation, fréquence d'interrogation et exigences relatives aux adresses d'image
Images multiples et vidéos de référence
Images de référence multiples, vidéo de référence, vidéo de profondeur, audio, limites de capacités, reprise des tâches et facturation
