> 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.

# Guía de segmentos

> Guía de lip sync multi-segmento. Sincroniza diferentes clips de audio con distintas partes de tu timeline de video en una sola llamada API.

## Resumen

Los segmentos te permiten sincronizar diferentes clips de audio con distintos rangos de tiempo dentro de un solo video en una sola llamada API. Esto habilita lip sync de múltiples hablantes al permitirte asignar diferentes entradas de audio a diferentes partes de tu video. Con segments, puedes:

* Aplicar lip sync de diferentes clips de audio a distintas partes de tu video
* Usar una porción específica de una entrada de audio para hacer lipsync de un segmento con timing preciso
* Usar tanto entradas de audio como de texto a voz para hacer lipsync de múltiples segmentos con distintos tipos de entrada en una sola generación

## Conceptos básicos

Para usar la funcionalidad de segments, debes proporcionar un arreglo de nivel superior [`segments`](/api-reference/api/generate-api/create#request.body.segments), con cada ítem definiendo un rango/segmento de tiempo de video, cada uno con su propia configuración de audio.

### Segment

Cada ítem de segmento acepta las siguientes propiedades:

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

Tiempo de inicio del segmento en segundos

---

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

Tiempo de fin del segmento en segundos

---

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

Configuración de audio con refId y recorte opcional

---

**`optionsOverride`** `SegmentOptionsOverride`

Sobrescribe las opciones de generación para este segmento específico

---

### audioInput

Cada segmento requiere exactamente un audioInput. audioInput acepta las siguientes propiedades:

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

ID de referencia de la entrada de audio/texto a voz que se usará para este segmento

---

**`startTime`** `double`

Tiempo de inicio opcional (en segundos) para recortar el audio referenciado. Cuando se especifica, también debe proporcionarse endTime

---

**`endTime`** `double`

Tiempo de fin opcional (en segundos) para recortar el audio referenciado. Cuando se especifica, también debe proporcionarse startTime

---

El audioInput especificado se usará para hacer lipsync del segmento de video entre startTime y endTime.

### optionsOverride

Cada segmento puede sobrescribir opcionalmente las opciones de generación de nivel superior. Esto te permite aplicar distintos ajustes por segmento, incluyendo apuntar a diferentes hablantes.

Para videos de múltiples hablantes, usa `active_speaker_detection` para apuntar a una persona diferente en cada segmento. Consulta [selección de hablante -- API](/developer-guides/speaker-selection) para ver todos los detalles sobre opciones de selección de hablante.

**`sync_mode`** `SyncMode`

Sobrescribe el [modo de sincronización](/developer-guides/sync-mode) para este segmento

---

**`temperature`** `double`

Sobrescribe la expresividad (0-1) para este segmento

---

**`occlusion_detection_enabled`** `boolean`

Sobrescribe la detección de oclusión para este segmento

---

**`active_speaker_detection`** `ActiveSpeaker`

Sobrescribe [active speaker detection](/developer-guides/speaker-selection) para este segmento. Útil cuando diferentes segmentos tienen diferentes hablantes. Acepta las mismas opciones que `active_speaker_detection` de nivel superior:

* `auto_detect`: detecta automáticamente y apunta al hablante activo
* `v3`: usa ASD v3
* `frame_number` + `coordinates`: especifica manualmente el hablante por frame y punto
* `bounding_boxes`: proporciona bounding boxes por frame si tienes datos de detección
* `bounding_boxes_url`: apunta a un archivo JSON externo que contiene bounding boxes (recomendado para videos largos para evitar payloads grandes)

---

## Cómo funciona el timing y la duración de segmentos

Cuando el audio de un segmento y su ventana de video (`endTime` − `startTime`) tienen longitudes distintas, [`sync_mode`](/compatibility-and-tips/media-content-tips#sync-mode-options) decide cómo se resuelve el desajuste, y el modo que elijas cambia la **duración efectiva** de ese segmento en la salida:

| `sync_mode` | audio más largo que la ventana                                | audio más corto que la ventana                                 |
| ----------- | ------------------------------------------------------------- | -------------------------------------------------------------- |
| `bounce`    | el video rebota (avance y luego reversa) para cubrir el audio | la ventana se recorta al audio                                 |
| `loop`      | el video se repite para cubrir el audio                       | la ventana se recorta al audio                                 |
| `cut_off`   | la salida se recorta a la pista **más corta** (la ventana)    | la ventana se recorta al audio                                 |
| `silence`   | reproduce el audio completo (video rellenado para cubrirlo)   | se reproduce la ventana completa; audio rellenado con silencio |
| `remap`     | el tiempo del video se estira para coincidir con el audio     | la ventana se recorta al audio                                 |

En resumen, la longitud efectiva de un segmento es `cut_off` → min(audio, ventana), `silence` → max(audio, ventana), y `loop` / `bounce` / `remap` → longitud del audio.

> **Note**
>
> Las mismas reglas aplican a una generación de segmento único (sin `segments`), donde la "ventana" es todo el video. Un audio de 30 s en un video de 15 s con `sync_mode: cut_off` produce una salida de **15 s** (recortada al video); `silence` / `loop` / `bounce` / `remap` producen una salida de \~30 s.

### La salida puede ser más larga que tu video fuente

Cada segmento coloca su toma de audio en su propia ventana en la línea de tiempo, y **cada ventana se expande para ajustarse a su audio** (según el `sync_mode` anterior). Cuando hay huecos entre segmentos, esas ventanas expandidas desplazan el resto de la línea de tiempo, por lo que la **salida puede ser más larga que el video fuente**. Por ejemplo, dos segmentos `[1s-3s]` y `[5s-8s]` en un video de 10 s pueden producir una salida de \~16.8 s: cada ventana se estira para ajustarse a su toma de audio completa. Este comportamiento es esperado, no es un bug.

**Para mantener la salida con la misma longitud que el video fuente**, recorta cada toma de audio a su ventana con `audioInput.startTime`/`endTime`, de forma que la toma tenga exactamente la misma duración que la ventana y la ventana no se expanda:

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

Aquí, el corte de audio de 2 segundos llena exactamente la ventana de 2 segundos, por lo que la línea de tiempo, y la duración de salida, se mantiene alineada con la fuente.

## Ejemplos de uso de API

#### Un segmento con un 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"
});
```

#### Múltiples segmentos con un audio

### Múltiples segmentos con una sola entrada de 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"
});
```

