# Come creare sottotitoli SRT da un video con un'API

> Manda il video a POST /transcribe impostando output_format su srt e word_timestamps su false, aspetta che il lavoro finisca e salva il testo restituito in un file .srt. Se vuoi i sottotitoli tradotti in un’altra lingua, aggiungi translate_to. In questa guida vediamo come fare la richiesta esatta, cosa c’è dentro l’SRT, come creare righe ordinate partendo dai tempi delle singole parole, come passare a WebVTT e come incorporare i sottotitoli nel video.

Ultimo aggiornamento: 2026-10-18 · HTML: https://console.kolwrite.com/it/guides/srt-subtitles-api

## La richiesta

Due chiamate: avviare il lavoro e poi interrogarlo. Il `result` di un lavoro `srt` completato è una stringa, non JSON. Questa versione richiede solo curl e jq:

```bash
# 1. Start the job. "word_timestamps": false gives one cue per segment.
JOB=$(curl -s https://app.kolwrite.com/transcribe \
  -H "x-api-key: $KOLWRITE_API_KEY" -H "Content-Type: application/json" \
  -d '{"audio_url": "https://example.com/talk.mp3", "model": "oracle", "output_format": "srt", "word_timestamps": false}' \
  | jq -r .jobId)

# 2. Poll until it is done and save the result string as a .srt file.
while true; do
  REPLY=$(curl -s "https://app.kolwrite.com/transcribe/$JOB" -H "x-api-key: $KOLWRITE_API_KEY")
  STATUS=$(echo "$REPLY" | jq -r .status)
  if [ "$STATUS" = "COMPLETED" ]; then echo "$REPLY" | jq -r .result > talk.srt; break; fi
  if [ "$STATUS" = "FAILED" ]; then echo "$REPLY" | jq -r .error; break; fi
  sleep 5
done
```

