# Seedance 2.0 : lip-sync, dialogue et 4 clips réels

> Le dialogue est écrit dans le prompt Seedance 2.0, et notre enregistrement de 1,8 s part comme audio de référence : bouche, piste audio, champs et quatre clips.

- Canonical HTML: https://omniakey.com/fr/blog/seedance-lip-sync
- Markdown: https://omniakey.com/fr/blog/seedance-lip-sync.md
- Published: 2026-11-03 (updated 2026-11-03)
- Author: Kiki, COO at OmniaKey
- Language: fr
- Category: Guide
- Reading time: 11 min
- All posts: https://omniakey.com/blog/llms.txt

---

Seedance 2.0 fait bouger la bouche selon le prompt. Deux clips de 5 secondes en 720P, identiques sauf l'audio activé ou coupé, ouvrent et ferment la bouche. Notre enregistrement de 1,8 seconde est passé par `reference_to_video`, et la phrase est revenue dans la piste de sortie. L'audio seul est refusé. BytePlus facture $0.15 par seconde en 720P, donc $0.75 pour 5 secondes.

## Réponse courte

- La bouche vient du prompt. Deux clips de 5 secondes en 720P avec le même prompt, l'un avec audio généré, l'autre muet, sont passés par fermée → entrouverte → grande ouverte.
- L'audio seul ne passe pas. La série 2.0 exige au moins une image ou une vidéo de référence (API de création de tâche BytePlus, vérifiée le 3 novembre 2026).
- L'audio de référence accepte 3 clips au maximum, de 2 à 15 secondes chacun, 15 secondes au total, en wav ou mp3, 15 Mo par fichier.
- L'audio sert vraiment. Notre mp3 de 1,8 seconde est revenu dans la piste de sortie, la phrase est complète.
- Au prix à la seconde de BytePlus, 720P coûte $0.15 par seconde, soit $0.75 pour 5 secondes.
- Quatre clips du même jour : 720P avec audio, 720P muet, image vers vidéo en 720P carré, 480P avec audio de référence.

## Seedance 2.0 fait-il du lip-sync ?

La documentation officielle n'emploie pas l'expression « lip-sync ». Elle décrit une génération conjointe de l'image et du son, puis conseille de mettre le dialogue entre guillemets doubles.

La page Seed de ByteDance présente Seedance 2.0 comme « a unified multimodal audio-video joint generation architecture that supports text, image, audio, and video inputs » (vérifiée le 3 novembre 2026). Le guide BytePlus ModelArk reprend la même idée et liste « Generate videos with audio » parmi les capacités (page mise à jour le 29 septembre 2026).

En cherchant dans ces pages, « lip sync » et « talking » n'apparaissent jamais. « mouth » apparaît une fois, dans un prompt d'exemple, et « dialogue » deux fois, toujours à propos de la génération audio. Le plus proche d'une consigne est cette phrase : « It is recommended to put dialogue content in double quotes to optimize the audio generation effect » (API de création de tâche, mise à jour le 28 octobre 2026).

La fonction se situe donc entre les deux : le modèle produit l'image et la piste audio, mais aucune page officielle ne promet que les lèvres suivent chaque syllabe. Sur nos quatre clips, la bouche a bougé avec et sans audio, ce qu'on attend d'un modèle vidéo dont le prompt dit que quelqu'un parle.

D'autres essaient. Un commentaire Hacker News du 18 février 2026 a envoyé une chanson avec la vidéo et conclut « the model did reference the singing music I provided, but it reinterpreted it on its own » ([commentaire](https://news.ycombinator.com/item?id=47056286)). Un ticket GitHub du 3 juin 2026 pose « Mouth movements match phoneme timing » comme condition de réussite, une mesure absente de la documentation ([ticket](https://github.com/etblues449/Faceless-Finance/issues/92)).

## Comment écrire la réplique dans le prompt

D'abord le personnage, ensuite la réplique entre guillemets doubles, enfin le mouvement de la bouche et du visage. Notre prompt décrivait le personnage et la bouche, mais avait oublié les guillemets : la réplique a donc été choisie par le modèle.

