Communitygithub.com

Developh/resolve-cut

Bearbeiten Sie Talking-Head-Videos (Lektionen, Kurse, Interviews) Ende-zu-Ende in DaVinci Resolve Studio: wortgenaue Transkripte, eine Akte jeder Aufnahme, die letzte vollständige Aufnahme jedes Absatzes, eine bildgenaue Schnittliste, Timeline-Assemblierung per Skript, Rendern mit Presets, Qualitätskontrolle (Lautstärke, Bilder, wiederholte Wörter) und Auslieferung. Verwenden Sie dies vor allen Resolve-Scripting-, Assemblierungs-, Render-, QC- oder Videoauslieferungsarbeiten.

Was ist resolve-cut?

Dieses Skill für KI-Agenten (wie Claude Code, Cursor oder Codex) automatisiert die gesamte Postproduktion von Talking-Head-Videos in DaVinci Resolve Studio. Es führt den Agenten durch einen strukturierten Workflow: Transkription (wortgenau), Erstellung einer kompakten Akte aller Takes, Auswahl des letzten kompletten Takes pro Absatz, Generierung einer bildgenauen Schnittliste, Timeline-Assemblierung, Rendern mit vordefinierten Presets (für Reels, YouTube, Kurse etc.) und Qualitätskontrolle (Lautstärke, Bilder, wiederholte Wörter). Das Skill stellt über gespeicherte Python-Skripte eine effiziente Kommunikation mit Resolve her, ohne bei jeder Sitzung das gesamte Scripting neu zu schreiben. Es vermeidet manuelle Entscheidungen – der Mensch entscheidet, der Agent führt aus und misst. Das Skill enthält außerdem umfangreiche Dokumentation zu bekannten Fallstricken („Traps“) der Resolve-API, die Zeit sparen und Fehler vermeiden helfen.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Developh/resolve-cut/tree/HEAD/skills/resolve-cut

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht resolve-cut?

Sie montieren, rendern und prüfen Videos in DaVinci Resolve Studio über gespeicherte Skripte mit Parametern. Sie schreiben die Montage nicht in jeder Sitzung neu: Sie rufen die Skripte auf, lesen, was sie zurückgeben, und überprüfen das Ergebnis mit Zahlen und Einzelbildern. Der Geschmack bleibt menschlich: Die Person entscheidet, was bleibt, Sie führen aus und messen.

$SKILL unten ist der Ordner dieses Skills (in dem diese Datei lebt). Skripte in scripts/resolve/ laufen in Resolve über run.py; Skripte in scripts/media/ sind einfaches Python mit ffmpeg. Jedes Skript hat --help.

Bevor Sie beginnen

  1. Resolve antwortet: python3 "$SKILL/scripts/resolve/run.py" - '{}' <<< 'result = resolve.GetVersionString()'. Exit-Code 2 bedeutet, dass Resolve geschlossen ist, es sich um die kostenlose Edition handelt oder unter Einstellungen > System > Allgemein > Externes Scripting verwenden nicht auf Lokal gesetzt ist.
  2. ffmpeg -version, python3 -c "import numpy, PIL" und ELEVENLABS_API_KEY (Umgebungsvariable oder ./.env).
  3. Wenn das Projekt eine Notizdatei führt (VIDEO_NOTES.md oder ähnlich), lesen Sie sie: was die Person zuvor genehmigt und abgelehnt hat. Fragen Sie nicht zweimal nach derselben Korrektur.
  4. Arbeitsordner: Alles, was Sie schreiben (Transkripte, Dossier, Einzelbilder, Render), geht in einen Arbeitsordner, niemals in den Rohmaterial-Ordner.

Der Ablauf

1. Transkribieren. Wortgenaue Transkripte, eine JSON pro Clip: python3 "$SKILL/scripts/media/transcribe.py" <clips-Ordner> --out work/transcripts [--language por]. Das Transkript ist die Grundlage für alles: Auswahl der Takes, Schnitt an Bildgrenzen und Prüfung des endgültigen Mixes.

