Passer à la navigation

Traitement batch

Traiter efficacement plusieurs générations lipsync

L’API Batch de Sync Labs traite jusqu’à 500 générations de lip sync dans une seule requête, envoyées sous forme de fichier JSONL ou de tableau JSON de lignes. C’est idéal pour les workflows de traitement vidéo en masse, comme les campagnes vidéo personnalisées, la localisation de contenu, ou tout scénario qui exige une génération de lip sync à grand volume.

Quel est le format de fichier batch ?

Le traitement batch vous permet d’envoyer 20 à 500 générations sans gérer vous-même la file d’attente ni la concurrence, avec un délai cible de 24 heures. Les jobs batch contournent votre limite de concurrence normale par génération, mais l’API Batch n’est disponible que sur le plan Scale ou supérieur. À ce jour, seules les générations avec des entrées allant jusqu’à 30 secondes sont prises en charge en traitement batch.

L’API Batch nécessite le plan Scale ou supérieur, y compris Enterprise

Limites de concurrence batch

Les jobs batch contournent votre limite de concurrence normale par génération, mais une limite séparée plafonne le nombre de batchs que vous pouvez exécuter en même temps, selon votre plan. Si vous envoyez un nouveau batch alors que vous êtes déjà à cette limite, l’API renvoie une réponse 429 Too Many Requests.

Le corps de la 429 est un objet JSON qui décrit la limite atteinte :

{
"statusCode": 429,
"errorCode": "concurrency_limit_reached",
"message": "Batch concurrency limit reached. Please wait for an existing batch to complete or upgrade your plan.",
"activeBatches": 3,
"concurrencyLimit": 3,
"retryAfterSeconds": 20
}

La réponse inclut aussi un en-tête Retry-After (en secondes) et un en-tête X-Sync-Concurrency-Limit. Plutôt que de réessayer immédiatement, attendez retryAfterSeconds avant de renvoyer, ou attendez qu’un de vos batchs en cours se termine.

Comment créer un job batch ?

1

Préparer votre fichier d'entrée

Créez un fichier JSON Lines (.jsonl) avec vos requêtes de génération. Chaque ligne doit contenir un request_id unique, l’endpoint (doit être "/v2/generate"), et un payload avec le format standard de requête de génération (identique à celui de la API de génération). Le fichier doit être au format JSON Lines (.jsonl) avec un minimum de 20 enregistrements, une taille maximale de 5MB, et jusqu’à 500 requêtes par batch.

input.jsonl
{"request_id": "request-1", "endpoint": "/v2/generate", "payload": {"model": "lipsync-2", "input": [{"type": "video", "url": "https://assets.sync.so/docs/example-video.mp4"}, {"type": "audio", "url": "https://assets.sync.so/docs/example-audio.wav"}]}}
{"request_id": "request-2", "endpoint": "/v2/generate", "payload": {"model": "lipsync-2", "input": [{"type": "video", "url": "https://assets.sync.so/docs/example-video.mp4"}, {"type": "audio", "url": "https://assets.sync.so/docs/example-audio.wav"}]}}
2

Créer un batch

from sync import Sync
sync = Sync()
batch = sync.batch.create(
input=open("input.jsonl", "rb")
)
print(f"Batch created with ID: {batch.id}")

Au lieu de téléverser un fichier, vous pouvez envoyer un corps application/json avec les enregistrements dans rows. Chaque ligne de rows est le même objet qu’une ligne JSONL, et les deux formes sont validées de la même façon : 20 à 500 lignes par défaut, 5 MB maximum une fois écrites en JSONL, et des valeurs request_id uniques. Quand un enregistrement est refusé, l’erreur indique sa ligne. Les refus d’édition de dialogue la renvoient dans un champ lineNumber ; les autres erreurs d’enregistrement, comme un JSON invalide ou un request_id manquant, ne l’indiquent que dans message (par exemple Record at line 4: payload is required). Les lignes comptent les enregistrements non vides, pas les lignes physiques : les lignes vides d’un fichier JSONL sont ignorées ; avec un corps JSON, la ligne N correspond à rows[N-1]. Les exemples ci-dessus montrent deux enregistrements par souci de concision ; un batch en nécessite au moins 20.

