# Videos mit Claude, Codex oder anderen KI-Agenten schneiden

> Wenn der Agent ein Transkript mit den genauen Start- und Endzeiten jedes Wortes bekommt, kann er entscheiden, welche Sätze im Video bleiben. Ein kurzes Skript schneidet das Material dann anhand dieser Zeiten mit ffmpeg. Die KolWrite-API erstellt solche Transkripte für Audio und Video in 100 Sprachen. Aus denselben Wortdaten entstehen am Ende auch die Untertitel für das geschnittene Video.

Zuletzt aktualisiert: 2026-10-18 · HTML: https://console.kolwrite.com/de/guides/video-editing-with-ai

## Was der Agent kann und was nicht

Da im Transkript nur das Gesprochene steht, schneidet der Agent rein nach Inhalt. Er streicht Versprecher, Füllwörter, doppelte Takes, Abschweifungen oder lange Pausen und sucht die passenden Sätze für kurze Clips heraus. Das Bild selbst sieht er nicht. Welche Kameraeinstellung passt, entscheiden weiterhin Sie, es sei denn, Sie übergeben ihm zusätzlich Einzelbilder zur Ansicht.

Wenn Ihr Agent Befehle ausführen darf (wie Claude Code, Codex CLI oder ein Cursor-Agent), ruft er die API direkt auf und startet ffmpeg selbst. Ein reines Chatfenster ohne Codeausführung kann Ihnen immerhin die nötigen Skripte dafür schreiben.

## Der Prompt für Ihren Agenten

Mit diesem Prompt arbeitet der Agent über Abschnittsnummern statt selbst geschriebener Zeitstempel, damit er keine Zeiten erfindet. Der Prompt verweist direkt auf die maschinenlesbare Dokumentation der API.

```text
Edit talk.mp4 down to the parts worth keeping, using the KolWrite API for the transcript.
Read https://console.kolwrite.com/agent-instructions.md first. The key is in KOLWRITE_API_KEY.
1. Extract the audio with ffmpeg and transcribe it with model "oracle", output_format "json", word_timestamps true.
2. Print the segments as numbered lines: S<number> [start-end] text.
3. Choose the segments to keep (remove false starts, filler, repeated takes and tangents) and write
   their numbers to keep.json as {"keep": [0, 2, 4]}. Do not invent timestamps; use segment numbers only.
4. Cut the video from those segments' word times with ffmpeg and write edited.mp4.
5. Make edited.srt for the edited video and attach it as a subtitle track.
Show me the list of removed segments before you cut anything.
```