2. Dossier. Das gesamte Material in einer kompakten Textdatei, einmal lesen: python3 "$SKILL/scripts/media/dossier.py" <clips-Ordner> --transcripts work/transcripts --out work/dossier.md [--sheets]. Es listet jeden Satz mit seiner Zeit auf und markiert «repeats C0076 20.2», wenn ein Satz wie ein früherer beginnt: ein weiterer Versuch derselben Zeile. Mit einem Skript behalten Sie die letzte vollständige Aufnahme jedes Absatzes; lassen Sie Zögern, Fehlstarts und wiederholte Versuche weg. Öffnen Sie einen Clip nur, um zu entscheiden: python3 "$SKILL/scripts/media/inspect_range.py" <clip> <t0> <t1> --words work/transcripts/<clip>.json (Einzelbilder, Wellenform und Wörter in einem Bild).

3. Schnittliste. Schreiben Sie work/plan.json mit den ausgewählten Takes in der Reihenfolge ({"Lesson 01 v1": [["01a", "C0081", 1.9, 12.6], ["01b", "C0083", 5.4, 23.8], ...]}: Take, Clip, von, bis in Sekunden des Clips), dann: python3 "$SKILL/scripts/media/cut_list.py" work/plan.json work/transcripts <clips-Ordner> work/cuts.json. Schnitte landen auf der leisesten Bildgrenze neben den Wörtern, Pausen über 1 s werden verkürzt, und Segmente wechseln sich mit Zoom 1 / 1,2 ab, sodass Schnitte zwischen Takes nicht springen. Bei einem Fehlstart ohne Lücke („ko- contar“) erzwingen Sie das Bild mit {"in_frame": N} oder {"out_frame": N}. Notizen für den Editor: add_markers.py.

4. In Resolve montieren. Ein schwerer Vorgang pro Aufruf, und lesen Sie jedes result, bevor Sie den nächsten ausführen:

R="$SKILL/scripts/resolve/run.py"
python3 "$R" "$SKILL/scripts/resolve/project.py" '{"name": "Lesson 01", "width": 1920, "height": 1080, "fps": "25"}'
python3 "$R" "$SKILL/scripts/resolve/assemble.py" '{"phase": "import", "bin": "Raw", "media": "/abs/clips", "files": ["C0081.MP4"]}'
python3 "$R" "$SKILL/scripts/resolve/assemble.py" '{"phase": "timeline", "bin": "Raw", "cuts": "/abs/work/cuts.json", "timeline": "Lesson 01 v1", "zoom": {"center": [0.45, 0.37]}, "voice_isolation": 50}'

zoom.center gibt an, wo sich das Gesicht befindet (Bruchteil des Bildes), sodass die Vergrößerung es an Ort und Stelle hält. Überprüfen Sie, ob frames == expected ist und failures leer ist.

5. Vor dem Rendern ansehen. frames.py exportiert Einzelbilder direkt aus der Timeline in unter einer Sekunde ({"timeline": "Lesson 01 v1", "frames": [100, 500], "folder": "/abs/work/frames", "max": 960}). Schauen Sie sich ein normales und ein vergrößertes Bild an.

6. Rendern. python3 "$R" "$SKILL/scripts/resolve/render.py" '{"phase": "start", "timeline": "Lesson 01 v1", "folder": "/abs/out", "name": "lesson-01", "preset": "reel", "width": 1920, "height": 1080, "mark": [0, <frames - 1>]}', dann alle 10 s {"phase": "status", "job": "<id>"} abfragen, bis JobStatus Complete ist. Warten Sie, bis der Render abgeschlossen ist, bevor Sie antworten: Ein unbeaufsichtigter Durchlauf, der seinen Turn bei „Render gestartet“ beendet, hat niemanden, der ihn überprüft.

