Communitygithub.com

Basis-Videobearbeitung (Zurechtschneiden von Rohaufnahmen anhan…

Schneidet eine rohe, durchgehende Video- oder Audioaufnahme (z. B. ein Talking-Head-Video in einer einzigen Einstellung mit vielen Wiederholungen, Fehlstarts und Versprechern) zu einer sauberen Endfassung, die einem gewünschten Skript folgt. Dabei wird Whisper-Transkription mit einer Stille-Erkennung kombiniert, um bildgenaue Schnittpunkte zu ermitteln, und die Montage erfolgt mit ffmpeg.

Was ist Basis-Videobearbeitung (Zurechtschneiden von Rohaufnahmen anhan…?

Dieser Skill löst ein spezifisches Problem der Videobearbeitung: Eine einzige, durchgehende Aufnahme mit vielen Wiederholungen und Fehlstarts lässt sich allein anhand einer Transkription kaum sauber schneiden. Whisper liefert oft ungenaue Zeitstempel, besonders bei Pausen und wiederholten Passagen – was zu ungewollter Stille im fertigen Video führen würde. Der Skill umgeht dies, indem er zunächst mit einer Stille-Erkennung (über `detect_bursts.py`) die tatsächlichen Sprachgrenzen auf Sample-Ebene ermittelt. Anschließend transkribiert `transcribe_bursts.py` jeden dieser Sprachabschnitte isoliert, wodurch versteckte Fehlstarts sichtbar werden, die in einer Ganzdatei-Transkription untergehen. Auf Basis dieser präzisen Daten erstellt der Skill einen detaillierten Schnittplan, der dem Benutzer zur Bestätigung vorgelegt wird. Erst nach Freigabe wird das Video mit `cut_and_concat.sh` zusammengesetzt. Die Ausgabe wird mit einem integrierten Prüfskript (`check_video.py`) auf Fehler wie eingefrorene Einzelbilder, tonlose Lücken oder falsche Überblendungen untersucht, bevor sie ausgeliefert wird. Der Skill läuft auf macOS und Linux, erfordert ffmpeg, Whisper und Python 3, und ist für Talking-Head-Videos optimiert, bei denen ein Skript als Referenz vorliegt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Istok-Media-Tool/video-edit-skills/tree/HEAD/video-edit/skills/basic

In Ihrer bevorzugten KI fragen

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

Dokumentation

Basis-Videobearbeitung (Zurechtschneiden von Rohaufnahmen anhand eines Skripts)

Warum dieser Skill existiert

Eine einzige, durchgehende Aufnahme voller Wiederholungen ist allein anhand einer Transkription trügerisch schwer korrekt zu schneiden. Als dieser Workflow zum ersten Mal von Hand ausgeführt wurde, führte das Vertrauen auf die eigenen Zeitstempel von Whisper aus einem einzigen Durchlauf durch die gesamte Datei zu einem Schnittplan, bei dem ein Satz angeblich 22 Sekunden dauerte. Tatsächlich dauerte er 5,75 Sekunden; Whisper hatte 16 Sekunden Stille und zwei Fehlstarts in dieses eine Segment gepackt. Hätte man dieser Transkription für die Schnitte vertraut, wäre das Video voller toter Luft gewesen.

Behalten Sie diese Lektion im Hinterkopf: Das Ziel dieses Workflows sind genaue Schnittpunkte, und Whisper allein liefert diese bei Aufnahmen mit Pausen, Wiederholungen oder mehrfach gesagten Zeilen nicht zuverlässig. Alles, was folgt, dient dazu, dies auszugleichen.

Workflow

1. Quellmaterial analysieren

Überprüfen Sie das Video auf grundlegende Fakten, bevor Sie etwas anderes tun:

ffprobe -v error -show_entries format=duration,size -show_entries stream=width,height,codec_name,codec_type,avg_frame_rate -of default=noprint_wrappers=0 "<video>"

Extrahieren Sie Mono-16-kHz-Audio für die Transkription (Whisper erwartet dies, und es ist viel kleiner/schneller zu verarbeiten als das gesamte Video):

ffmpeg -y -i "<video>" -vn -ac 1 -ar 16000 audio.wav -loglevel error

Falls der Benutzer Ihnen eine Skript-/Szenariodatei (txt, rtf, docx usw.) gegeben hat, lesen Sie diese jetzt, damit Sie den beabsichtigten Inhalt zum Vergleich haben. Eine .rtf-Datei benötigt oft textutil -convert txt -stdout file.rtf (macOS), um sauberen Text statt rohem RTF-Markup zu erhalten.

2. Groben Überblick mit einer ersten Transkription gewinnen

whisper audio.wav --language <lang> --model medium --output_format txt --output_format srt --output_dir .

Verwenden Sie dies NUR, um einen allgemeinen Eindruck vom Inhalt zu bekommen und grob zu sehen, wie weit verschiedene Zeilen in der Aufnahme fortgeschritten sind. Verwenden Sie die Start-/Endzeiten der Segmente nicht als echte Schnittpunkte – siehe „Warum dieser Skill existiert". Wenn die Aufnahme lang ist, kann dieser Schritt parallel zu Schritt 3 ausgeführt werden (oder zugunsten von Schritt 3 übersprungen werden).

3. Echte Sprachgrenzen mit Stille-Erkennung finden

Dies ist der Schritt, der tatsächlich zählt. Führen Sie aus:

python3 scripts/detect_bursts.py audio.wav > bursts.txt

Dies liefert samplegenaue Sprach-„Bursts" (das Komplement der erkannten Stille), gefiltert, um sub-0,5-s-Blitzer auszuschließen, die fast immer Atemgeräusche und keine Wörter sind. Vertrauen Sie diesen Zeitstempeln, nicht denen von Whisper.

Plausibilitätsprüfung: Natürliche Sprache hat etwa 2-3 Wörter pro Sekunde. Wenn die Dauer eines Bursts im Verhältnis zur darin erwarteten Textmenge unverhältnismäßig erscheint, stimmt etwas nicht.

4. Jeden Burst isoliert transkribieren

python3 scripts/transcribe_bursts.py audio.wav bursts.txt --language <lang> --model medium

Dies lädt das Whisper-Modell einmal, transkribiert dann jeden Burst als eigenen kurzen Clip mit condition_on_previous_text=False und temperature=0. Diese Kombination bringt tatsächlich versteckte Wiederholungen ans Licht: Ein Burst, den ein Ganzdatei-Durchlauf als eine saubere Zeile bezeichnet, kann sich, isoliert betrachtet, als ein Fehlstart mit sofort folgender korrekter Version entpuppen – im ersten Transkriptionsdurchlauf, der die Wiederholung stillschweigend zusammengefasst oder unterdrückt hatte, völlig unsichtbar.

Erwarten Sie bei einer Aufnahme mit merklichen Wiederholungen mehr Bursts als Skriptzeilen – oft mehrere Fehlstart-Fragmente pro Zeile, besonders bei der Zeile, mit der der Sprecher am meisten zu kämpfen hatte. Das ist normal; genau dafür ist dieser Schritt da.

5. Schnittplan erstellen – und vor dem Schneiden bestätigen lassen

Gruppieren Sie die transkribierten Bursts nach der Zeile/ Idee des Skripts, zu der sie gehören. Für jede Zeile sehen Sie typischerweise eines von Folgendem:

  • Ein sauberer, vollständiger Burst – einfach, das ist die Version.
  • Ein Fehlstart, gefolgt von einem vollständigen Burst – verwenden Sie den vollständigen, verwerfen Sie das Fragment.
  • Mehrere vollständige, ganze Versionen mit demselben Wortlaut – das sind echte Performance-Duplikate; Sie können Vortrag/Emotion nicht allein anhand einer Transkription beurteilen, also schneiden Sie mit einer vernünftigen Voreinstellung (z. B. den späteren Versuch, da sich Sprecher oft in eine Version einfinden) und lassen Sie den Benutzer im Dublovi-Modus (unten) auswählen.
  • Mehrere vollständige Versionen mit tatsächlich unterschiedlichem Wortlaut (der Sprecher hat jedes Mal anders improvisiert) – dies ist eine echte inhaltliche Entscheidung, nicht nur eine Performance-Entscheidung. Präsentieren Sie dem Benutzer die Alternativen explizit, anstatt stillschweigend eine auszuwählen – er könnte seine improvisierte Phrase der skriptgemäßen vorziehen oder umgekehrt.

Für beide Arten von Duplikat-Versionen entscheidet der Benutzer gemeinsam mit Ihnen, indem er sie ansieht: Die Versionen gehen in den Dublovi-Modus des Plan-editors (zwei Versionen nebeneinander, links / rechts, „Ovaj je bolji"), bei JEDEM Video. Beschreiben Sie Versionen nicht im Chat und fragen Sie dort nicht „dubl 1 ili 2". Schneiden Sie mit Ihrer Standardauswahl, listen Sie jedes Duplikat in takes_src.json (Plan-editor-Skill, „Dublovi") auf und öffnen Sie den Editor; tauschen Sie die Version im Schnitt aus, wenn der Benutzer eine andere wählt.

Dann schreiben Sie den vollständigen Plan als Nachricht an den Benutzer: den exakten Text, der für jede Zeile behalten wird, seinen genauen Zeitstempelbereich und was geschnitten wird und warum (tote Luft, Fehlstarts, verworfene Alternativversionen). Warten Sie auf eine explizite Bestätigung, bevor Sie einen Schneidebefehl ausführen. Dies ist keine Formalität – das Bearbeiten eines Videos fühlt sich zerstörerisch an und ist schwer ohne Ansehen des Outputs zu überprüfen. Der Benutzer muss den Plan sehen, um Probleme (falsche Version ausgewählt, eine Zeile, die nebeneinandergesetzt nicht natürlich klingt) zu erkennen, bevor Renderzeit dafür aufgewendet wird, nicht danach.

Wenn der Benutzer nach der Gesamtdauer fragt, summieren Sie einfach die Dauern der behaltenen Segmente – weisen Sie aber darauf hin, dass die tatsächliche Enddauer etwas länger sein wird, sobald Abstände zwischen den Schnitten hinzugefügt werden (Schritt 6).

6. Schneiden und zusammensetzen

Schreiben Sie die bestätigten Auswahlen (ein start<TAB>end-Paar pro Zeile, in Ausgabereihenfolge) in eine Datei, dann:

scripts/cut_and_concat.sh "<source_video>" selections.txt final_output.mp4

Lesen Sie den Kommentarblock am Anfang von cut_and_concat.sh, bevor Sie ihn manuell ausführen oder anpassen – er dokumentiert Fallstricke (ffmpeg stiehlt stdin von einer Bash-Schleife, Ausblendungen verschlucken den letzten Buchstaben eines Wortes, warum jeder Clip einzeln neu codiert werden muss, bevor er zusammengefügt wird), die leicht stillschweigend wieder eingeführt werden, wenn das Skript von Grund auf neu geschrieben wird, anstatt es unverändert zu verwenden.

Standardeinstellungen: 0,15 s Abstand vor jedem Einschnitt, 0,35 s nach jedem Ausschnitt, nur ein 5 ms Einblenden (kein Ausblenden), neu codiertes h264 (crf 18) + aac 192k pro Clip, jeder Clip auf eine exakte Bildanzahl geschnitten, dessen Audio auf dieselbe Länge getrimmt, verbunden mit dem ffmpeg concat FILTER (niemals dem concat Demuxer – siehe „Jeden Render überprüfen" unten). Überschreiben Sie diese über die Umgebungsvariablen PRE_PAD, POST_PAD, CRF, FADE_IN, wenn ein bestimmter Schnitt eine andere Behandlung benötigt (z. B. eine Zeile mit viel nachlaufendem Atemgeräusch könnte mehr POST_PAD benötigen).

Wenn der letzte Buchstabe eines Satzes nach einem ersten Durchlauf immer noch abgeschnitten klingt, bedeutet das fast immer, dass POST_PAD für diesen speziellen Schnitt zu knapp ist (der Nachklang des Sprechers reicht weiter als die Schwelle der Stille-Erkennung erfasst hat) – erhöhen Sie ihn für dieses Segment, anstatt zu einer Ausblendung zu greifen, die einen engen Schnitt nur noch schlechter klingen lässt, nicht besser.

Straffe Taktung – der Standard des Benutzers

Der Standardabstand (0,15 s / 0,35 s) hinterlässt eine ~0,5 s Pause an jedem Schnitt. Der Benutzer fand, dass dies den Rhythmus brach („mora biti sve zbijenije i tečnije"), also straffen Sie für seine Videos jeden Schnitt vor dem Zusammensetzen:

python3 scripts/tighten_cuts.py audio.wav selections.txt tight.txt
PRE_PAD=0.04 POST_PAD=0.08 scripts/cut_and_concat.sh "<source_video>" tight.txt final_output.mp4 <abs workdir>

Es verschiebt jede Kante dorthin, wo die Sprache wirklich beginnt / endet (-42 dB) und teilt jede interne Pause über 0,30 s auf. Bei einem echten Film dauerte dies von 1:48 bis 1:41, jedes Wort blieb erhalten. Überprüfen Sie danach durch Transkription des Ergebnisses: Jedes Wort des behaltenen Textes muss noch vorhanden sein. Zeitangaben von allem, was auf dem alten Schnitt platziert wurde (Nahaufnahmen, Untertitel, Titel), müssen über die Quellzeit neu zugeordnet werden, nicht um eine Konstante verschoben.

Wenn zwei getrennt geschnittene Teile zusammengefügt werden (z. B. Hauptteil + Abspann), nehmen Sie den Verbindungspunkt aus der tatsächlichen Bildanzahl des ersten Teils (nb_read_frames / fps), nicht aus seiner Container-Dauer: Bei einem echten Film ließ der Unterschied von 0,04 s ein einzelnes Bild der Totalen zwischen einer Nahaufnahme und dem Abspann erscheinen, und der erste Untertitel des Abspanns erschien ein Bild zu früh. Eine Überlagerung, die am Verbindungspunkt endet, muss bis zu diesem Bild laufen.

Jeden Render überprüfen – bevor Sie etwas senden

Bei einem echten Film bemerkte der Benutzer ein einzelnes Bild der Totalen bei 1:05 („to ne sme da nam se dešava"). Die eigentliche Ursache war größer: Das alte cut_and_concat.sh verband Clips mit dem concat Demuxer, der jeden Clip anhand seiner Container-Dauer und AAC-Priming/Padding platziert, nicht anhand seiner tatsächlichen Bilder. Das hinterließ ein 80 ms Loch (2 Bilder) an 10 der Schnitte – ein eingefrorenes Bild auf dem Bildschirm nach der Neuencodierung – und der Audio driftete langsam vor dem Bild, sodass jede davon abgeleitete Überlagerung und jeder Untertitel ein oder zwei Bilder versetzt landete. Das korrigierte Skript (Fallstrick #4 in seinem Header) schneidet jeden Clip auf eine exakte Bildanzahl, fügt Padding/Trimmt sein Audio auf genau diese Länge und verbindet mit dem concat Filter.

Daraus folgende Regeln:

  • Führen Sie den Prüfer bei JEDEM Render (Schnitt, Zoom, Untertitel, Finale) aus, bevor Sie ihn an den Benutzer senden:

    python3 scripts/check_video.py final.mp4 --ass captions.ass --edges edges.txt --cuts joins.txt
    

    joins.txt = jeder Verbindungspunkt der Schnittliste auf der endgültigen Zeitleiste (laufende Summen der Dauern jedes Teils aus durs.txt, plus die Teilgrenzen). Übergeben Sie es immer: Ein Sprungschnitt innerhalb derselben Einstellung wird weit unterhalb der Szenenschwelle bewertet, sodass der Prüfer ohne ihn einen Zoomwechsel übersah, der 3 Bilder vor einem Verbindungspunkt bei einem echten Film landete (1:15) – ein 3-Bild-Blitzen, das der Benutzer sah.

    Er meldet Zeitstempellücken, einzelne eingefrorene Bilder, Audio- vs. Videolänge, nur wenige Bilder lange Einstellungen, Untertitel kürzer als 0,4 s oder die 1-3 Bilder von einem Bildschnitt beginnen/enden, sowie Überlagerungskanten (edges.txt: ein Nahaufnahme-/B-Roll-Start oder -Ende pro Zeile, Sekunden) 2-5 Bilder von einem Schnitt entfernt. Exit 1 = etwas wurde gefunden: Beheben Sie es und rendern Sie erneut; nur „OK - nothing found" wird gesendet.

  • Nehmen Sie jede Clip-Position aus Bildanzahlen (nb_frames / fps oder der vom Skript geschriebenen durs.txt), niemals aus format=duration.

  • Wenn sich der Schnitt ändert, verschieben Sie Nahaufnahmen, Untertitel und den Titel durch die QUELLzeit (alte Zeitleiste -> Quelle -> neue Zeitleiste), niemals um eine Konstante.

  • Eine Überlagerung, die an einem Schnitt endet (eine Nahaufnahme vor dem Abspann), läuft genau bis zu diesem Schnittbild; ein Untertitel endet mit seinem Clip.

  • Fangen Sie jeden Zoomwechsel, jedes Nahaufnahmen-Ende und jede Untertitelkante, die innerhalb von 6 Bildern eines Verbindungspunkts liegt, AUF diesen Verbindungspunkt ein (ein Nahaufnahmen-Start nur, wenn der Verbindungspunkt unmittelbar davor liegt). Zwei Bildwechsel im Abstand von wenigen Bildern werden immer als Fehler wahrgenommen; bei einem Bild wirken sie wie ein Schnitt.

  • Geben Sie dem allerletzten Segment einen kleinen Rest (~0,5 s), damit der letzte Untertitel und das letzte Wort nicht abgeschnitten werden.

7. Ausliefern

Der Master-Output von cut_and_concat.sh ist in voller Qualität (neu codiert bei crf 18). Wenn er durch ein Tool mit Dateigrößenbeschränkung muss, erstellen Sie eine sekundäre komprimierte Kopie für diesen Zweck, anstatt den Master zu komprimieren:

ffmpeg -nostdin -y -i final_output.mp4 -c:v libx264 -preset slow -crf 24 -pix_fmt yuv420p -c:a aac -b:a 128k final_output_share.mp4 -loglevel error

Wenn der Benutzer auch dynamische Punch-in/Zoom-Crops für Dynamik wünscht, siehe den Zoom-Skill – dieser kann entweder den Output dieses Skills übernehmen und neu schneiden oder (effizienter) Sie können beide in einem Durchgang kombinieren, indem Sie die pro-Segment-Filterketten aus dem Zoom-Skill direkt in die dritte Spalte von selections.txt schreiben, bevor Sie cut_and_concat.sh einmal ausführen. Eine Drehung ins Hochformat, falls erforderlich, wird separat behandelt (gehört zu keinem der beiden Skills) – fragen Sie den Benutzer, da dies nicht immer gewünscht wird.

Plattformhinweise

  • macOS hat standardmäßig kein GNU timeout – umwickeln Sie ffmpeg-Aufrufe nicht damit; sie sind für kurze Clips schnell, und die Zeitüberschreitungs-/Hintergrundverarbeitung des aufrufenden Tools deckt den langlaufenden Ganzdatei-Durchlauf in Schritt 2 ab.
  • Wenn Sie selbst eine while read ...; done < file-Schleife schreiben (anstatt die gebündelten Skripte zu verwenden) und darin ffmpeg aufrufen, fügen Sie -nostdin zum ffmpeg-Aufruf hinzu und leiten Sie dessen stdin von /dev/null um – andernfalls verbraucht ffmpeg Zeilen, die für das read der Schleife bestimmt sind, und verfälscht, welcher Zeitstempel zu welcher Iteration gehört, ohne erkennbaren Fehler.

Nach dem Schnitt: Zoom und Untertitel durchlaufen den Plan-editor

Wenn das geschnittene Video auch Zoom/Punch-ins (Zoom-Skill) und/oder Untertitel (Untertitel-Skill) erhalten soll, ist der Standard des Benutzers der Plan-editor-Skill: ein interaktives Klick-auf-Wort-Werkzeug, in dem sie den Zoom mit Ihnen entscheiden und Untertiteltext in denselben Sätzen korrigieren („Izmeni tekst"). Behalten Sie den pro Clip behaltenen Text aus dem Plan dieses Skills – er wird zu sentences.txt dieses Werkzeugs (eine Zeile pro geschnittenem Clip, gleiche Reihenfolge wie selections.txt).

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Verwandte Skills