Communitygithub.com

Video-Cut

Verwandelt ein langes, unbearbeitetes Video in einen kompakten, ansehbaren Erstschnitt – entscheidungsfreudig, inhaltsbewusst und selbstgeprüft.

Was ist Video-Cut?

Diese Fähigkeit wandelt ein langes, unbearbeitetes Video (YouTube-URL oder lokale Datei) in einen kompakten, ansehbaren Erstschnitt um. Sie ist ideal, wenn die Anforderung lautet „Halbieren“, „die langweiligen Teile herausschneiden“ oder „einen ersten Rohschnitt erstellen“. Die Fähigkeit ist nicht für Detailarbeit wie Wort-für-Wort-Füllerentfernung, Multi-Kamera-Schnitt oder Farb-/Audiokorrektur gedacht – diese Aufgaben sind späteren Politur-Durchgängen vorbehalten. Der menschliche Redakteur (der Benutzer oder das Modell) trifft die redaktionelle Entscheidung, WAS behalten wird; die gebündelten Skripte übernehmen die mechanische Präzision wie Grenzanpassung, Leerlauf-Wiederherstellung, speichersicheres Rendern und Selbstprüfung. Voraussetzung ist die Fähigkeit `/video-understand`, die zuerst ausgeführt werden muss, um validierte Medien, Transkript, Analyse und Zeitleiste bereitzustellen. Der Workflow besteht aus sechs Schritten: Herunterladen, Transkribieren, Diagnostizieren, redaktionelle Entscheidung von Hand schreiben, Erweitern/Auto-Beschleunigen/Rendern und Selbstprüfung. Integritätsprüfungen stellen sicher, dass keine Wörter abgeschnitten werden, keine schwarzen Bilder entstehen, die A/V-Synchronisation intakt ist und der endgültige Schnitt in einer Zusammenfassung („first_cut_report.md“) dokumentiert wird. Die Option der Auto-Varigeschwindigkeit (Auto-Varispeed) verändert das Sprechtempo, ohne den Inhalt zu beeinflussen, und ist separat meldepflichtig.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/WhiteTowerAI/cut-as-code/tree/main/skills/video-cut

In Ihrer bevorzugten KI fragen

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

Dokumentation

Video Cut

Ein langes unbearbeitetes Video wird in einen kompakten, ansehbaren Erstschnitt verwandelt – entscheidungsfreudig, inhaltsbewusst und selbstgeprüft. Der Mensch (Sie, das Modell) trifft die redaktionelle Entscheidung, WAS behalten wird; die gebündelten Skripte übernehmen die mechanische Präzision (Grenzanpassung, Leerlauf-Wiederherstellung, speichersicheres Rendern, Selbstprüfung).

Wann verwenden

  • Ein rohes/unbearbeitetes Video (YouTube-URL oder lokale Datei) muss zu einem engeren Schnitt werden.
  • Die Anforderung lautet „Halbieren“, „die langweiligen Teile herausschneiden“, „einen ersten/rohen Schnitt erstellen“.
  • NICHT für: Wort-für-Wort-Mikrochirurgie bei Füllwörtern, Multi-Kamera-B-Roll-Montage, Farb-/Audiokorrektur – das sind spätere P1/P2-Politur-Durchgänge. Diese Fähigkeit ist P0: Diagnose validieren + einen soliden Schnitt erstellen.

Abhängigkeiten

/video-understand ist eine Voraussetzung. Führen Sie es zuerst aus und verwenden Sie dessen validierte Medien, Transkript, Analyse und Zeitleiste anstatt sie in dieser Fähigkeit neu zu erstellen. Überprüfen Sie vor dem Start, ob es installiert ist. Wenn nicht, warnen Sie den Benutzer, dass diese Voraussetzung fehlt, und stoppen Sie, bevor Sie Medien verarbeiten.

Aktivieren Sie eine beliebige Umgebung, die diese Komponenten enthält (gehen Sie NICHT von einem bestimmten Conda-Umgebungsnamen aus):

  • yt-dlp (Download), ffmpeg/ffprobe (Schnitt/Rendering/Prüfung) im PATH
  • Python mit faster-whisper (CPU funktioniert: device=cpu, compute_type=int8) Überprüfen Sie zuerst: yt-dlp --version, ffmpeg -version, python -c "import faster_whisper".

Projektprotokoll-Workflow

Verwenden Sie diese dauerhaften Projektdateien:

work/cut/edit-plan.json          # nur selbst verfasste keep/drop-Entscheidungen
work/timeline.json               # generierte Präzisionsbereiche + Quell-/Programmzuordnung
review/01-cut/cut-summary.md
review/01-cut/timeline-map.png
review/01-cut/boundary-review.mp4
review/01-cut/full-proxy.mp4  # optional: gesamte Programm-Nachverfolgung

Jede kanonische Entscheidung hat eine stabile id, action (keep oder drop), start_s, end_s, reason und semantische/Transkript-evidence_refs. Keep-Entscheidungen sind chronologisch; V1 unterstützt keine neu angeordneten oder duplizierten Quellclips.

Wiederverwenden Sie die gemeinsame Beweisebene, anstatt erneut zu transkribieren oder zu diagnostizieren:

python skills/video-understand/scripts/transcribe.py work/cache/audio16k.wav work/understand/transcript
python skills/video-understand/scripts/analyze.py work/understand/transcript.json work/understand/analysis.json

Die vorhandenen Präzisionsskripte akzeptieren den kanonischen Plan. Erweitern Sie wortgeschützte Grenzen, weisen Sie optional lineare variable Geschwindigkeit zu und generieren Sie dann die gemeinsame Zeitleiste:

python skills/video-cut/scripts/build_edit.py work/cut/edit-plan.json work/understand/transcript.json work/cache/edit-final.json
python skills/video-cut/scripts/assign_speed.py work/cache/edit-final.json work/understand/transcript.json
python skills/video-understand/scripts/build_timeline.py work/cache/edit-final.json work/timeline.json --fps-num SOURCE_FPS_NUM --fps-den SOURCE_FPS_DEN

Verwenden Sie die exakte rationale FPS aus work/understand/media.json; runden Sie niemals 30000/1001 auf 30/1. Überprüfen Sie timeline-map.png und das kurze boundary-review.mp4. Generieren Sie full-proxy.mp4 nur, wenn die gesamte Programm-Nachverfolgung überprüft werden muss. Schreiben Sie das Ergebnis in cut-summary.md und verweisen Sie den Betriebsprüfungsbericht auf diese Datei.

Zeichnen Sie den Zeitleistenbeitrag mit seiner erforderlichen Quelleingabe auf, aktualisieren Sie die Betriebs-Ganzzahl revision und setzen Sie based_on auf die genaue verwendete Understanding-Revision:

"render": {
  "kind": "timeline-transform",
  "input": "../input/original-video.mp4",
  "plan": "timeline.json"
}

Der gemeinsame Auslieferungsrenderer codiert die aktive Sequenz, nachdem alle Revisionsprüfungen bestanden sind.

Standalone-Kompatibilitäts-Workflow

Die untenstehenden Legacy-Dateien und -Befehle bleiben während der Migration unterstützt. build_edit.py akzeptiert sowohl edit_coarse.json als auch kanonische decisions[]; cut_render.py akzeptiert sowohl edit_final.json als auch timeline.json; das transcribe.py dieser Fähigkeit ist ein Kompatibilitäts-Wrapper um ../video-understand/scripts/transcribe.py.

Behalten Sie alle Zwischendateien unter work/ und liefern Sie sie im Projektstammverzeichnis aus:

work/source.mp4            # heruntergeladenes Original
work/audio16k.wav          # 16k Mono-Audio für Whisper
work/transcript.json/.srt  # Wort-Zeitstempel
work/analysis.json         # Diagnose (Stille, Füller, Läufe)
work/edit_coarse.json      # *** IHRE redaktionelle Entscheidung (handgeschrieben) ***
work/edit_final.json       # erweiterte, enge Render-Segmente (generiert; enthält geschwindigkeit pro Segment)
work/selfcheck/            # Schnitt-Neu-Transkription + Frame-Zusammenfügung
first_cut.mp4              # DAS AUSLIEFERUNGSERGEBNIS
first_cut_report.md        # Schnitt- + Selbstprüfungsbericht

Die Pipeline (6 Schritte)

1. Herunterladen

Höchste erreichbare Qualität + Audio. Der Standard-Player-Client schlägt oft fehl (nicht verfügbar / DRM / Anmeldung). Der zuverlässige Fallback ist der android-Client:

yt-dlp --extractor-args "youtube:player_client=android" \
       -o work/source.mp4 "<URL>"