7. Verifizieren. python3 "$SKILL/scripts/media/qc.py" out/lesson-01.mp4 --expected <frames> --transcribe (--ref gegen die letzte genehmigte Version hinzufügen, --frames für ein Blatt, --simulate für Instagram). Lesen Sie das Transkript des endgültigen Mixes an jedem Schnitt: Wiederholte Wörter („entscheiden, entscheiden“), abgeschnittene Wörter und Wörter an der falschen Stelle sind die Mängel, die eine Schnittliste verursacht. Bestätigen Sie einen verdächtigen Schnitt an der Wellenform (inspect_range.py), bevor Sie ihn verschieben, reparieren Sie die Schnittliste, montieren Sie eine neue Version (v2) und rendern Sie erneut. Maximal 3 Runden, jeder Mangel mit seiner genauen Zeit benannt. Nennen Sie es nie erledigt, weil es „richtig aussieht“: Zitieren Sie die Zahlen.

8. Ausliefern. loudness.py, wenn der Mix nicht im Zielbereich liegt (linearer Gain und ein Limiter, niemals loudnorm), dann deliver.py export.mp4 clean.mp4 [--no-editlist] [--copy <ordner>]: keine Timecode-Spur, keine Metadaten, moov zuerst, Kopie Byte für Byte verglichen.

9. Überprüfen, nachdem die Person genehmigt hat. Notieren Sie in der Notizdatei, was sie genehmigt und abgelehnt hat, in ihren Worten, eine Zeile pro Punkt; jede neue Falle mit ihrem Datum; und jede Routine, die Sie mehr als einmal von Hand ausgeführt haben, wird zu einem Skript mit Parametern neben diesen.

Skripte in Resolve ausführen

  • run.py verbindet sich mit dem geöffneten Resolve und führt ein Skript mit resolve, project, P (das JSON) und __file__ aus, dann gibt es result als JSON aus. Es kostet weitaus weniger Token, als dasselbe Skript über einen MCP zu schreiben.
  • Mit einem MCP-Server stattdessen (offizielles run_script_unsafe): P = {...}; __file__ = "<absoluter Pfad des Skripts>"; exec(open(__file__, encoding="utf-8").read()). Die Sandbox liest Dateien ohne encoding als ASCII, und Namen bleiben zwischen Aufrufen erhalten: Die Skripte verwenden Variablen mit Präfix.
  • Speichern Sie vor und nach dem Schreiben (GetProjectManager().SaveProject()); es gibt kein Rückgängig. Jede neue Version auf einer Kopie der Timeline erstellen (DuplicateTimeline, die auch Fusion-Comps kopiert).
  • Schlagen Sie die API nach, anstatt zu raten: die offizielle MCP search_scripting_api, get_scripting_docs und get_whats_new (einmal pro Sitzung) oder Blackmagics README im Ordner Developer/Scripting von Resolve (Hilfe > Dokumentation > Entwickler).
  • Neue Operation, die sich wiederholen wird? Schreiben Sie sie einmal als Skript mit einem P-Dict und einem result neben diesen.

Auslieferungsziele

ZielBildTon
Reels, Stories, Shorts, TikTok1440x2560 mit der Aufnahme-Bildrate, H.264 High bei etwa 20 Mbit/s real, Rec.709 Tags (1-1-1), faststart-14 LUFS, True Peak unter -1,5 dBTP
Lektionen und Kursewie aufgenommen (1920x1080 oder 3840x2160)-16 LUFS, True Peak bis zu -1 dBTP
YouTubeder 4K-Master (1080p-Uploads verlieren Qualität), MP4 ohne Edit-ListenDer Mix des Masters
LinkedIn1920x1080 und 1080x1920 mit 16 Mbit/s, mit SRTDer Mix des Masters

Verifizierte Fallen

Gemessen auf macOS mit Resolve Studio 21.1.1 und 21.1.2, Oktober und November 2026.

Maschine

  • Ein ffmpeg gleichzeitig, mit nice -n 15 und -threads 2: 96 parallele ffmpeg-Prozesse haben den Mac eingefroren und einen Neustart erzwungen.
  • In zsh teilt $var nicht in Wörter auf (ffmpeg $args bricht): Argumentlisten in Python erstellen.
  • Ausgaben in den Arbeitsordner schreiben: Ein Helfer, der Bilder neben dem Clip gespeichert hat, hat in den Rohmaterial-Ordner geschrieben.