Puoi usare direttamente un file video, perché l'API ne legge la traccia audio. Se il file è in locale, passa prima da `POST /upload` (massimo 100 MiB); per i video lunghi estrai prima l'audio con ffmpeg. Nella [guida al montaggio video](https://console.kolwrite.com/it/guides/video-editing-with-ai) trovi una funzione di supporto che fa entrambe le cose in Python.

## Cosa c’è dentro l’SRT

Impostando `"word_timestamps": false` si ottiene una riga per ogni segmento, come avviene nella maggior parte dei file di sottotitoli:

```text
1
00:00:01,000 --> 00:00:03,750
Hello everyone and welcome to the show.

2
00:00:05,000 --> 00:00:07,750
Today we talk about editing video from a transcript.
```

Se lasci attivi i timestamp per parola (l'impostazione predefinita), l'API genera invece una riga per ogni singola parola. Ogni riga ripete l'intero testo del segmento racchiudendo la parola pronunciata in quel momento in un tag `<font>` giallo. Serve a evidenziare il testo mentre si legge, quindi non è un sottotitolo tradizionale:

```text
1
00:00:01,000 --> 00:00:01,350
<font color="yellow">Hello</font> everyone and welcome to the show.

2
00:00:01,400 --> 00:00:01,750
Hello <font color="yellow">everyone</font> and welcome to the show.
```

Se ti servono sottotitoli standard, passa `"word_timestamps": false` oppure componi tu le righe partendo dalle parole nel JSON, come vediamo qui sotto.

## Comporre righe su misura dai timestamp delle parole

Richiedi `output_format: "json"` e raggruppa le parole via codice: fissa un tetto di 42 caratteri e 6 secondi per riga, andando a capo dopo le pause. In questo modo hai il pieno controllo sulla lunghezza delle righe, un aspetto molto utile quando imprimi i sottotitoli direttamente nel video.

srt_tools.py

```python
# srt_tools.py — neat subtitle cues from word timings
def srt_time(seconds):
    ms = round(seconds * 1000)
    h, ms = divmod(ms, 3_600_000)
    m, ms = divmod(ms, 60_000)
    s, ms = divmod(ms, 1000)
    return f"{h:02}:{m:02}:{s:02},{ms:03}"


def cues_from_words(words, max_chars=42, max_seconds=6.0, max_gap=0.8):
    """Group timed words into subtitle cues: (start, end, text)."""
    cues, line = [], []
    for word in words:
        text = word["word"].strip()
        if not text:
            continue
        if line:
            length = sum(len(w["word"]) + 1 for w in line) + len(text)
            if (length > max_chars
                    or word["end"] - line[0]["start"] > max_seconds
                    or word["start"] - line[-1]["end"] > max_gap):
                cues.append(line)
                line = []
        line.append({"start": word["start"], "end": word["end"], "word": text})
    if line:
        cues.append(line)
    return [(c[0]["start"], c[-1]["end"], " ".join(w["word"] for w in c)) for c in cues]


def cues_from_result(result):
    """Cues for a whole JSON result; a segment without word times becomes one cue."""
    cues = []
    for segment in result["segments"]:
        if segment.get("words"):
            cues += cues_from_words(segment["words"])
        elif segment["text"].strip():
            cues.append((segment["start"], segment["end"], segment["text"].strip()))
    return cues


def write_srt(cues, path):
    with open(path, "w", encoding="utf-8") as out:
        for number, (start, end, text) in enumerate(cues, 1):
            out.write(f"{number}\n{srt_time(start)} --> {srt_time(end)}\n{text}\n\n")
```

La funzione `cues_from_result(result)` restituisce delle tuple `(start, end, text)` per l'intero risultato e, se un modello non fornisce i tempi delle singole parole, usa come ripiego i tempi del segmento. Poi `write_srt(cues, "talk.srt")` scrive il file vero e proprio.

## Sottotitoli tradotti in un'altra lingua

Aggiungi il parametro `translate_to` con il codice della lingua desiderata e scegli un modello Oracle (`oracle_mini` è il più economico tra quelli che traducono). Il testo ti arriverà già tradotto; ricorda di lasciare `word_timestamps` su false per avere un segmento intero su ogni riga.

```json
{
  "audio_url": "https://example.com/lecture-he.mp4",
  "model": "oracle_mini",
  "language": "he",
  "translate_to": "en",
  "output_format": "srt",
  "word_timestamps": false
}
```

Se devi tradurre un video in più lingue, avvia un lavoro separato per ciascuna lingua. Prima di pubblicare, però, rileggi sempre nomi, numeri e termini specifici: considera la traduzione automatica come una prima bozza.

## WebVTT, ASS e altri formati

L’API restituisce soltanto i formati `json`, `txt` o `srt`. Se ti serve un file WebVTT per un tag `<video>` in HTML5, puoi convertire l’SRT con ffmpeg:

```bash
ffmpeg -i video.srt video.vtt
```

Con lo stesso comando ffmpeg puoi convertire quasi tutti i formati di sottotitoli: ti basta cambiare l'estensione del file di output.

## Incorporare o allegare i sottotitoli al video

Incorporati nell’immagine:

```bash
ffmpeg -i edited.mp4 -vf "subtitles=edited.srt" -c:a copy burned.mp4
```

Per aggiungerli come traccia separata dentro un file MP4 (così chi guarda può attivarli o disattivarli):

```bash
ffmpeg -i edited.mp4 -i edited.srt -c copy -c:s mov_text -metadata:s:s:0 language=eng soft.mp4
```

YouTube Studio e la maggior parte dei lettori e dei programmi di montaggio accettano direttamente il file `.srt`.

## Sottotitoli in ebraico e arabo

- L’API restituisce semplice testo Unicode. L’impaginazione da destra a sinistra dipende poi dal lettore video o dal renderer dei sottotitoli di ffmpeg, che gestisce senza problemi l’ebraico e l’arabo se il font usato contiene quelle lettere.
- Specifica un font che supporti quell'alfabeto e fai una prova su un singolo fotogramma prima di elaborare tutto il video. Nei nostri test, ad esempio, con Arial l'ebraico si vedeva bene, mentre in una parola araba mancava un glifo. Per l'arabo conviene quindi scegliere un altro font.

```bash
ffmpeg -i video.mp4 -vf "subtitles=video.he.srt:force_style='FontName=Arial,FontSize=24'" -c:a copy burned.mp4
```

- Se una riga finisce con un segno di punteggiatura o con caratteri latini (come un marchio o un numero), i lettori che non gestiscono bene il testo bidirezionale potrebbero mostrare gli elementi in un ordine strano. Fai sempre qualche prova sui lettori che usa il tuo pubblico.

## Quanto costa

| Lavoro | Modello | Costo |
| --- | --- | --- |
| Lezione di 45 minuti, sottotitoli | `oracle` | 1,08 US$ |
| La stessa lezione, sottotitoli tradotti | `oracle_mini` | 0,72 US$ |
| Un'ora di audio pulito, sottotitoli | `base` | 0,48 US$ |

Paghi al secondo, senza costi minimi. Trovi le tariffe in [/llms/pricing.md](https://console.kolwrite.com/llms/pricing.md).

## Domande e risposte

### Come ottengo un file SRT da un video?

Chiama `POST /transcribe` passando l'URL del video, `output_format: "srt"` e `word_timestamps: false`. Interroga lo stato del lavoro e, una volta pronto, salva la stringa `result` in un file `.srt`.

### L’API può restituire WebVTT?

No, restituisce solo `json`, `txt` o `srt`. Puoi però convertire l'SRT in WebVTT con il comando `ffmpeg -i video.srt video.vtt`.

### Perché il mio SRT ha una riga per ogni parola?

Perché i timestamp per parola sono attivi per impostazione predefinita: nell’SRT trovi quindi una riga per ogni parola, con il termine corrente evidenziato. Passa `word_timestamps: false` per avere una riga per ogni segmento, oppure componi tu le righe partendo dal JSON.

### Posso ottenere sottotitoli in un'altra lingua?

Sì. Ti basta aggiungere `translate_to` con il codice della lingua e scegliere un modello Oracle. Il testo delle righe ti arriverà già tradotto.

### Che differenza c'è tra sottotitoli normali e sottotitoli per non udenti?

I sottotitoli normali trascrivono o traducono i dialoghi per chi sente l’audio, mentre quelli per non udenti descrivono anche i suoni. L’API genera il testo del parlato con i relativi tempi; le indicazioni sui suoni puoi aggiungerle tu dove servono.

## Pagine correlate

- [Montare video con agenti IA](https://console.kolwrite.com/it/guides/video-editing-with-ai)
- [API per i timestamp di ogni parola](https://console.kolwrite.com/it/guides/word-timestamps-api)
- [Sottotitoli per podcast e YouTube](https://console.kolwrite.com/it/guides/podcast-youtube-captions)
- [Media, podcast e sottotitoli](https://console.kolwrite.com/it/use-cases/media)
- [Università e studenti](https://console.kolwrite.com/it/use-cases/education)
- [Documentazione dell’API](https://console.kolwrite.com/it/public_api_docs)

---
Ottieni una chiave API: https://console.kolwrite.com/auth?lang=it · Documentazione dell’API: https://console.kolwrite.com/it/public_api_docs · llms.txt: https://console.kolwrite.com/llms.txt