#### Múltiples segmentos con múltiples audios

### Múltiples segmentos con múltiples audios

```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 con options override

### Segmentos con opciones por segmento

Usa `optionsOverride` para aplicar distintos ajustes de generación a cada segmento.

```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-hablante con active speaker detection

### Apunta a distintos hablantes por segmento

Usa `active_speaker_detection` en `optionsOverride` para apuntar a distintos hablantes en cada segmento. Esto es útil cuando un video tiene varias personas y diferentes segmentos deben hacer lipsync con diferentes hablantes.

```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"
});
```

Consulta [selección de hablante -- API](/developer-guides/speaker-selection) para detalles sobre opciones de `active_speaker_detection`.

## Mejores prácticas

### Planifica tus segmentos

1. **Mapea tu timeline**: identifica segmentos de video y necesidades de audio correspondientes
2. **Prepara archivos de audio**: garantiza calidad de audio y duración apropiada
3. **Prueba límites de segmento**: verifica transiciones suaves entre segmentos

### Preparación de audio

* Usa calidad de audio consistente en todos los segmentos y en el audio del video.
* Para mejores resultados, asegúrate de alinear correctamente el timing con los segmentos de video. Si la duración del segmento y la duración del audio correspondiente no coinciden, usa [sync\_mode](/developer-guides/sync-mode) para decidir cómo manejar el desajuste.

## Solución de problemas

### Errores comunes

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

Proporciona un arreglo `segments` de nivel superior cuando uses múltiples entradas de audio o texto.

```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"

Asegúrate de que todas las entradas de audio tengan valores `url` o `assetId` válidos y de que los valores `refId` referenciados existan en tus entradas de audio o texto.

```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"

Este error ocurre cuando al `audio_input` de un segmento le falta `refId` o `refId` está vacío. Cada segmento debe referenciar una entrada de audio o texto válida mediante su `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"

Este error ocurre cuando un segmento referencia un `refId` que no existe en tus entradas de audio o texto. Asegúrate de que todos los valores `refId` referenciados coincidan exactamente con los definidos en tus entradas.

```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"

El `startTime` de cada segmento debe ser menor o igual que su `endTime`. Se permiten segmentos de duración cero (cuando `startTime` es igual a `endTime`) para casos de uso como puntos de recorte de duración cero.

```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"

Cuando especificas límites de segmento usando frames en lugar de segundos, `startFrame` debe ser estrictamente menor que `endFrame`. A diferencia de los segmentos basados en tiempo, que permiten tiempos de inicio y fin iguales, los segmentos basados en frames requieren al menos un frame de diferencia.

```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"

Cuando recortas audio dentro de un segmento, deben proporcionarse tanto `startTime` como `endTime`, y `startTime` debe ser menor o igual que `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"

Asegúrate de tener al menos una entrada de audio o texto con un `refId` válido al usar 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"
)
```