Resolve Einrichtung und API

  • Resolve 21.1 hat Python Scripting zu Studio verschoben: run.py und beide MCP-Server benötigen DaVinci Resolve Studio.
  • Externes Scripting muss auf Lokal gesetzt sein (Einstellungen > System > Allgemein), sonst gibt scriptapp("Resolve") None zurück.
  • StartRendering ist der letzte Aufruf eines Skripts: Alles andere gibt None zurück, bis der Render endet.
  • Die Projekt-Bildrate wird beim Erstellen der ersten Timeline festgelegt: setzen Sie sie vorher (project.py).
  • Auflösung: SetSetting einen Schlüssel nach dem anderen, useCustomSettings zuerst.
  • Das MCP-Timeout (standardmäßig 10 s, maximal 60 s) gibt einen Fehler zurück, aber das Skript läuft in Resolve weiter: Überprüfen Sie den Status, bevor Sie es erneut ausführen.
  • Es gibt kein Trimmen, Verschieben oder Slip: Löschen Sie das Element und fügen Sie es mit startFrame, endFrame (exklusive) und recordFrame erneut hinzu.
  • startFrame zählt ab dem ersten Bild der Datei, auch mit Kamera-Timecode.
  • GetSourceStartFrame liest manchmal ein Bild zu früh (866 liest 865), während die Platzierung richtig ist: Lesen Sie den In-Point mit GetLeftOffset.
  • AddMarker behält einen Marker pro Bild.
  • ReplaceClip löscht die Metadaten des Clips.
  • SetTrackEnable gibt True zurück und ändert bei einigen Timelines nichts: Deaktivieren Sie die Clips mit SetClipEnabled und bestätigen Sie auf einem exportierten Bild.
  • SetClipEnabled auf einer Timeline, die nicht die aktuelle ist, gibt False zurück: Zuerst SetCurrentTimeline, dann mit GetClipEnabled bestätigen.
  • DeleteClips(items, True) rippelt jede Spur: Löschen Sie zuerst, ohne Ripple, was den Schnitt kreuzt (Stems, Untertitel).
  • Voice Isolation funktioniert per Skript: TimelineItem.SetVoiceIsolationState({"isEnabled": True, "amount": 100}) hat den Raumhall um 3 bis 4 dB gesenkt; Timeline.SetVoiceIsolationState(track, {...}) setzt einen Regler für eine ganze Spur.
  • Die API kann keine ResolveFX-Parameter setzen (Face Refinement, Blemish Removal): Eine Person setzt sie, oder Sie steuern die UI über Barrierefreiheit.
  • Bei gesperrtem Bildschirm oder minimiertem Resolve verschwindet das Fenster aus der Barrierefreiheit, aber die API arbeitet weiter: Mit exportierten Bildern überprüfen.
  • Super Scale ist eine Media-Pool-Eigenschaft: SetClipProperty("Super Scale", 2); eine Ersatzdatei muss erneut gesetzt werden.
  • LUTs für Graph.SetLUT werden im System-LUT-Ordner von Resolve in einem Unterordner abgelegt, übergeben durch relativen Pfad nach RefreshLUTList().
  • Ändern der Seiten während Resolve abspielt, lässt es hängen; item.GetFusionCompByIndex(1).Execute(lua) bearbeitet eine Kompilation, ohne die Fusion-Seite zu öffnen.