Paramètres optionnels :

  • webhook_url: Recevoir des notifications quand le batch est terminé
  • dry_run: Définir true pour valider votre entrée sans lancer le traitement. Une entrée valide renvoie {"status": "VALIDATED"} et ne crée aucun batch.

La création de batch n’est pas couverte par les requêtes idempotentes. Si une requête de création expire, listez vos batchs avec GET /v2/batch avant de renvoyer la requête, afin de ne pas exécuter deux fois les mêmes lignes.

3

Vérifier le statut du batch

Suivez la progression de votre batch en interrogeant son statut :

batch = sync.batch.get(batch_id)
print(f"Status: {batch.status}")
print(f"Progress: {batch.metrics}")

Un batch peut avoir l’un des statuts suivants :

  1. PENDING: Batch créé, en attente de démarrage du traitement
  2. PROCESSING: Les générations sont en cours de traitement
  3. COMPLETED: Toutes les générations sont terminées (avec succès ou échec)
  4. FAILED: Le traitement batch a totalement échoué
4

Vérifier les résultats du batch

Quand un batch se termine, les résultats sont disponibles sous forme de fichier JSON Lines à l’adresse outputUrl de la réponse get batch. Un GET vers cette URL renvoie une redirection 302 vers un fichier de résultats signé, les clients qui suivent automatiquement les redirections peuvent lire directement la réponse JSONL. Chaque ligne contient :

output.jsonl
{"request_id": "request-1", "endpoint": "/v2/generate", "payload": {...}, "status": "COMPLETED", "error": null, "response": {...}, "updated_at": "2024-01-15T10:35:00Z"}
{"request_id": "request-2", "endpoint": "/v2/generate", "payload": {...}, "status": "FAILED", "error": {"code": "INVALID_INPUT", "message": "..."}, "response": null, "updated_at": "2024-01-15T10:35:00Z"}

Le champ response contient les mêmes données que les réponses individuelles de la API de génération. Les noms de champs du fichier de résultats sont en snake_case : la vidéo d’une ligne terminée se trouve donc à response.output_url et son ID de génération à response.id. Associez chaque ligne à votre entrée grâce à request_id.

Pour un exemple complet et fonctionnel, consultez l’exemple de traitement batch dans notre dépôt d’exemples.

Notifications webhook

Lorsque vous fournissez un webhook_url, vous recevrez des notifications POST à la fin du batch :

webhook_payload.json
{
"id": "batch_abc123",
"createdAt": "2024-01-15T10:30:00Z",
"status": "COMPLETED",
"webhookUrl": "https://your-webhook-url.com/batch-webhook",
"metrics": {
"totalGenerations": 5,
"successCount": 4,
"failedCount": 1,
"pendingCount": 0
},
"options": {},
"outputUrl": "https://api.sync.so/v2/batches/batch_abc123/result"
}

Le webhook de fin de batch peut être livré plusieurs fois pour un même batch. Utilisez l’id du batch pour ignorer les notifications que vous avez déjà traitées.

Lignes d’édition de dialogue (accès anticipé)

Une ligne de batch peut produire le rendu d’un aperçu d’édition de dialogue terminé, au lieu d’associer une vidéo à un nouvel audio. Utilisez-la pour transformer une vidéo enregistrée en de nombreuses variantes, par exemple une par nom de destinataire. Le tutoriel Messages vidéo personnalisés propose un script complet.

Les lignes d’édition de dialogue sont en accès anticipé et s’activent par organisation. Contactez-nous pour les activer. D’ici là, les lignes qui contiennent dialogueEdit sont refusées à l’envoi.

Le payload de chaque ligne contient :

  • model, par exemple sync-3.
  • input avec exactement une vidéo : la même vidéo source que celle à partir de laquelle l’aperçu a été créé.
  • dialogueEdit: {"id": "..."} : l’ID d’un aperçu terminé issu de POST /v2/dialogue-edits dans votre organisation.

N’ajoutez pas d’entrées audio ou texte, ni segments, ni dubParams ; l’aperçu fournit l’audio.