Notre méthode tient en cinq étapes.

1. Le personnage en une phrase : stop-motion en pâte à modeler, grandes lunettes rondes, écharpe en laine, assis à une table de cuisine.
2. Ce qu'il fait : dire une courte réplique face caméra.
3. La réplique, telle quelle, entre guillemets doubles. C'est la recommandation de BytePlus.
4. La bouche et le visage : les lèvres s'ouvrent et se ferment avec les mots, les sourcils suivent la phrase, la tête penche sur la syllabe accentuée.
5. Caméra et lumière fixes, pour que seule la gestuelle bouge.

Voici le prompt envoyé, sans modification, pour les quatre clips :

> A stop-motion clay character with big round glasses and a knitted scarf sits at a kitchen table, looks straight into the camera, and speaks one short line to the viewer. The mouth opens and closes in time with the words, the eyebrows move with the sentence, and the head tilts slightly on the stressed word. Fixed camera, warm lamp light, a mug of tea in front of them, gentle 24 fps stop-motion feel.

Il manque la réplique. Le prompt disait seulement « une courte réplique », donc les mots viennent du modèle. Avec l'audio, il dit « You look like you could use a warm hug. », une phrase absente de la requête. Pour contrôler le dialogue, l'étape 3 doit être ajoutée avant l'envoi.

Nous avons regardé la bouche image par image, une toutes les 0,5 seconde. Le clip avec audio commence bouche fermée, reste entrouvert des images 2 à 7, s'ouvre grand à l'image 8, puis se referme. Le clip muet montre fermée, entrouverte, grande ouverte, entrouverte, grande ouverte, et les deux dernières images entrouvertes.

