> For the documentation index, fetch https://sync.so/docs/llms.txt. Append .md to a page URL for Markdown. Documentation-search MCP: https://sync.so/docs/_mcp/server.

# Guide des segments

> Guide du lip sync multi-segments. Synchronisez différents clips audio avec différentes parties de votre timeline vidéo en un seul appel API.

## Vue d ensemble

Les segments vous permettent de synchroniser différents clips audio avec différentes plages temporelles d'une même vidéo en un seul appel API. Cela permet le lip sync multi-locuteurs en assignant différentes entrées audio à différentes parties de votre vidéo. Avec les segments, vous pouvez :

* Appliquer du lip sync à différents clips audio sur différentes parties de votre vidéo
* Utiliser une portion précise d'une entrée audio pour synchroniser un segment avec un timing exact
* Utiliser à la fois des entrées audio et synthèse vocale pour synchroniser plusieurs segments avec différents types d'entrées dans une seule génération

## Concepts de base

Pour utiliser la fonctionnalité de segments, fournissez un tableau [`segments`](/api-reference/api/generate-api/create#request.body.segments) au niveau racine. Chaque élément définit une plage temporelle ou un segment vidéo, avec sa propre configuration audio.

### Segment

Chaque segment accepte les propriétés suivantes :

**`startTime`** `double` — required

Heure de début du segment, en secondes

---

**`endTime`** `double` — required

Heure de fin du segment, en secondes

---

**`audioInput`** `SegmentAudioInput` — required

Configuration audio avec refId et recadrage facultatif

---

**`optionsOverride`** `SegmentOptionsOverride`

Remplacer les options de génération pour ce segment précis

---

### audioInput

Chaque segment nécessite exactement un audioInput. audioInput accepte les propriétés suivantes :

**`refId`** `string` — required

ID de référence de l entrée audio ou synthèse vocale à utiliser pour ce segment

---

**`startTime`** `double`

Heure de début facultative (en secondes) pour recadrer l'audio référencé. Si elle est spécifiée, endTime doit aussi être fourni

---

**`endTime`** `double`

Heure de fin facultative (en secondes) pour recadrer l'audio référencé. Si elle est spécifiée, startTime doit aussi être fourni

---

L audioInput spécifié sera utilisé pour appliquer le lip sync au segment vidéo entre startTime et endTime.

### optionsOverride

Chaque segment peut facultativement remplacer les options de génération définies au niveau racine. Cela vous permet d appliquer des paramètres différents par segment, y compris cibler différents locuteurs.

Pour les vidéos multi-locuteurs, utilisez `active_speaker_detection` pour cibler une personne différente dans chaque segment. Consultez [sélection du locuteur - API](/developer-guides/speaker-selection) pour tous les détails sur les options de sélection du locuteur.

**`sync_mode`** `SyncMode`

Remplacer le [mode Sync](/developer-guides/sync-mode) pour ce segment

---

**`temperature`** `double`

Remplacer l expressivité (0-1) pour ce segment

---

**`occlusion_detection_enabled`** `boolean`

Remplacer la détection d'occlusion pour ce segment

---

**`active_speaker_detection`** `ActiveSpeaker`

Remplacer l'[active speaker detection](/developer-guides/speaker-selection) pour ce segment. Utile lorsque différents segments ont différents locuteurs. Accepte les mêmes options que `active_speaker_detection` au niveau racine :

* `auto_detect` : détecter et cibler automatiquement le locuteur actif
* `v3` : utiliser ASD v3
* `frame_number` + `coordinates` : spécifier manuellement le locuteur par frame et par point
* `bounding_boxes` : fournir des bounding boxes par frame si vous avez des données de détection
* `bounding_boxes_url` : pointer vers un fichier JSON externe contenant les bounding boxes (recommandé pour les longues vidéos afin d éviter de gros payloads de requête)

---

## Fonctionnement du timing et de la durée des segments

Lorsque l'audio d'un segment et sa fenêtre vidéo (`endTime` - `startTime`) ont des durées différentes, [`sync_mode`](/compatibility-and-tips/media-content-tips#sync-mode-options) décide comment résoudre l écart. Le mode choisi modifie la **durée effective** de ce segment dans la sortie :

| `sync_mode` | audio plus long que la fenêtre                                 | audio plus court que la fenêtre                                |
| ----------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| `bounce`    | la vidéo rebondit (avant puis arrière) pour couvrir l'audio    | fenêtre raccourcie à la durée de l'audio                       |
| `loop`      | la vidéo boucle pour couvrir l'audio                           | fenêtre raccourcie à la durée de l'audio                       |
| `cut_off`   | sortie coupée à la piste **la plus courte** (la fenêtre)       | fenêtre raccourcie à la durée de l'audio                       |
| `silence`   | lit tout l'audio (vidéo prolongée pour le couvrir)             | toute la fenêtre est lue ; l'audio est complété par du silence |
| `remap`     | la vidéo est étirée temporellement pour correspondre à l'audio | fenêtre raccourcie à la durée de l'audio                       |

En bref, la durée effective d'un segment est `cut_off` -> min(audio, fenêtre), `silence` -> max(audio, fenêtre), et `loop` / `bounce` / `remap` -> la durée de l'audio.

> **Note**
>
> Les mêmes règles s'appliquent à une génération à segment unique (sans `segments`), où la "fenêtre" correspond à toute la vidéo. Un audio de 30 s sur une vidéo de 15 s avec `sync_mode: cut_off` produit une sortie de **15 s** (coupée à la vidéo) ; `silence` / `loop` / `bounce` / `remap` produisent une sortie d'environ 30 s.

### La sortie peut être plus longue que votre vidéo source

Chaque segment place sa prise audio dans sa propre fenêtre sur la timeline, et **chaque fenêtre s'étend pour correspondre à son audio** (selon le `sync_mode` ci-dessus). Lorsqu il y a des espaces entre les segments, ces fenêtres étendues décalent le reste de la timeline, donc la **sortie peut être plus longue que la vidéo source**. Par exemple, deux segments `[1s-3s]` et `[5s-8s]` sur une vidéo de 10 s peuvent produire une sortie d'environ 16,8 s : chaque fenêtre est étirée pour contenir toute sa prise audio. C est le comportement attendu, pas un bug.

**Pour conserver une sortie de la même longueur que la vidéo source**, recadrez chaque prise audio à sa fenêtre avec `audioInput.startTime`/`endTime`, afin que la prise ait exactement la même durée que la fenêtre et que celle-ci ne s'étende pas :

```json
{
  "startTime": 1,
  "endTime": 3,
  "audioInput": { "refId": "audio_1", "startTime": 0, "endTime": 2 }
}
```

Ici, la tranche audio de 2 secondes remplit exactement la fenêtre de 2 secondes. La timeline, et donc la durée de sortie, reste alignée avec la source.

## Exemples d utilisation de l'API

#### Segment unique avec un seul audio

```python
from sync import Sync
from sync.common import Audio, Video

sync = Sync()

response = sync.generations.create(
    input=[
        Video(url="https://assets.sync.so/docs/example-video.mp4"),
        Audio(url="https://assets.sync.so/docs/example-audio.wav", ref_id="audio_1"),
    ],
    model="lipsync-2",
    segments=[
        GenerationSegment(
            start_time=2,
            end_time=5,
            audio_input=SegmentAudioInput(ref_id="audio_1"),
        ),
    ],
)
```

```typescript
import { SyncClient } from "@sync.so/sdk";

const sync = new SyncClient();

const response = await sync.generations.create({
    input: [
        {
            type: "video",
            url: "https://assets.sync.so/docs/example-video.mp4"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/example-audio.wav",
            refId: "audio_1"
        },
    ],
    segments: [
        {
            startTime: 2,
            endTime: 5,
            audioInput: { refId: "audio_1" }
        },
    ],
    model: "lipsync-2"
});
```

#### Plusieurs segments avec un seul audio

### Plusieurs segments avec une seule entrée audio

```python
from sync import Sync
from sync.common import Audio, Video, TTS

sync = Sync()

response = sync.generations.create(
    input=[
        Video(url="https://assets.sync.so/docs/example-video.mp4"),
        Audio(url="https://assets.sync.so/docs/example-audio.wav", ref_id="audio_1")
    ],
    segments=[
        {
            "startTime": 2,
            "endTime": 5,
             "audioInput": {"refId": "audio_1", "startTime": 2, "endTime": 5}
        },
        {
            "startTime": 6,
            "endTime": 8,
            "audioInput": {"refId": "audio_1", "startTime": 6, "endTime": 8}
        }
    ],
    model="lipsync-2"
)
```

```typescript
import { SyncClient } from "@sync.so/sdk";

const sync = new SyncClient();

const response = await sync.generations.create({
    input: [
        {
            type: "video",
            url: "https://assets.sync.so/docs/example-video.mp4"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/example-audio.wav",
            refId: "audio_1"
        },
    ],
    segments: [
        {
            startTime: 2,
            endTime: 5,
            audioInput: { refId: "audio_1", startTime: 2, endTime: 5 }
        },
        {
            startTime: 6,
            endTime: 8,
            audioInput: { refId: "audio_1", startTime: 6, endTime: 8 }
        }

    ],
    model: "lipsync-2"
});
```

#### Plusieurs segments avec plusieurs audios

### Plusieurs segments avec une seule entrée audio

```python
from sync import Sync
from sync.common import Audio, Video, TTS

sync = Sync()

response = sync.generations.create(
    input=[
        Video(url="https://assets.sync.so/docs/example-video.mp4"),
        Audio(url="https://assets.sync.so/docs/example-audio.wav", ref_id="audio_1"),
        Audio(url="https://assets.sync.so/docs/example-audio.wav", ref_id="audio_2")
    ],
    segments=[
        {
            "startTime": 2,
            "endTime": 5,
             "audioInput": {"refId": "audio_1", "startTime": 2, "endTime": 5}
        },
        {
            "startTime": 6,
            "endTime": 8,
            "audioInput": {"refId": "audio_2", "startTime": 6, "endTime": 8}
        }
    ],
    model="lipsync-2"
)
```

```typescript
import { SyncClient } from "@sync.so/sdk";

const sync = new SyncClient();

const response = await sync.generations.create({
    input: [
        {
            type: "video",
            url: "https://assets.sync.so/docs/example-video.mp4"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/example-audio.wav",
            refId: "audio_1"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/example-audio.wav",
            refId: "audio_2"
        },
    ],
    segments: [
        {
            startTime: 2,
            endTime: 5,
            audioInput: { refId: "audio_1", startTime: 2, endTime: 5 }
        },
        {
            startTime: 6,
            endTime: 8,
            audioInput: { refId: "audio_2", startTime: 6, endTime: 8 }
        }

    ],
    model: "lipsync-2"
});
```

#### Segments avec options remplacées

### Segments avec options par segment

Utilisez `optionsOverride` pour appliquer des paramètres de génération différents à chaque segment.

```python
from sync import Sync
from sync.common import Audio, Video

sync = Sync()

response = sync.generations.create(
    input=[
        Video(url="https://assets.sync.so/docs/example-video.mp4"),
        Audio(url="https://assets.sync.so/docs/audio1.wav", ref_id="audio_1"),
        Audio(url="https://assets.sync.so/docs/audio2.wav", ref_id="audio_2")
    ],
    segments=[
        {
            "startTime": 0,
            "endTime": 5,
            "audioInput": {"refId": "audio_1"},
            "optionsOverride": {
                "sync_mode": "loop",
                "temperature": 0.3
            }
        },
        {
            "startTime": 5,
            "endTime": 10,
            "audioInput": {"refId": "audio_2"},
            "optionsOverride": {
                "sync_mode": "cut_off",
                "temperature": 0.7
            }
        }
    ],
    model="lipsync-2",
    options={"sync_mode": "bounce"}  # Default for segments without override
)
```

```typescript
import { SyncClient } from "@sync.so/sdk";

const sync = new SyncClient();

const response = await sync.generations.create({
    input: [
        {
            type: "video",
            url: "https://assets.sync.so/docs/example-video.mp4"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/audio1.wav",
            refId: "audio_1"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/audio2.wav",
            refId: "audio_2"
        }
    ],
    segments: [
        {
            startTime: 0,
            endTime: 5,
            audioInput: { refId: "audio_1" },
            optionsOverride: {
                sync_mode: "loop",
                temperature: 0.3
            }
        },
        {
            startTime: 5,
            endTime: 10,
            audioInput: { refId: "audio_2" },
            optionsOverride: {
                sync_mode: "cut_off",
                temperature: 0.7
            }
        }
    ],
    model: "lipsync-2",
    options: { sync_mode: "bounce" }  // Default for segments without override
});
```

#### Segments multi-locuteurs avec Active Speaker Detection

### Cibler différents locuteurs par segment

Utilisez `active_speaker_detection` dans `optionsOverride` pour cibler différents locuteurs dans chaque segment. C est utile lorsqu'une vidéo contient plusieurs personnes et que différents segments doivent appliquer le lip sync à différents locuteurs.

```python
from sync import Sync
from sync.common import Audio, Video

sync = Sync()

response = sync.generations.create(
    input=[
        Video(url="https://assets.sync.so/docs/two-speakers.mp4"),
        Audio(url="https://assets.sync.so/docs/speaker-a.wav", ref_id="audio_a"),
        Audio(url="https://assets.sync.so/docs/speaker-b.wav", ref_id="audio_b")
    ],
    segments=[
        {
            "startTime": 0,
            "endTime": 5,
            "audioInput": {"refId": "audio_a"},
            "optionsOverride": {
                "active_speaker_detection": {
                    "frame_number": 0,
                    "coordinates": [200, 300]  # Point on speaker A's face
                }
            }
        },
        {
            "startTime": 5,
            "endTime": 10,
            "audioInput": {"refId": "audio_b"},
            "optionsOverride": {
                "active_speaker_detection": {
                    "frame_number": 150,
                    "coordinates": [600, 300]  # Point on speaker B's face
                }
            }
        }
    ],
    model="lipsync-2"
)
```

```typescript
import { SyncClient } from "@sync.so/sdk";

const sync = new SyncClient();

const response = await sync.generations.create({
    input: [
        {
            type: "video",
            url: "https://assets.sync.so/docs/two-speakers.mp4"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/speaker-a.wav",
            refId: "audio_a"
        },
        {
            type: "audio",
            url: "https://assets.sync.so/docs/speaker-b.wav",
            refId: "audio_b"
        }
    ],
    segments: [
        {
            startTime: 0,
            endTime: 5,
            audioInput: { refId: "audio_a" },
            optionsOverride: {
                activeSpeakerDetection: {
                    frameNumber: 0,
                    coordinates: [200, 300]  // Point on speaker A's face
                }
            }
        },
        {
            startTime: 5,
            endTime: 10,
            audioInput: { refId: "audio_b" },
            optionsOverride: {
                activeSpeakerDetection: {
                    frameNumber: 150,
                    coordinates: [600, 300]  // Point on speaker B's face
                }
            }
        }
    ],
    model: "lipsync-2"
});
```

Consultez [sélection du locuteur - API](/developer-guides/speaker-selection) pour plus de détails sur les options `active_speaker_detection`.

## Bonnes pratiques

### Planifier vos segments

1. **Cartographiez votre timeline** : identifiez les segments vidéo et les besoins audio correspondants
2. **Préparez les fichiers audio** : assurez une bonne qualité audio et une durée adaptée
3. **Testez les limites des segments** : vérifiez que les transitions entre segments sont fluides

### Préparation audio

* Utilisez une qualité audio cohérente sur tous les segments et l'audio de la vidéo.
* Pour de meilleurs résultats, assurez un alignement temporel correct avec les segments vidéo. Si la durée du segment et la durée audio correspondante ne correspondent pas, utilisez [sync\_mode](/developer-guides/sync-mode) pour déterminer comment gérer l écart.

## Dépannage

### Erreurs courantes

#### "Multiple audio inputs are only allowed when using multi-segments"

Fournissez un tableau `segments` au niveau racine lorsque vous utilisez plusieurs entrées audio ou texte.

```python
# ❌ This will fail
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio1.wav"),  # Multiple audio without segments
        Audio(url="audio2.wav")
    ],
    model="lipsync-2"
)

# ✅ This will work
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio1.wav", ref_id="a1"),
        Audio(url="audio2.wav", ref_id="a2")
    ],
    segments=[
        {"start_time": 0, "end_time": 10, "audio_input": {"refId": "a1"}},
        {"start_time": 10, "end_time": 20, "audio_input": {"refId": "a2"}}
    ],
    model="lipsync-2"
)
```

#### "Unable to resolve audio input URL"

Assurez-vous que toutes les entrées audio ont des valeurs `url` ou `assetId` valides, et que les valeurs `refId` référencées existent dans vos entrées audio ou texte.

```python
# ❌ Missing refId reference
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")
    ],
    segments=[
        {"start_time": 0, "end_time": 10, "audio_input": {"refId": "missing"}}  # Wrong refId
    ],
    model="lipsync-2"
)

# ✅ Correct refId reference
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")
    ],
    segments=[
        {"start_time": 0, "end_time": 10, "audio_input": {"refId": "audio1"}}  # Correct refId
    ],
    model="lipsync-2"
)
```

#### "Segment at index X is missing a valid audioInput.refId"

Cette erreur se produit lorsque `audio_input` d'un segment n'a pas de `refId` ou que le `refId` est vide. Chaque segment doit référencer une entrée audio ou texte valide via son `refId`.

```python
# ❌ Missing refId in segment
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")
    ],
    segments=[
        {
            "start_time": 0, 
            "end_time": 10, 
            "audio_input": {}  # Missing refId
        }
    ],
    model="lipsync-2"
)

# ✅ Include refId in segment
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")
    ],
    segments=[
        {
            "start_time": 0, 
            "end_time": 10, 
            "audio_input": {"refId": "audio1"}  # Valid refId
        }
    ],
    model="lipsync-2"
)
```

#### "Segment at index X references unknown refId"

Cette erreur se produit lorsqu'un segment référence un `refId` qui n existe pas dans vos entrées audio ou texte. Assurez-vous que toutes les valeurs `refId` référencées correspondent exactement à celles définies dans vos entrées.

```python
# ❌ Segment references unknown refId
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")  # refId is "audio1"
    ],
    segments=[
        {
            "start_time": 0, 
            "end_time": 10, 
            "audio_input": {"refId": "nonexistent"}  # References unknown refId
        }
    ],
    model="lipsync-2"
)

# ✅ Segment references existing refId
response = sync.generations.create(
    input=[
        Video(url="video.mp4"),
        Audio(url="audio.wav", ref_id="audio1")  # refId is "audio1"
    ],
    segments=[
        {
            "start_time": 0, 
            "end_time": 10, 
            "audio_input": {"refId": "audio1"}  # References existing refId
        }
    ],
    model="lipsync-2"
)
```

#### "Invalid segment time range: startTime must be \<= endTime"

Le `startTime` de chaque segment doit être inférieur ou égal à son `endTime`. Les segments de durée nulle (où `startTime` est égal à `endTime`) sont autorisés pour des cas comme des points de recadrage de durée nulle.

```python
# ❌ Invalid: startTime greater than endTime
segments=[
    {
        "startTime": 10,
        "endTime": 5,  # endTime must be >= startTime
        "audioInput": {"refId": "audio1"}
    }
]

# ✅ Valid: startTime less than endTime
segments=[
    {
        "startTime": 0,
        "endTime": 10,
        "audioInput": {"refId": "audio1"}
    }
]

# ✅ Valid: startTime equals endTime (zero-length segment)
segments=[
    {
        "startTime": 5,
        "endTime": 5,
        "audioInput": {"refId": "audio1"}
    }
]
```

#### "Invalid segment frame range: startFrame must be \< endFrame"

Lorsque vous spécifiez les limites d'un segment avec des frames au lieu de secondes, `startFrame` doit être strictement inférieur à `endFrame`. Contrairement aux segments temporels qui autorisent des heures de début et de fin identiques, les segments basés sur des frames nécessitent au moins une frame de différence.

```python
# ❌ Invalid: startFrame greater than or equal to endFrame
segments=[
    {
        "startFrame": 100,
        "endFrame": 0,  # endFrame must be > startFrame
        "audioInput": {"refId": "audio1"}
    }
]

# ❌ Invalid: startFrame equals endFrame (not allowed for frames)
segments=[
    {
        "startFrame": 50,
        "endFrame": 50,  # endFrame must be > startFrame
        "audioInput": {"refId": "audio1"}
    }
]

# ✅ Valid: startFrame less than endFrame
segments=[
    {
        "startFrame": 0,
        "endFrame": 100,
        "audioInput": {"refId": "audio1"}
    }
]
```

#### "Invalid audioInput crop range"

Lorsque vous recadrez l'audio dans un segment, `startTime` et `endTime` doivent tous les deux être fournis, et `startTime` doit être inférieur ou égal à `endTime`.

```python
# ❌ Incomplete crop range
segments=[
    {
        "startTime": 0,
        "endTime": 10,
        "audioInput": {
            "refId": "audio1",
            "startTime": 5  # Missing endTime
        }
    }
]

# ❌ Invalid: startTime greater than endTime
segments=[
    {
        "startTime": 0,
        "endTime": 10,
        "audioInput": {
            "refId": "audio1",
            "startTime": 15,
            "endTime": 5  # endTime must be >= startTime
        }
    }
]

# ✅ Valid: complete crop range with startTime <= endTime
segments=[
    {
        "startTime": 0,
        "endTime": 10,
        "audioInput": {
            "refId": "audio1",
            "startTime": 5,
            "endTime": 15
        }
    }
]

# ✅ Valid: zero-duration crop point (startTime equals endTime)
segments=[
    {
        "startTime": 0,
        "endTime": 10,
        "audioInput": {
            "refId": "audio1",
            "startTime": 5,
            "endTime": 5
        }
    }
]
```

#### "When using multi-segments, please provide at least one audio or text input"

Assurez-vous d avoir au moins une entrée audio ou texte avec un `refId` valide lorsque vous utilisez des segments.

```python
# ❌ This will fail - no audio or text inputs
response = sync.generations.create(
    input=[
        Video(url="https://example.com/video.mp4")
    ],
    segments=[
        {"start_time": 0, "end_time": 10, "audio_input": {"refId": "missing"}}
    ],
    model="lipsync-2"
)

# ✅ This will work - includes text input
response = sync.generations.create(
    input=[
        Video(url="https://example.com/video.mp4"),
        TTS(
            provider={
                "name": "elevenlabs",
                "voiceId": "EXAVITQu4vr4xnSDxMaL",
                "script": "Hello world"
            },
            ref_id="text1"
        )
    ],
    segments=[
        {"start_time": 0, "end_time": 10, "audio_input": {"refId": "text1"}}
    ],
    model="lipsync-2"
)
```