Import und Medien

  • Ein ProRes pro Importaufruf: Mehrere ProRes 4444 (und einmal zwei neue ProRes 422) in einem Aufruf haben Resolve 21.1 zum Absturz gebracht (UiMpController, std::out_of_range). Kamera-MP4s, 22 in einem Aufruf, waren in Ordnung.
  • Nach diesem Absturz meldet ein verwaister ResolvePython-Prozess dem MCP launch_resolve, dass Resolve läuft: Töten Sie ihn und öffnen Sie Resolve erneut.
  • ImportMedia mit einer Liste von Pfaden: Die Form mit Dictionaries gab None für MP4 auf 21.1 zurück.
  • Resolve speichert die Decodierung nach Pfad zwischen: Eine Datei, die Sie erneut rendern, bekommt einen neuen Namen.
  • PCM 24-Bit Little-Endian in MOV wird als weißes Rauschen gelesen: Verwenden Sie pcm_s24be.
  • iPhone HEVC hat den macOS-Decoder zum Absturz gebracht: Bearbeiten Sie von ProRes aus.
  • iPhone HDR (HLG, Dolby Vision): Unser eigenes Tonemapping sah verwaschen aus und wurde zweimal abgelehnt. Fragen Sie zu Beginn nach einem SDR-Export.
  • Ein 1-Bild .mov wird als 150-Bild-Standbild importiert: Geben Sie ihm mindestens 3 Bilder und trimmen Sie es auf der Timeline.
  • Gerades Alpha: Resolve liest Alpha un-premultipliziert, sodass ein Overlay, das mit ffmpeg overlay auf einer transparenten Leinwand erstellt wurde, dunkel erscheint; positionieren Sie es mit pad=W:H:x:y:[email protected].

Rendern

  • Mit SelectAllFrames gibt StartRendering manchmal False zurück: Setzen Sie MarkIn/MarkOut (render.py mark), was auch die Tonenden abschneidet, die eine Timeline verlängern.
  • Ein H.264-Job, der direkt nach einem reiner Audio-Job erstellt wurde, kam ohne Video: Laden Sie ein Preset vor SetRenderSettings und überprüfen Sie mit ffprobe den Videostream.
  • VideoQuality ist eine Obergrenze, kein Durchschnitt: 20000 ergab 14,7 Mbit/s und 27300 ergab 20,7 Mbit/s bei 1440x2560.
  • „Force sizing to highest quality“ ist kein SetRenderSettings-Schlüssel, wird aber in einem Render-Preset (ForceHighestQualitySizing) transportiert.
  • ExportRenderPreset(name, path) behandelt path als Ordner; ImportRenderPreset benennt das Preset nach der Datei.
  • Presets speichern eine Bildrate: Setzen Sie FrameRate von der Timeline, oder eine 29,97-Timeline wird konvertiert gerendert (render.py macht das).
  • ExportFrame (21.1.2) gab 4 Bilder bei 1440x2560 in 0,75 s aus, innerhalb von 41 bis 46 dB des Renders: Überprüfen Sie Bilder ohne Rendern.

Ton und Transkripte

  • Ein Schnitt zwischen zwei Takes kann ein wiederholtes Wort verbinden („entscheiden, entscheiden“): Transkribieren Sie den finalen Mix und suchen Sie nach Duplikaten. Korrigieren Sie, ohne die Länge zu ändern: Beenden Sie das erste Stück vor dem Wort, beginnen Sie das zweite früher in der Pause des guten Takes.
  • Das Transkript hört keine Flüstern und Atemzüge: Schnittpunkte kommen vom eigenen Ton der Kamera (cut_list.py).
  • Scribe hat einmal ein Wort 3 s zu früh platziert, nach einem Klatschen und einem Flüstern: Bestätigen Sie auf der Wellenform, bevor Sie einen Schnitt verschieben.
  • MP3-Soundeffekte landen etwa 60 ms zu spät (der Encoder-Delay wird nicht kompensiert): Verwenden Sie WAV für alles, was auf ein Bild treffen muss.
  • loudnorm in einem Durchlauf ist dynamisch und ändert den genehmigten Mix; in zwei Durchläufen fällt es stillschweigend auf dynamisch zurück: Verwenden Sie loudness.py.