Wenn der Agent die API in jeder Sitzung direkt kennen soll, übernehmen Sie einfach die Regel aus der [Tool-Anleitung](https://console.kolwrite.com/de/guides/transcription-tool-for-ai-agents) in Ihre `AGENTS.md` oder `CLAUDE.md`.

## Schritt 1: Audio extrahieren und transkribieren

Über einen signierten Upload lassen sich Dateien bis 100 MiB hochladen. Ziehen Sie bei längeren Videos also am besten vorher die Tonspur heraus. Eine Stunde Mono-Audio mit 48 kbit/s hat nur rund 21 MB.

```bash
ffmpeg -i talk.mp4 -vn -ac 1 -ar 16000 -b:a 48k talk.mp3
```

 Dieses kleine Hilfsskript lädt eine lokale Datei hoch, startet den Auftrag und wartet auf das fertige Transkript:

kolwrite.py

```python
# kolwrite.py — three small functions around the KolWrite REST API
import os, time, requests

API = "https://app.kolwrite.com"
HEADERS = {"x-api-key": os.environ["KOLWRITE_API_KEY"]}


def upload(path):
    """Upload a local file (up to 100 MiB) and return a URL the API can read."""
    name = os.path.basename(path)
    form = requests.post(f"{API}/upload", headers=HEADERS, json={"filename": name}, timeout=30)
    form.raise_for_status()
    form = form.json()
    with open(path, "rb") as media:
        # No x-api-key on this request: it goes to the storage address.
        sent = requests.post(form["uploadUrl"], data=form["uploadFields"],
                             files={"file": (name, media)}, timeout=600)
    sent.raise_for_status()
    return form["fileUrl"]


def transcribe(audio_url, timeout_s=3600, **options):
    """Start a job, wait for it, return the result: a dict for json, a string for srt and txt."""
    body = {"audio_url": audio_url, "model": "oracle", **options}
    job = requests.post(f"{API}/transcribe", headers=HEADERS, json=body, timeout=30)
    job.raise_for_status()
    job_id = job.json()["jobId"]
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        time.sleep(5)
        reply = requests.get(f"{API}/transcribe/{job_id}", headers=HEADERS, timeout=30)
        reply.raise_for_status()
        reply = reply.json()
        if reply["status"] == "COMPLETED":
            return reply["result"]
        if reply["status"] == "FAILED":
            raise RuntimeError(reply.get("error", "transcription failed"))
    raise TimeoutError(f"job {job_id} did not finish in {timeout_s} seconds")
```

Das Skript `edit.py` unten fragt JSON mit Wortzeitstempeln an (beides ist ohnehin Standard, steht hier aber zur besseren Lesbarkeit im Code). Zurück kommt die Liste `segments[]`, in der jeder Abschnitt `start`, `end`, `text` sowie optional `speaker` und `words[]` enthält:

Die Antwort (gekürzt):

```json
{
  "jobId": "34c63d45-4cb5-473b-bc60-25c175e69c57",
  "status": "COMPLETED",
  "result": {
    "language": "en",
    "segments": [
      {
        "start": 1.0,
        "end": 3.75,
        "text": "Hello everyone and welcome to the show.",
        "speaker": "Speaker 1",
        "words": [
          { "start": 1.0, "end": 1.35, "word": "Hello" },
          { "start": 1.4, "end": 1.75, "word": "everyone" }
        ]
      }
    ]
  }
}
```

## Schritt 2: Den Agenten auswählen lassen, was bleibt

Geben Sie das Transkript als einfach nummerierte Zeilen aus. Der Agent liest dann nur diesen Text, was deutlich weniger Tokens verbraucht als das komplette JSON mit jedem einzelnen Wort.

view.py

```python
# view.py — print the transcript the way an agent can read it
import json, sys

result = json.load(open(sys.argv[1]))
for number, segment in enumerate(result["segments"]):
    who = f'{segment["speaker"]}: ' if segment.get("speaker") else ""
    print(f'S{number} [{segment["start"]:.1f}-{segment["end"]:.1f}] {who}{segment["text"]}')
```

Der Agent gibt als Antwort nur die Nummern der Abschnitte zurück:

keep.json

```json
{"keep": [0, 2, 4]}
```

Lassen Sie sich vom Agenten vor dem Schnitt auflisten, welche Stellen er warum streicht. Man kann einen Schnitt zwar schnell wiederholen, aber ein kurzer Blick auf die Liste spart viel Zeit gegenüber dem Anschauen des gesamten Videos.

## Schritt 3: Mit ffmpeg nach Wortzeiten schneiden

Anhand der Abschnittsnummern holt sich das Skript die Startzeit des ersten und die Endzeit des letzten Wortes. Es gibt ein paar Hundertstelsekunden Puffer dazu, fasst direkt aufeinanderfolgende Abschnitte zusammen und kodiert das Video in einem Durchgang neu, damit die Schnitte bildgenau sitzen. Gleichzeitig rechnet es die Wortzeiten für die Untertitel auf die neue Zeitleiste um.

cut.py

```python
# cut.py — ranges from segment numbers, one ffmpeg pass, word times for the new timeline
import subprocess

PAD = 0.08  # seconds of room kept around every range


def ranges_from_ids(segments, keep_ids, pad=PAD):
    """Turn the segment numbers the agent chose into [start, end] ranges in seconds."""
    ranges = []
    for i in sorted(set(keep_ids)):
        segment = segments[i]
        words = segment.get("words") or []
        start = words[0]["start"] if words else segment["start"]
        end = words[-1]["end"] if words else segment["end"]
        start, end = max(0.0, start - pad), end + pad
        if ranges and start <= ranges[-1][1]:
            ranges[-1][1] = max(ranges[-1][1], end)
        else:
            ranges.append([start, end])
    return ranges


def cut(video, ranges, out):
    """Re-encode the kept ranges into one file (frame accurate)."""
    parts = []
    for i, (start, end) in enumerate(ranges):
        parts.append(f"[0:v]trim=start={start:.3f}:end={end:.3f},setpts=PTS-STARTPTS[v{i}]")
        parts.append(f"[0:a]atrim=start={start:.3f}:end={end:.3f},asetpts=PTS-STARTPTS[a{i}]")
    joined = "".join(f"[v{i}][a{i}]" for i in range(len(ranges)))
    parts.append(f"{joined}concat=n={len(ranges)}:v=1:a=1[v][a]")
    subprocess.run(["ffmpeg", "-y", "-hide_banner", "-loglevel", "error", "-i", video,
                    "-filter_complex", ";".join(parts), "-map", "[v]", "-map", "[a]", out], check=True)


def remap(words, ranges):
    """Move word times onto the edited timeline, so subtitles match the cut video."""
    moved, offset = [], 0.0
    for start, end in ranges:
        for word in words:
            if word["start"] >= start and word["end"] <= end:
                moved.append({**word, "start": word["start"] - start + offset,
                              "end": word["end"] - start + offset})
        offset += end - start
    return moved
```

edit.py

```python
# edit.py — the whole pipeline: transcript in, edited video and subtitles out
import json
from kolwrite import upload, transcribe
from cut import ranges_from_ids, cut, remap
from srt_tools import cues_from_words, write_srt

result = transcribe(upload("talk.mp3"), output_format="json", word_timestamps=True)
with open("talk.json", "w", encoding="utf-8") as out:
    json.dump(result, out, ensure_ascii=False)
# ... the agent reads talk.json (python view.py talk.json) and writes keep.json ...

keep = json.load(open("keep.json"))["keep"]
ranges = ranges_from_ids(result["segments"], keep)
cut("talk.mp4", ranges, "edited.mp4")

words = [w for segment in result["segments"] for w in segment.get("words", [])]
write_srt(cues_from_words(remap(words, ranges)), "edited.srt")
```

Das reine Kopieren der Streams ohne Neukodierung (`-c copy`) geht zwar schneller, schneidet aber nur an Keyframes. Dadurch kann der Schnitt um einige Sekunden verrutschen. Wenn es auf genaue Schnitte ankommt, sollten Sie neu kodieren.

## Schritt 4: Untertitel für das geschnittene Video

Das Skript `edit.py` hat aus den umgerechneten Wortzeiten bereits die Datei `edited.srt` erzeugt. Wie sich die Zeilen im Detail steuern lassen, erfahren Sie in der [SRT-Anleitung](https://console.kolwrite.com/de/guides/srt-subtitles-api).

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

Sie können die Untertitel nun fest ins Bild einbrennen oder als eigene Spur einbetten, die sich im Player ein- und ausschalten lässt:

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

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

## Weitere Schnittmöglichkeiten mit denselben Wortzeiten

- Pausen kürzen: Behalten Sie zusammenhängende Sprachpassagen und schneiden Sie Stille ab einer bestimmten Länge heraus (siehe [Anleitung zu Wortzeitstempeln](https://console.kolwrite.com/de/guides/word-timestamps-api)).
- Einzelne Clips ausschneiden: Suchen Sie in den Wortdaten nach einer bestimmten Formulierung und schneiden Sie genau diesen Zeitraum aus.
- Füllwörter streichen: Lassen Sie den Agenten Abschnitte markieren, die nur aus Füllwörtern bestehen, oder filtern Sie direkt in den Wortdaten danach.
- Kapitel und Highlights erstellen: Der Agent sucht die passenden Abschnittsnummern heraus und das Skript liest die Zeiten dafür aus ([Anleitung für Podcasts und YouTube](https://console.kolwrite.com/de/guides/podcast-youtube-captions)).
- Einen einzelnen Sprecher isolieren: Aktivieren Sie `include_diarization` und behalten Sie nur die Abschnitte der gewünschten Person.

## Kosten

| Aufgabe | Modell | Kosten |
| --- | --- | --- |
| 10-Minuten-Clip, einmal transkribiert | `oracle` | 0,24 US$ |
| Eine Stunde Video, gute Tonqualität | `base` | 0,48 US$ |
| Eine Stunde Video, Produktionsqualität | `oracle` | 1,44 US$ |
| Eine Stunde, schwierige Tonqualität | `oracle_max` | 3,60 US$ |

Abgerechnet wird sekundengenau ohne Mindestumsatz. Wenn Sie eine schwer verständliche Stelle vorher ausschneiden und einzeln an ein stärkeres Modell schicken, zahlen Sie den höheren Tarif auch nur für diese paar Sekunden. Alle Preise finden Sie unter [/llms/pricing.md](https://console.kolwrite.com/llms/pricing.md).

## Technische Grenzen

- Die Zeitstempel sind genau genug für Schnitte zwischen zwei Wörtern, können aber direkt am Wortanfang oder -ende leicht abweichen. Der Puffer in `cut.py` gleicht das aus. Hören Sie sich die Übergänge vor dem Veröffentlichen am besten kurz an.
- Maschinell erstellte Transkripte enthalten Fehler. Kontrollieren Sie in allem, was Sie veröffentlichen, die Namen und Zahlen. KolWrite nennt für diese API keine Genauigkeitswerte pro Sprache.
- Heben Sie die Originaldatei auf. Das Schnittskript kodiert direkt aus dem Original neu, und vielleicht wollen Sie den Schnitt später noch einmal ändern.
- Sehr viele Schnittbereiche erzeugen einen entsprechend langen ffmpeg-Filter. Ab ein paar hundert Schnitten sollten Sie das Video besser in mehreren Durchgängen schneiden.

## Fragen und Antworten

### Kann Claude ein Video schneiden?

Ja, sofern Claude auf Ihrem System Befehle ausführen darf. Es holt sich über die KolWrite-API ein Transkript mit Wortzeitstempeln, wählt die passenden Sätze aus und schneidet das Video per ffmpeg. Mit Claude Code, Codex CLI oder einem Cursor-Agenten klappt das direkt; ein normales Chatfenster kann Ihnen nur die Skripte dafür schreiben.

### Wie schneide ich ein Video anhand seines Transkripts?

Transkribieren Sie das Video mit Wortzeitstempeln und wählen Sie die gewünschten Abschnitte aus. Nehmen Sie jeweils den Start des ersten und das Ende des letzten Wortes und schneiden Sie diese Stellen mit den ffmpeg-Filtern trim und concat zusammen, genau wie oben in `cut.py` gezeigt.

### Brauche ich ein Plugin oder ein SDK?

Nein. Die API ist HTTPS und JSON; der Agent ruft sie mit curl oder Python auf. Zum Zeitpunkt der Veröffentlichung sind weder ein SDK-Paket noch ein MCP-Server veröffentlicht.

### Funktioniert das auch auf Hebräisch, Arabisch oder in anderen Sprachen?

Für das Transkript ja: Die API verarbeitet 100 Sprachen, entweder per automatischer Erkennung oder fest eingestellt über den Parameter `language`. Welche Modelle Wortzeitstempel liefern, steht in der [Anleitung zu Wortzeitstempeln](https://console.kolwrite.com/de/guides/word-timestamps-api). Probieren Sie es am besten vorab mit einer kurzen eigenen Aufnahme aus und werfen Sie einen Blick auf die [Sprachenübersicht](https://console.kolwrite.com/de/languages/).

### Wie verhindere ich, dass der Agent Zeitstempel erfindet?

Fragen Sie nie nach Zeitangaben. Übergeben Sie stattdessen nummerierte Abschnitte und lassen Sie sich nur die Nummern zurückgeben. Die Zeiten berechnen Sie dann im eigenen Code anhand der Wortzeiten.

## Verwandte Seiten

- [SRT-Untertitel-API](https://console.kolwrite.com/de/guides/srt-subtitles-api)
- [Wortzeitstempel-API](https://console.kolwrite.com/de/guides/word-timestamps-api)
- [Transkriptions-Tool für KI-Agenten](https://console.kolwrite.com/de/guides/transcription-tool-for-ai-agents)
- [KI-Agenten und Vibe Coding](https://console.kolwrite.com/de/use-cases/ai-agents)
- [Medien, Podcasts und Untertitel](https://console.kolwrite.com/de/use-cases/media)
- [API-Dokumentation](https://console.kolwrite.com/de/public_api_docs)

---
API-Schlüssel holen: https://console.kolwrite.com/auth?lang=de · API-Dokumentation: https://console.kolwrite.com/de/public_api_docs · llms.txt: https://console.kolwrite.com/llms.txt
