SRT-Untertitel aus einem Video per API erstellen
Schicken Sie Ihr Video mit output_format srt und word_timestamps false an POST /transcribe. Sobald der Auftrag fertig ist, speichern Sie den zurückgegebenen Text einfach als .srt-Datei. Über den Parameter translate_to bekommen Sie direkt übersetzte Untertitel. Hier sehen Sie den genauen API-Aufruf, den Aufbau der SRT-Datei, wie Sie aus Wortzeiten saubere Zeilenumbrüche bauen, WebVTT erzeugen und Untertitel ins Video einbrennen.
Die Anfrage
Zwei Aufrufe: den Auftrag starten, dann abfragen. Das result eines fertigen srt-Auftrags ist ein String, kein JSON. Diese Variante braucht nur curl und jq:
# 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
Sie können direkt Videodateien übergeben, die API liest daraus die Tonspur. Lokale Dateien bis 100 MiB laden Sie zuerst über POST /upload hoch; bei längeren Videos ziehen Sie vorher mit ffmpeg das Audio heraus. Das Hilfsskript aus der Anleitung zum Videoschnitt übernimmt beides in Python.
Was in der SRT-Datei steht
Mit "word_timestamps": false bekommen Sie pro Abschnitt einen Eintrag, wie bei normalen Untertiteln üblich:
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.
Standardmäßig sind die Wortzeitstempel aktiv. Dann erzeugt die API für jedes einzelne Wort einen eigenen Eintrag: Der gesamte Abschnittstext wird jeweils wiederholt und das gerade gesprochene Wort mit einem gelben <font>-Tag hervorgehoben. Das eignet sich zum Mitlesen, nicht als klassischer Untertitel:
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.
Für normale Untertitel setzen Sie entweder "word_timestamps": false oder Sie stellen sich die Zeilen wie im nächsten Schritt gezeigt selbst aus den JSON-Wörtern zusammen.
Eigene Zeilen aus den Wortzeiten bauen
Fragen Sie output_format: "json" an und fassen Sie die Wörter selbst zu Zeilen zusammen: maximal 42 Zeichen, höchstens 6 Sekunden Anzeigedauer und ein Umbruch nach Sprechpausen. So behalten Sie die volle Kontrolle über die Zeilenlänge, was vor allem bei fest eingebrannten Untertiteln wichtig ist.
srt_tools.py
# 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")
cues_from_result(result) gibt für das gesamte Ergebnis (start, end, text)-Tupel zurück. Hat ein Modell keine Wortzeiten geliefert, nutzt die Funktion automatisch die Zeiten der Abschnitte. write_srt(cues, "talk.srt") speichert das Ganze als Datei.
Untertitel übersetzen
Übergeben Sie translate_to mit dem gewünschten Sprachcode und wählen Sie ein Oracle-Modell (oracle_mini ist die günstigste Option mit Übersetzung). Der Text wird direkt in der Zielsprache ausgegeben. Belassen Sie word_timestamps auf false, damit jeder Abschnitt eine Zeile bildet.
{
"audio_url": "https://example.com/lecture-he.mp4",
"model": "oracle_mini",
"language": "he",
"translate_to": "en",
"output_format": "srt",
"word_timestamps": false
}
Wenn Sie Untertitel in mehreren Sprachen brauchen, starten Sie pro Zielsprache einen eigenen Auftrag. Sehen Sie sich Namen, Zahlen und Fachbegriffe vor dem Veröffentlichen noch einmal an, denn eine maschinelle Übersetzung ist immer nur ein Entwurf.
WebVTT, ASS und andere Formate
Die API gibt nur json, txt oder srt aus. Wenn Sie WebVTT für eine HTML5-<video>-Spur brauchen, wandeln Sie SRT einfach mit ffmpeg um:
ffmpeg -i video.srt video.vtt
Auf dieselbe Weise konvertiert ffmpeg auch zwischen den meisten anderen Untertitelformaten. Ändern Sie einfach die Dateiendung der Ausgabedatei.
Untertitel einbrennen oder als Spur einbetten
Fest ins Videobild einbrennen:
ffmpeg -i edited.mp4 -vf "subtitles=edited.srt" -c:a copy burned.mp4
Als eigene Untertitelspur in einem MP4 (lässt sich im Player abschalten):
ffmpeg -i edited.mp4 -i edited.srt -c copy -c:s mov_text -metadata:s:s:0 language=eng soft.mp4
YouTube Studio sowie die meisten Videoplayer und Schnittprogramme nehmen .srt-Dateien direkt an.
Hebräische und arabische Untertitel
- Die API gibt regulären Unicode-Text zurück. Dass die Schrift von rechts nach links läuft, regelt der Videoplayer oder der Untertitel-Renderer von ffmpeg. Beides klappt mit Hebräisch und Arabisch problemlos, solange die gewählte Schriftart die nötigen Zeichen enthält.
- Wählen Sie eine Schriftart, die das jeweilige Schriftsystem unterstützt, und prüfen Sie das Ergebnis an einem einzelnen Standbild, bevor Sie das komplette Video durchlaufen lassen. In unseren Tests funktionierte Hebräisch mit Arial fehlerfrei, während bei einem arabischen Wort in derselben Schrift ein Zeichen fehlte. Für Arabisch sollten Sie also eine andere Schrift wählen.
ffmpeg -i video.mp4 -vf "subtitles=video.he.srt:force_style='FontName=Arial,FontSize=24'" -c:a copy burned.mp4
- Endet eine Zeile mit einem Satzzeichen oder einem lateinischen Wort (etwa einer Marke oder Zahl), kann die Reihenfolge in Playern ohne Unterstützung für bidirektionalen Text durcheinandergeraten. Testen Sie deshalb die Player, die Ihr Publikum nutzt.
Kosten
| Aufgabe | Modell | Kosten |
|---|---|---|
| 45-minütige Vorlesung, Untertitel | oracle | 1,08 US$ |
| Dieselbe Vorlesung, übersetzte Untertitel | oracle_mini | 0,72 US$ |
| Eine Stunde klares Audio, Untertitel | base | 0,48 US$ |
Abgerechnet wird sekundengenau ohne Mindestumsatz. Die Preise finden Sie unter /llms/pricing.md.
Fragen und Antworten
Wie erstelle ich aus einem Video eine SRT-Datei?
Senden Sie die Video-URL zusammen mit output_format: "srt" und word_timestamps: false an POST /transcribe. Fragen Sie den Status ab, bis der Auftrag fertig ist, und speichern Sie den String aus result als .srt-Datei.
Gibt die API auch WebVTT aus?
Nein, ausgegeben werden json, txt oder srt. SRT lässt sich aber mit ffmpeg -i video.srt video.vtt direkt in WebVTT umwandeln.
Warum enthält meine SRT-Datei für jedes Wort einen eigenen Eintrag?
Wortzeitstempel sind standardmäßig eingeschaltet. Dadurch enthält die SRT-Datei für jedes Wort eine eigene Zeile, in der das jeweils aktuelle Wort hervorgehoben ist. Übergeben Sie word_timestamps: false, um eine Zeile pro Abschnitt zu erhalten, oder stellen Sie sich die Zeilen selbst aus dem JSON zusammen.
Kann ich mir Untertitel direkt übersetzen lassen?
Ja. Geben Sie bei translate_to den gewünschten Sprachcode an und verwenden Sie eines der Oracle-Modelle. Die Untertitel werden dann direkt in der Zielsprache ausgegeben.
Was unterscheidet normale Untertitel von Untertiteln für Hörgeschädigte?
Normale Untertitel transkribieren oder übersetzen das Gesprochene für Zuschauer, die den Ton hören. Untertitel für Hörgeschädigte beschreiben zusätzlich Geräusche. Die API liefert Ihnen den gesprochenen Text samt Zeitangaben; Beschreibungen von Geräuschen ergänzen Sie dort selbst, wo Sie sie brauchen.