Aufnahmen und Plattformen

  • 25 fps auf Instagram: Dienen mit 25 (ffprobe der ausgelieferten Dateien, November 2026). Das Ruckeln kommt von ProMotion iPhones, die keinen 25- oder 50-Hz-Modus haben. Behalten Sie 25-fps-Material bei 25 (die Konvertierung auf 30 wiederholt eines von fünf Bildern); neues Material mit 29,97 und einem 1/50-Verschluss aufnehmen.
  • Flimmern unter 50-Hz-Lichtern hängt vom Verschluss ab, nicht von der Bildrate: 1/50 und 1/100 flimmern nicht; 1/60 bei 30 fps tut es.
  • Instagram kodiert auf dem Telefon und erneut auf dem Server erneut: Die grundlegende Auslieferung liegt bei etwa 720x1280 mit 1,4 Mbit/s, der Ton normalisiert auf etwa -14 LUFS, daher gewinnt ein Master über -14 nichts. qc.py --simulate zeigt, was überlebt.
  • CRF in ffmpeg unterbelichtet dunkle Hintergründe: Ein Reel blieb bei 6,8 Mbit/s. Prüfen Sie die tatsächliche Bitrate vor der Auslieferung.
  • Ein unbeaufsichtigter claude -p-Durchlauf beendet seinen Turn, wenn der Render startet, es sei denn, die Eingabeaufforderung sagt, dass er warten soll.

Skripte

SkriptWas es tut
scripts/media/transcribe.pyScribe Wort-für-Wort JSON pro Clip (Schlüssel über stdin, niemals in der Prozessliste)
scripts/media/dossier.pyJeder Clip als kompakter Text: Sätze mit Zeiten, Pausen, wiederholte Versuche, optionale Einzelbildblätter
scripts/media/inspect_range.pyEin Bild eines Bereichs: Einzelbilder, Wellenform, Wörter mit Zeiten
scripts/media/cut_list.pyTake-Auswahl zu Schnittliste mit Bildgenauigkeit und Zoom-Variation
scripts/media/qc.pyFinale Datei auf Bildanzahl, Lautstärke, wiederholte Wörter, Simulation der Plattform prüfen
scripts/resolve/run.pyPython mit resolve, project, P und file in Resolve ausführen
scripts/resolve/project.pyProjekt mit Name, Auflösung, Bildrate erstellen
scripts/resolve/assemble.pyMedien importieren, Timeline aus Schnittliste montieren
scripts/resolve/render.pyTimeline rendern, Status abfragen
scripts/resolve/frames.pyEinzelbilder direkt aus Timeline exportieren
scripts/resolve/deliver.pyExportierte Datei säubern: Metadaten, Edit-Listen entfernen; optional kopieren
scripts/resolve/loudness.pyLautstärke mit linearem Gain und Limiter korrigieren
scripts/resolve/add_markers.pyMarker nach Schnittliste setzen

Allgemeine Parameter

Die meisten Skripte erwarten die folgenden Parameter als JSON über die Umgebungsvariable P oder über einen Dateipfad:

ParameterTypBeschreibung
nameStringProjektname oder Timelinename
widthIntegerBreite des Projekts/Bildes
heightIntegerHöhe des Projekts/Bildes
fpsStringBildrate (z.B. "25", "29.97")
binStringMedienpool-Ordner
mediaStringPfad zum Medienordner
filesListeDateinamen für Import
cutsStringPfad zur Schnittliste JSON
timelineStringTimelinename
zoomObjectZoom-Einstellungen ({"center": [0.45, 0.37]})
voice_isolationIntegerStärke der Sprachisolierung (0-100)
folderStringAusgabeordner
nameStringAusgabedateiname
presetStringRender-Preset ("reel", "lesson", "youtube", "linkedin")
markListeMark In/Out für Render

Hinweise

  • Das Skill erwartet, dass DaVinci Resolve Studio bereits läuft und externes Scripting aktiviert ist.
  • Alle Skripte geben ihre Ergebnisse als JSON auf stdout aus. Lesen Sie result nach jedem Aufruf.
  • Die Arbeitsordner müssen absolute Pfade sein. Relative Pfade können zu Fehlern führen.
  • Bei Fehlern geben die Skripte einen Exit-Code ungleich 0 und eine Fehlermeldung auf stderr aus.

Verwandte Skills