Wenn nur ein gemuxter 360p (Format 18) ohne Anmeldung erreichbar ist, akzeptieren Sie es und dokumentieren Sie die Einschränkung – HD DASH ist häufig DRM-/Anmelde-geschützt. Extrahieren Sie dann das Audio:

ffmpeg -y -i work/source.mp4 -ac 1 -ar 16000 work/audio16k.wav

2. Transkribieren (wortgenau)

python scripts/transcribe.py work/audio16k.wav work/transcript [base.en]

Erzeugt work/transcript.json (Segmente + Start/Ende pro Wort) und .srt. faster-whisper, CPU/int8, VAD an, word_timestamps=True. Nicht-Englisch: Übergeben Sie ein mehrsprachiges Modell + --lang, z.B. python scripts/transcribe.py work/audio16k.wav work/transcript medium --lang zh (die .en-Modelle sind nur für Englisch). Überprüfen Sie die Sprache zuerst an einer kurzen Probe. Hinweis: Whisper entfernt die meisten vokalisierten „hm/äh“ – SIE SIND NICHT IM TRANSKRIPT MESSBAR, Daher muss die Füllererkennung die lexikalische Wortsuche unten mit der Stillelückenanalyse kombinieren und sich nicht allein auf den Transkripttext verlassen.

3. Diagnostizieren („sehen“ + „lesen“)

python scripts/analyze.py work/transcript.json work/analysis.json

Erkennt: Führende/nachlaufende Stille, Wortzwischenstille ≥0.8s (mit dem Wort, dem sie folgt), Fülleranzahl, WPM, Sprechverhältnis, nahezu identische Wiederholungen, Monologe >40s (Kandidaten für Abschweifungen).

Um das Bild zu sehen, entnehmen Sie etwa alle 2s ein Bild in ein Kontaktblatt und lesen Sie es selbst; bestätigen Sie die Szenenstruktur / suchen Sie schwarze oder fehlerhafte Bilder:

ffmpeg -y -i work/source.mp4 -vf "fps=1/2,scale=240:-1,tile=10x10" -frames:v 1 work/contact.png
ffmpeg -i work/source.mp4 -vf "blackdetect=d=0.1:pic_th=0.98" -an -f null -

Bei einer einzelnen statischen Talking-Head-Aufnahme gibt es keine Szenenschnitte – erwarten Sie dies, und beachten Sie, dass die späteren Sprungschnitte normal sind, keine Störungen.

4. Über den Schnitt entscheiden – edit_coarse.json VON HAND schreiben

Dies ist der redaktionelle Kern. Lesen Sie das Transkript + die Analyse und schreiben Sie dann einen groben Plan von keep-Blöcken und drop-Spannen, die die gesamte Zeitleiste lückenlos/überlappungsfrei kacheln, jeweils mit in, out und einem einzeiligen reason. Komprimieren Sie langsame Einleitungen auf einige aussagekräftige Nuggets; behalten Sie Substanz als große Blöcke; entfernen Sie klare Abschweifungen/Geschwafel. Behalten Sie die chronologische Reihenfolge bei; die kanonische V1-Zeitleiste lehnt Neuordnungen ab. Zielen Sie darauf ab, die Laufzeit etwa zu halbieren.

  • Formatspezifikation + ein reales Arbeitsbeispiel: reference/edit_coarse.schema.md.
  • Richten Sie jede Blockgrenze an einem Satz-/Klauselende aus – beginnen/stoppen Sie niemals mitten im Satz oder bei einem Stottern. Verwenden Sie:
    python scripts/inspect_bounds.py work/edit_coarse.json work/transcript.json
    
    Es akzeptiert sowohl Legacy-keep[]- als auch kanonische decisions[]-Pläne und gibt die Wörter aus, die jede Grenze überspannen, sodass Sie sie auf saubere Kanten verschieben können.

5. Erweitern → Auto-Geschwindigkeit → Rendern

Wandeln Sie grobe Blöcke in enge, störungsfreie Render-Segmente um, normalisieren Sie das Sprechtenpo, und rendern Sie dann:

python scripts/build_edit.py   work/edit_coarse.json work/transcript.json work/edit_final.json 1.5
python scripts/assign_speed.py work/edit_final.json   work/transcript.json   # fügt Geschwindigkeit pro Segment hinzu
python scripts/cut_render.py    work/edit_final.json   work/source.mp4 first_cut.mp4
  • build_edit.py teilt jeden Block bei internen Pausen > SPLIT_GAP (4. Argument, z.B. 1.5s) und trimmt jede Grenze IN DIE STILLE (LEAD 0.10s / TRAIL 0.30s), sodass kein Wort abgeschnitten wird und Stille zurückgewonnen wird. Niedrigerer SPLIT_GAP = enger, aber abgehackter; für einen langsamen, bedächtigen Sprecher bevorzugen Sie ~1.5, nicht 0.6 (vermeidet zuckende Mikroschnitte).
  • assign_speed.py (automatische variable Geschwindigkeit) – gruppiert Render-Segmente nach decision_ref, misst das Sprechtenpo jeder selbst verfassten keep-Entscheidung und schreibt einen gemeinsamen speed-Faktor plus die resultierende out_dur jedes Segments zurück in edit_final.json. Tempo bereits innerhalb des Komfortbandes bleibt bei 1.0; außerhalb des Bandes bewegt es sich nur zum nächsten Grenzwert des Komfortbandes. Benachbarte Entscheidungsblöcke unterscheiden sich um höchstens 0.08x, um „pumpende“ Übergänge zu vermeiden. Es ändert nur das Tempo – niemals, welcher Inhalt behalten wird. Lesen Sie die gedruckte Tabelle vor dem Rendern:
    • Metrik: Wörter/Minute (Englisch) – wechselt automatisch zu Zeichen/Minute für CJK (zh/ja/ko).
    • Standardwerte sind Erstlauf-Startpunkte, keine validierten Konstanten: Komfortband 145–185 WPM und Geschwindigkeit begrenzt auf 1.0–1.3. Dies ist nur Beschleunigung: langsame Entscheidungsblöcke können gestrafft werden, während natürliche schnelle Lieferung bei 1.0 bleibt. Kurze Entscheidungsblöcke (<3.5s / <6 Wörter) sind zu verrauscht, um gemessen zu werden, und übernehmen den globalen Faktor.
    • Die Rate wird nach der Stille-Rückgewinnung gemessen, daher liest sie sich höher als der Brutto-WPM und ist näher an der Artikulationsrate. Die Überprüfung der gedruckten Tabelle ist tragend: überfliegen Sie sie und stimmen Sie deadband auf den Sprecher ab, bevor Sie rendern, vertrauen Sie nicht blind den Standardwerten.
    • Einstellungen (k=v): mode=segment|global|off (Standard segment; global=ein Faktor für das gesamte Video, off=deaktivieren), deadband=lo,hi, min_speed=/max_speed=, min_seg=/min_words=, lang=auto|en|cjk. Um die Funktion vollständig zu überspringen, führen Sie diesen Schritt einfach nicht aus – cut_render.py behandelt eine fehlende speed als 1.0.
  • cut_render.py verwendet N separate gesuchte Eingaben + concat-Filter, einzelne Neucodierung. Dies ist zwingend: N-maliges Trimmen von EINER decodierten Eingabe bewirkt, dass ffmpeg den gesamten decodierten Stream puffert (zig GB für ein langes Video). Siehe reference/pitfalls.md. Wenn Segmente eine speed tragen, passt es die Zeitsteuerung jeder Eingabe an (setpts Video / atempo Audio) und normalisiert fps/Zeitbasis/Abtastrate pro Eingabe vor dem Concat, sodass A/V synchron bleibt; ohne Geschwindigkeit fällt es auf den exakten Originalgraphen zurück.
  • Abschließender Vergleich: video-edit-compare liest die kanonische Zeitleiste plus die tatsächliche endgültige Auslieferung. Es projiziert endgültige Pixel zurück auf die Quellzeit, dehnt varispeed-Clips auf ihre Quellendauer und zeigt verworfene Bereiche als Schwarz an.

6. Selbstprüfung – nicht als erledigt erklären, bis dies bestanden ist

# Protokoll-Präzisions-Regressionsprüfung (vom Repository-Stammverzeichnis aus ausführen)
python skills/video-cut/scripts/check_project_protocol.py
# den fertigen Schnitt neu transkribieren
ffmpeg -y -i first_cut.mp4 -ac 1 -ar 16000 work/selfcheck/cut_audio16k.wav
python scripts/transcribe.py work/selfcheck/cut_audio16k.wav work/selfcheck/cut_transcript
# Inhalts- + Füller- + Grenzprüfung
python scripts/verify_cut.py work/edit_final.json work/transcript.json work/selfcheck/cut_transcript.json
# Bild- / Schwarz- / Verbindungsprüfung (Verbindungszeiten verwenden die out_dur nach der Geschwindigkeit, daher bleiben sie genau)
python scripts/selfcheck_frames.py work/edit_final.json first_cut.mp4 work/selfcheck
# A/V-Synchronisation + keine verbleibende Stille
ffprobe -v error -select_streams v:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffprobe -v error -select_streams a:0 -show_entries stream=duration -of csv=p=0 first_cut.mp4
ffmpeg -i first_cut.mp4 -af silencedetect=noise=-32dB:d=1.5 -f null -