![Dix gros plans d'un personnage en pâte à modeler avec de grandes lunettes rondes et une écharpe, un toutes les demi-secondes : bouche fermée sur le premier et le dernier, ouverte entre les deux, grande ouverte sur le huitième.](https://omniakey.com/_img/blog/seedance-lip-sync/t1-t2v-audio-strip.3d59731f.1600.webp)

_Avec audio, une image toutes les demi-secondes : bouche fermée sur l'image 1, entrouverte de 2 à 7, grande ouverte sur la 8 et refermée sur la 10. Seedance 2.0 via OmniaKey, texte vers vidéo, 5 secondes, 720P, généré le 3 novembre 2026._

![Dix gros plans d'un personnage orange en pâte à modeler à l'écharpe vert foncé, un toutes les demi-secondes, qui ouvre et ferme la bouche, tirés d'une vidéo sans piste audio.](https://omniakey.com/_img/blog/seedance-lip-sync/t1-t2v-silent-strip.58b1caee.1600.webp)

_Audio coupé et même prompt : la bouche s'ouvre et se ferme quand même, grande ouverte sur les images 5, 6 et 8, et le fichier n'a aucune piste audio. 5 secondes, 720P, généré le 3 novembre 2026._

Le même texte choisit aussi un autre personnage : le clip muet est revenu avec un corps orange, une raie châtain gris et une écharpe vert foncé. La phrase du personnage est à écrire comme une suggestion. Sur les deux clips la caméra n'a pas bougé, c'est l'effet de « Fixed camera ».

## Peut-on envoyer son propre audio ?

Oui, avec une image ou une vidéo de référence dans la même requête. Notre mp3 de 1,8 seconde est passé comme audio de référence, et ses mots sont revenus dans la piste de sortie.

Nous avons utilisé `reference_to_video` avec trois pièces : l'image fixe en pâte à modeler comme image de référence, notre enregistrement comme audio de référence, et le prompt ci-dessus. Les paramètres étaient 480P, 5 secondes et audio activé. OmniaKey a répondu 202, la tâche `task_3Ay0Ktf2mbYXh9GNZpZ5j9kGyOIzz8Pv` a réussi, et 120,2 secondes plus tard un MP4 de 864×496 est arrivé avec une piste aac de 5.06 secondes.

La transcription de cette piste donne une seule phrase : « Why tow it? I told you the keys were in the drawer. » La seconde moitié est exactement notre enregistrement, mot pour mot. Les trois premiers mots ne venaient pas de notre fichier ; la transcription ne distingue pas notre respiration d'un ajout du modèle, donc nous laissons ce qui s'entend.

![Dix images d'un personnage en pâte à modeler marron avec chapeau et écharpe orange derrière une table en bois, la bouche se ferme et s'ouvre, la vapeur de la tasse bouge.](https://omniakey.com/_img/blog/seedance-lip-sync/t3-ref-audio-strip.edfa40c7.1600.webp)

_Avec notre enregistrement en référence : la bouche bouge, la vapeur de la tasse dérive, et la piste de sortie porte la phrase envoyée. 5 secondes, 480P, généré le 3 novembre 2026._

Dix images à 0,5 seconde d'intervalle montrent seulement que la bouche bouge. Pour l'alignement par phonème, il faudrait des images plus denses et une mesure dédiée, ce que nous n'avons pas fait : les lèvres ne peuvent donc pas être dites synchrones de chaque son.

Les limites viennent de l'API de création de tâche BytePlus (vérifiée le 3 novembre 2026). L'audio accepte 3 clips, de 2 à 15 secondes chacun, 15 secondes au total, en wav ou mp3, 15 Mo par fichier. Un clip peut arriver en URL publique, en chaîne Base64 ou en identifiant de ressource. L'audio seul est refusé : « Audio-only input is not supported; include at least one reference image or video. »

> Pas de vrais visages. La série 2.0 refuse les images et vidéos de référence contenant une personne réelle ; pour une scène parlée, prenez un personnage en pâte à modeler, dessiné ou en images de synthèse.

## L'image vers vidéo change de plan tout seul

Notre clip image vers vidéo est passé d'un plan large debout à un plan rapproché assis dans la cuisine à l'image 4, alors que le prompt ne demandait ni coupe ni mouvement de caméra.

La première image est un fixe généré pour cet essai : le personnage debout devant un mur blanc chaud, bras le long du corps, en pied, 1254×1254 pixels. Le prompt est celui du dessus, qui l'assied à une table de cuisine. Les images 1 à 3 restent debout, la 4 saute au plan rapproché assis et s'y tient. La bouche est fermée jusqu'à l'image 7, entrouverte à la 8, grande ouverte aux images 9 et 10. La bande-son contient « Well, what do you think? » et des froissements de tissu.

![Dix images d'une vidéo carrée : le personnage en pâte à modeler est debout au début, puis assis à la table de la cuisine, bouche ouverte.](https://omniakey.com/_img/blog/seedance-lip-sync/t2-i2v-audio-strip.c23818f5.1600.webp)

_Image vers vidéo : le plan debout dure un instant, puis le montage passe à l'assise de cuisine demandée par le prompt, absente de l'image. 5 secondes, 720P, généré le 3 novembre 2026._

Ici c'est le cadrage qui compte, pas la bouche. Sur ce modèle, le prompt décide où se trouve le personnage et comment bouge la caméra, et la première image décide de son apparence. Un plan important s'écrit dans le prompt.

Le fichier est arrivé en 960×960, pas en 1280×720. La cause : une image carrée en première image et aucune proportion envoyée, et l'API suit alors l'image par défaut. Pour choisir un format, écrivez `ratio` au lieu de le déduire du nom de la résolution.

## La requête en Python

Créer la tâche, interroger l'identifiant, télécharger le MP4 : trois requêtes, bibliothèque standard seule. Le même utilitaire sert aux trois étapes.

```python
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "dreamina-seedance-2-0-260128"

PROMPT = (
    "A stop-motion clay character with big round glasses and a knitted scarf sits at a kitchen table, "
    "looks straight into the camera, and speaks one short line to the viewer. The mouth opens and closes "
    "in time with the words, the eyebrows move with the sentence, and the head tilts slightly on the "
    "stressed word. Fixed camera, warm lamp light, a mug of tea in front of them, gentle 24 fps "
    "stop-motion feel."
)

MIME = {".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg",
        ".webp": "image/webp", ".mp3": "audio/mpeg", ".wav": "audio/wav"}


def call(method, url, body=None, idempotency_key=None):
    headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode()
    if idempotency_key:
        headers["Idempotency-Key"] = idempotency_key
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)


def data_url(path, limit_mb):
    raw = open(path, "rb").read()
    if len(raw) > limit_mb * 1024 * 1024:  # 30 Mo pour une image, 15 Mo pour l'audio
        raise ValueError(f"{path} is over {limit_mb} MB, the limit for this input type")
    mime = MIME[os.path.splitext(path)[1].lower()]
    return f"data:{mime};base64," + base64.b64encode(raw).decode()


def wait(task_id, timeout=900, step=5):
    deadline = time.time() + timeout
    while time.time() < deadline:
        state = call("GET", f"{API}/{task_id}")
        if state["status"] not in ("queued", "processing"):
            return state
        time.sleep(step)
    raise TimeoutError(f"{task_id} is still running: poll it again, do not resubmit")


def run(body, out_path):
    task_id = call("POST", API, body, str(uuid.uuid4()))["id"]
    print("task", task_id, flush=True)
    state = wait(task_id)
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    signed = state["assets"][0]["url"]  # expire, donc on télécharge tout de suite
    req = urllib.request.Request(signed, headers={"User-Agent": "omniakey-example/1"})
    with urllib.request.urlopen(req, timeout=300) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    return task_id


def reference_to_video(prompt, image_path, audio_path, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "reference_to_video",
        "input": {
            "prompt": prompt,
            "media": [
                {"type": "reference_image", "url": data_url(image_path, 30)},
                {"type": "reference_audio", "url": data_url(audio_path, 15)},
            ],
        },
        "parameters": {"duration": 5, "resolution": "480P", "ratio": "16:9",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)


if __name__ == "__main__":
    print("done", reference_to_video(PROMPT, "character.png", "line.mp3", "line-clip.mp4"))
```

Trois détails méritent de rester. La clé `Idempotency-Key` est un UUID neuf par requête : un renvoi récupère la tâche d'origine au lieu de payer deux fois. La boucle d'attente s'arrête au bout de 15 minutes avec une exception, car un délai dépassé signifie que le clip rend encore et un nouvel envoi en achète un second. Le téléchargement se fait au premier `succeeded`, parce que `assets[0].url` est un lien signé qui expire.

Les deux autres opérations changent seulement le corps, les utilitaires restent :

```python
def text_to_video(prompt, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "text_to_video",
        "input": {"prompt": prompt},
        "parameters": {"duration": 5, "resolution": "720P", "ratio": "16:9",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)


def image_to_video(prompt, image_path, out_path):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "image_to_video",
        "input": {"prompt": prompt,
                  "media": [{"type": "first_frame", "url": data_url(image_path, 30)}]},
        "parameters": {"duration": 5, "resolution": "720P", "ratio": "adaptive",
                       "generate_audio": True, "watermark": False},
    }
    return run(body, out_path)
```

La liste des champs est courte : `model`, `type`, `operation`, `input.prompt`, `input.media[]` avec `type` à `first_frame`, `reference_image`, `reference_video` ou `reference_audio`, puis `parameters.duration`, `resolution`, `ratio`, `generate_audio`, `watermark`. La même forme se trouve dans la [documentation de l'API vidéo](https://docs.omniakey.com/en/media/video) d'OmniaKey, et le cycle création, interrogation, téléchargement est décrit dans la [vue d'ensemble de l'API média](https://docs.omniakey.com/en/media/overview). Ce modèle s'essaie depuis la [page du modèle Seedance 2.0](https://omniakey.com/fr/dreamina-seedance-2-0-260128).

## Combien ça coûte

BytePlus facture à la seconde. Le tarif public pour 5 secondes en 16:9 sans entrée vidéo est celui-ci (page des prix ModelArk, vérifiée le 3 novembre 2026) :

|Sortie|Par seconde|Clip de 5 s|
|-|-|-|
|480p|$0.07|$0.35|
|720p|$0.15|$0.76|
|1080p|$0.37|$1.87|
|4K|$0.78|$3.89|

Le calcul à partir de la colonne par seconde donne le même résultat, à un centime d'arrondi près sur la page : 5 secondes × $0.15 = $0.75, contre $0.76 sur la ligne 720p. Nos deux clips texte vers vidéo étaient en 720P sur 5 secondes, donc chacun se situe à ces $0.75.

Une requête avec vidéo en entrée est facturée autrement, et plus cher : une tâche avec vidéo de référence ne rentre pas dans ce tableau (page des prix ModelArk, vérifiée le 3 novembre 2026). OmniaKey facture à la seconde générée et rembourse quand une tâche finit en `failed` ou `canceled` (vue d'ensemble de l'API média, vérifiée le 3 novembre 2026) ; le tarif en vigueur est sur la [page du modèle](https://omniakey.com/fr/dreamina-seedance-2-0-260128).

## Ce qui rate

- L'audio seul est refusé. Ajoutez au moins une image ou une vidéo de référence à côté de la piste.
- Les vrais visages sont bloqués. Une image ou une vidéo de référence avec une personne réelle ne passe pas : prenez un personnage en pâte à modeler, dessiné ou en images de synthèse.
- `generate_audio` est actif par défaut. Pour un fichier muet il faut le désactiver ; pour une réplique, on le laisse et le prompt dit que quelqu'un parle.
- La taille livrée suit `ratio`. 720P a donné 1280×720 depuis du texte, 960×960 depuis un fixe carré sans proportion, et 864×496 en 480P avec 16:9.
- La vitesse varie. Quatre tâches de 5 secondes ont pris 259,0, 202,0, 155,3 et 120,2 secondes : comptez deux à cinq minutes et interrogez l'état.
- La durée va de 4 à 15 secondes en sortie, les clips de référence de 2 à 15 secondes chacun, 15 au total. Les quatre fichiers sont revenus à 24 fps.

## Questions fréquentes

### Si j'envoie un WAV, la bouche suit-elle mon enregistrement ?

Oui, avec une image de référence, et le modèle l'utilise : notre enregistrement est revenu dans la piste de sortie. Savoir si les lèvres tombent sur chaque son du fichier, nos images ne le montrent pas ; une image toutes les 0,5 seconde montre que la bouche bouge, pas une correspondance mesurée.

### Pourquoi ma requête audio seule a-t-elle été refusée ?

La série 2.0 n'accepte pas l'audio comme seule entrée. Ajoutez une image ou une vidéo de référence à la même requête et la piste passe avec.

### Faut-il activer l'audio pour une réplique ?

Laissez-le actif, c'est la valeur par défaut. Avec `false`, le fichier n'a aucune piste audio et le personnage ouvre quand même la bouche si le prompt dit qu'il parle, comme notre clip muet.

### Quelle longueur pour l'audio de référence ?

Chaque clip fait 2 à 15 secondes, 3 clips au maximum, 15 secondes au total, en wav ou mp3 et 15 Mo par fichier (API de création de tâche BytePlus, vérifiée le 3 novembre 2026). Le nôtre faisait 1,8 seconde, moins que ce minimum, et est quand même passé en URL de données Base64.

## Sources vérifiées

- [ByteDance Seed : Seedance 2.0](https://seed.bytedance.com/en/seedance2_0), vérifiée le 3 novembre 2026
- [BytePlus ModelArk : guide Seedance 2.0](https://docs.byteplus.com/en/docs/ModelArk/seedance-2-0), vérifié le 3 novembre 2026
- [BytePlus ModelArk : API de création de tâche vidéo](https://docs.byteplus.com/en/docs/ModelArk/create-video-generation-task-api), vérifiée le 3 novembre 2026
- [BytePlus ModelArk : prix des modèles](https://docs.byteplus.com/en/docs/ModelArk/model-pricing), vérifiés le 3 novembre 2026

## Journal des modifications

- 3 novembre 2026 : première version, les quatre clips ont été générés ce jour-là.