{
"rows": [
{
"request_id": "line-2",
"endpoint": "/v2/generate",
"payload": {
"model": "sync-3",
"input": [{"type": "video", "url": "https://assets.sync.so/docs/example-video.mp4"}],
"dialogueEdit": {"id": "7644754c-bdfc-4d51-a78f-e0cb0cbbd40f"}
}
}
],
"dry_run": true
}

Les mêmes objets de ligne fonctionnent aussi comme lignes d’un fichier JSONL téléversé.

À l’envoi, chaque ligne d’édition de dialogue est développée exactement en la requête que POST /v2/generate construit pour cet aperçu, et elle est facturée comme cette génération. Le payload du fichier de résultats montre la requête développée (la vidéo, l’audio de l’aperçu et les segments modifiés), et non la ligne que vous avez envoyée. Envoyez d’abord le batch avec dry_run: true : il exécute toutes les vérifications ci-dessous, y compris le développement, sans effectuer aucun rendu.

  • Toutes les lignes d’édition de dialogue d’un même batch doivent utiliser des aperçus créés à partir de la même vidéo source. Pour plusieurs vidéos, envoyez un batch par vidéo.
  • Les limites habituelles des batchs s’appliquent : 20 à 500 lignes et 5 MB.
  • La plupart des aperçus sont rendus sous forme de segments modifiés de la vidéo. Un aperçu qui ne peut être rendu qu’en lip sync sur la vidéo entière n’est accepté dans un batch que si ce rendu dure 30 secondes ou moins ; générez les plus longs avec POST /v2/generate.

Refus des lignes d’édition de dialogue

Si une ligne d’édition de dialogue ne peut pas être rendue, toute la requête est refusée et aucun batch n’est créé. La réponse contient l’errorCode que POST /v2/generate renverrait pour cet aperçu, ainsi que le lineNumber de la première ligne en échec :

{
"statusCode": 422,
"errorCode": "dialogue_edit_not_found",
"lineNumber": 3,
"message": "Record at line 3: The dialogue edit was not found in this organization."
}
errorCodeStatutCauseCorrection
dialogue_edit_not_found422L’ID est inconnu ou appartient à une autre organisation.Utilisez un aperçu créé par votre organisation.
dialogue_edit_not_completed422L’aperçu est encore PENDING ou PROCESSING, ou il est FAILED.Tant qu’il est en attente ou en cours, interrogez GET /v2/dialogue-edits/{id} jusqu’à ce qu’il soit terminé, puis envoyez le batch. Un aperçu FAILED est définitif : créez-en un nouveau.
dialogue_edit_source_mismatch422La vidéo de la ligne n’est pas celle à partir de laquelle l’aperçu a été créé.Envoyez la vidéo source d’origine de l’aperçu.
dialogue_edit_retime_required422Il manque à l’aperçu le recalage temporel nécessaire à son rendu (segmentLipsyncEnabled ou sectionExpansionEnabled vaut false pour cet aperçu).Créez un nouvel aperçu. S’il indique toujours false, contactez-nous.
dialogue_edit_removal_too_large422La modification supprime plus de parole que les images environnantes ne peuvent en absorber.Restaurez certains mots et créez un nouvel aperçu.
dialogue_edit_audio_conflict422La ligne contient aussi une entrée audio ou texte, segments ou dubParams.N’envoyez que l’entrée vidéo et dialogueEdit.
dialogue_edit_unsupported422L’API ne peut pas rendre cet aperçu, y compris un rendu de la vidéo entière de plus de 30 secondes.Créez un nouvel aperçu de la vidéo entière avec une clé API, ou rendez celui-ci avec POST /v2/generate.
dialogue_edit_batch_mixed_sources422Les aperçus du batch proviennent de vidéos sources différentes.Envoyez un batch par vidéo source.
generation_input_validation_failed400dialogueEdit n’est pas un objet avec un id UUID, ou input ne contient pas exactement une vidéo.Corrigez la structure de la ligne.

Seule la première ligne en échec est signalée. Corrigez-la et relancez le dry run jusqu’à ce qu’il renvoie {"status": "VALIDATED"}.

Ressources associées

  • Rate Limits — comprendre le rate limiting API pour planifier efficacement vos tailles de batch
  • Webhooks Guide — configurer les notifications webhook pour les événements de fin de batch
  • gestion des erreurs — référence des codes d’erreur spécifiques au batch et dépannage