Bestandenschwellen:

PrüfungBestandensbedingung
Schwarze Bilderkeine
Verbindungsbildersauber – nur natürliche Kopfsprünge, kein Schwarz/Einfrieren/Riss
A/V-SynchronisationVideodauer vs. Audiodauer innerhalb von ~1 Frame (≈30ms); insgesamt ≈ final_duration_s_after_speed bei varispeed
Stille ≥1.5s0 (Sprechverhältnis sollte deutlich steigen)
Verworfenes/doppeltes Segmentkeine – alle wichtigen Inhalte vorhanden (difflib ~0,90 ist OK; niedrigeres Verhältnis ist normalerweise Transkriptionsrauschen des zweiten Durchgangs bei gemurmeltem Sprechen, kein Verlust – durch Schlüsselwort-Präsenz verifizieren, bevor Sie dem Schnitt die Schuld geben)
Abgeschnittene Halbsätzekeine – Grenzen landen in Stille / an Satzenden

Ehrlicher Füller-Vorbehalt: Absatzweises Schneiden wird NICHT „fast keine Füller“ erreichen. Die Dichte pro Minute kann sogar steigen, weil die beibehaltene Substanz gesprächig ist. Berichten Sie dies ehrlich; die Entfernung von Füllwörtern auf Wortebene gehört in P1/P2 (und würde einen Einzel-Talking-Head sichtbar abgehackt machen).

Schließlich

Schreiben Sie first_cut_report.md: Quellenzusammenfassung, was geschnitten wurde & warum, die Selbstprüfungstabelle, und alle ehrlichen Vorbehalte (Qualitätsgrenze durch 360p-Quelle, Füllerdichte usw.). Wenn varispeed angewendet wurde, legen Sie es offen: wie viele Segmente zeitlich angepasst wurden und den Geschwindigkeitsbereich (aus der Tabelle von assign_speed.py / speed_params), sodass der Leser weiß, dass der Schnitt nicht 1:1 Echtzeit ist. Beachten Sie auch, dass die Füller-pro-Minute-Zahl von verify_cut.py nach der Beschleunigung etwas höher gelesen wird (gleiche Wörter, kürzere Minuten) – ein Darstellungsartefakt, keine hinzugefügten Füller.

Schlüsselprinzipien (die hart erarbeiteten)

  • Sie entscheiden über den Inhalt; Skripte entscheiden über die Bilder. Schreiben Sie edit_coarse.json von Hand; lassen Sie build_edit.py die Präzision und assign_speed.py das Tempo übernehmen.
  • Geschwindigkeit beeinflusst das Tempo, niemals den Inhalt. Auto-Varispeed gibt allen Render-Segmenten von einem decision_ref die gleiche Geschwindigkeit, bewegt außerhalb des Bandes liegendes Tempo nur zum nächsten Grenzwert des Komfortbandes, begrenzt benachbarte Entscheidungen auf ein Delta von 0,08x und begrenzt die Ausgabe auf 1.0–1.3. atempo bewahrt die Tonhöhe. Überprüfen Sie die Tabelle; mode=off oder überspringen Sie den Schritt, um zu deaktivieren.
  • Schneiden Sie niemals ein Wort an. Grenzen fallen immer in die Stille.
  • Nur speichersicheres Rendern (N gesuchte Eingaben + concat). Niemals mehrere Trims von einer Eingabe.
  • Seien Sie entscheidungsfreudig. Treffen Sie vernünftige Entscheidungen und fahren Sie fort; fragen Sie nicht übermäßig nach.
  • Selbstprüfung ist nicht verhandelbar. Neu transkribieren + Bilder prüfen, bevor Sie die Fertigstellung erklären.
  • Siehe reference/pitfalls.md für die vollständige Liste der Fallstricke und Korrekturen.

Individual skills in this repo

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

Verwandte Skills