Video bearbeiten (Bildschirmaufnahme / OBS / Vortrag)
Script-Kit: scripts/ in diesem Skill (prep.sh, transcript_txt.py, ocr_scan.py,
cam_flags.py, df_enhance.py, build_edl.py, render.py, verify_output.py,
chapters.py, overview.py, job.example.json, selftest.sh). Führe sie aus einer Kopie in
<workdir>/scripts/ aus, damit ein Job nie vom Skill-Verzeichnis abhängt. scripts/selftest.sh beweist
eine vollständige Installation in wenigen Minuten.
Eingaben
<src>: Die Aufnahme, normalerweise die neueste~/Desktop/*.mov(OBS-BenennungYYYY-MM-DD HH-MM-SS.mov). Falls mehrere aktuelle Aufnahmen existieren, bestätige welche VOR dem Start der langen Pipeline – das Bearbeiten des falschen Videos verschwendet eine Stunde.<target_minutes>: Frage, falls nicht angegeben; typisch 20-30 aus einer 45-90 minütigen Quelle.<workdir>: Frisches Scratch-Verzeichnis, z.B./tmp/<session>/edit.- Toolchain:
ffmpeg6+,python3,mlx_whisper, DeepFilterNet3, Pillow/numpy/soundfile, Apple Vision (pyobjc-framework-Vision/-Quartz).
Schritte
- Erkundung, niemals die Quelle anfassen.
ffprobe <src>(Auflösung, fps, Audio). Arbeite nur mit Kopien/Extrakten in<workdir>. - Vorbereitung.
prep.sh "<src>" $W:orig48.wav,mono16.wav,frames/(1 pro 2 s),camall/(Webcam-Ausschnitt bei 1 fps, Geometrie automatisch aus der Auflösung abgeleitet),sheet_overview.jpg,silences_raw.txt(nur Diagnose) undtranscript.json(mlx_whisper large-v3-turbo, Wort-Zeitstempel, ~4 min). Whisper läuft nach der Rückkehr von prep im Hintergrund weiter – starte JETZTdf_enhance.py orig48.wav df_enhanced.wav(DeepFilterNet3, ~6 min CPU), es ist unabhängig. - Lies das gesamte Transkript (3 Blöcke via
transcript_txt.py ... --from/--to). Schreibe Behaltens-Bereiche (Quellsekunden) injob.json -> keep. Stilletrimmen ist gering (~2 von 47 min); die echten Minuten kommen von Inhaltsentscheidungen. Whisper informiert selbst: Ein 10+ Mal wiederholter Satz oder leere Segmentläufe = Totschweigen, schneide es. - Visueller Standbild-Durchlauf. „Nichts passiert“ ist oft visuell statisch, NICHT still. Frame-Differenz der 0,5 fps Frames: <1% Pixeländerung über ein ~10 s Fenster = inaktiv; Läufe zusammenführen, die durch <=1 s Blips getrennt sind; >=4 s zum Schneiden erforderlich; 0,5 s Überlappungen. Blinkende Cursor/Spinner simulieren Aktivität – maskiere oder erhöhe den Schwellwert; prüfe Zwischenframes auf Änderungs-und-Rückkehr-Bursts. Tippen ist Rauschen, nicht Stille: Gates verwenden RMS auf der verbesserten Spur (
pause.loud_db), niemals rohessilencedetect. - Eröffnung. Schneide alles vor dem ersten echten Inhalt. Wenn der Anfang langsam/langweilig ist, beginne mit der interessantesten Demo; optional kalter Einstieg mit 1-2 aufregenden Clips und dann eine Beschleunigung der Einleitung. Öffne niemals mit Hintergrundbild/Schwarz – ein abgehackter erster 30 s wirkt wie Müll.
- Leck-Scan (läuft während des Lesens).
ocr_scan.py scannachrunaufframes/: IPv4/v6,*.ts.net, E-Mails, API-Schlüssel, SSH-Material. Dichter 2 fps Durchlauf auf jedem Terminal-/Konfigurationslastigen Bereich (ocr_scan.py dense src.mov dense 600:60 ...). Statischer Text ->boxes(durchgehende Füllung); scrollende Terminalausgabe -> das gesamte Fenster verwischen (blurFenster +blur_regions, in Quellpixeln) für das Fenster – boxes pro Zeile übersehen Text zwischen Samples.127.0.0.1/localhostsind in Ordnung. Protokolliere jedes Fenster injob.json. - Privatsphären-Schnitte (Webcam).
cam_flags.py(Hand-am-Mund via Vision) +cam_flags.py --sheet S:DURgezoomte 2 fps Sheets jedes markierten Clusters. Schneide die Momente, die der Nutzer nicht veröffentlichen würde: Hand im Gesicht während einer Pause, den Schreibtisch verlassen, eine andere Person im Bild, Vollbild-Gesichtssegmente. Normale Denkposen und kleine Gesten sind in Ordnung. NIEMALS mitten im Satz für eine Geste schneiden – springe zur nächsten Satzgrenze und notiere, was verloren ging. - Zeitstempel-Schnitte des Nutzers sind wörtlich zu nehmen. „Schneide 0000 - 01:12“ -> setze es in
job.cuts(oderkeep), wende es genau an, dann überprüfe das Tempo um die Nahtstelle. - Audio-Master. Plausibilitätsprüfung: Korrelation zwischen verbesserter und Original > 0,95 (
df_enhance.pygibt es aus). Die Standard-audio_chainist Hochpass 75, Schnitte/Anhebungen um 220 Hz / 3,2 kHz / 9 kHz, De-Esser, 3:1 Kompressor; entferne einen dauerhaften Lüfterton durch Hinzufügen einesequalizerTerms;render.pyführt den Zwei-Durchgang loudnorm auf -16 LUFS / -1,5 dBTP durch. Das unberührte Mikrofon bleibt als Audiospur 2. - EDL + Render.
build_edl.py->segments.json(Pausen >0,7 s innerhalb von Behaltensbereichen auf 0,4 s verkürzt; auf die abgetastete Bildrate geschnappt; <0,3 s verworfen).render.py: gruppierte paralleleh264_videotoolbox-Kodierungen, concat-c copy, beide Spuren muxen. Es ist pro Gruppe neustartbar – falls eine Gruppe fehlschlägt, reparieren und erneut ausführen, unveränderte Gruppen werden übersprungen. Liefere 1080p, sofern nicht anders gewünscht (4K verdoppelt die Renderzeit für nichts). - Verifiziere vor der Auslieferung.
verify_output.pybeendet sich mit Fehler, es sei denn, die Frame-Anzahl stimmt mit der EDL überein, beide Audiospuren passen zur Videodauer, und OCR der Ausgabe bei 4 fps über jedes Schwärzungsfenster findet keine Lecks. Ziehe auch Ausgabeframes bei jedem Privatsphären-Schnitt und bei 0:00-1:00 und SCHAU sie dir an. Verwende--fullfür einen vollständigen Leck-Durchlauf bei sensiblen Material. - Neu-Transkription des neuen Schnitts. Transkript, Untertitel und Kapitel müssen zur AUSGABE-Zeitleiste passen, nicht zur Quelle – führe erneut Whisper auf dem Schnitt aus (oder
chapters.py, das durch die EDL remappt) bevor SRT/Kapitel geschrieben werden. Liefere niemals SRT-Zeiten, die aus dem Quelltranskript übernommen wurden. - Metadaten + Auslieferung. Ohne zweimal gefragt zu werden: Kapitel-Zeitstempel (
chapters.py, >=3, erstes bei 0:00), 2-3 Titeloptionen, ~30 Tags unter 500 Zeichen (+2 Tag-/Beschreibungsvarianten falls gewünscht), Beschreibung, SRT pro Sprache (~42 Zeichen/Zeile; mehrsprachig auf Anfrage), alles als Klartext. Thumbnail via youtube-pack: Lies die letzten 10 Thumbnails des Nutzers für den Stil; Standard weiß/creme Hintergrund + schwarzer Text, kein Gesicht außer auf Anfrage, Logos/Text groß und übersichtlich. Dann verschiebe<output>.mp4(und SRTs/Metadaten) nach~/Downloadsundopendie Datei / öffne den Ordner in der Standard-App.
Ausgaben
<Thema> - JJJJ-MM-TT - edit.mp4(1080p, 2 Audiospuren) in~/Downloads, in der Standard-App geöffnet.<workdir>:job.json,segments.json,group_bounds.json,vf_<n>.txt, Schwärzungs-/Privatsphärenprotokolle.~/Downloads: SRTs,metadata.txt(Titel, Beschreibung, Tags, Kapitel).- Optional auf Anfrage: Thematische Untervideos, aus derselben Quelle geschnitten, jeweils mit eigenen Kapiteln.
Kombiniert mit
whisper/DFN3 (im Kit) -> video-edit (verifiziertes mp4 in ~/Downloads) -> youtube-pack (thumbnail.png) -> Browser-Upload zu YouTube Studio, konfiguriert wie die anderen Videos des Nutzers.
Regeln
- Ändere niemals die Quellaufnahme.
- Ziellänge ist ein Ziel; wenn sich der Inhalt nicht ohne Ausdünnung des Vortrags verkürzen lässt, liefere leicht über und benenne die nächsten beiden Schnitte.
- Schneide ganze Abschweifungen, bevor du mehr Pausen trimmst; behalte Hardware-Gespräche, Live-Demos, ehrliche Einschränkungen, die Zusammenfassung.
- Beende immer mit: Verschieben nach ~/Downloads + öffnen.
- Berichte getreu: Du kannst das Ergebnis nicht hören – sage das und verweise auf Spur 2.
- Separat aufgenommene Audiospuren (Discord/Craig) existieren normalerweise nicht; überprüfe Desktop/Downloads/iCloud/Sprachmemos, falls nicht vorhanden, verwende das OBS-Mikrofon und sage das.
- Bei Anfrage nach Speicherplatz: Lösche alte nicht akzeptierte Entwürfe/Varianten, behalte die Quelle und das Finale.
- Multi-Personen-Podcasts: Finde die RICHTIGEN Audiospuren (normalerweise 2 von vielen), ordne Audio dem richtigen Sprecher zu, wechsle das Video mit dem sprechenden, saubere Übergänge.
- Behaupte niemals, die Bearbeitung sei abgeschlossen, weil der Render beendet ist; nur
verify_output.py+ überprüfte Frames entscheiden das.
Verifizieren
verify_output.pygibt PASS aus (Frame-Anzahl, zwei Audiospuren, keine Lecks in Fenstern) und beendet sich mit 0.- Überprüfte Frames bei 0:00-1:00 und jedem Privatsphären-Schnitt (
verify_output.py --sheet 0:60). - SRT-Neu-Transkription Stichprobenprüfung gegen den Schnitt.
ffprobedie ausgelieferte Datei: Dauer, Auflösung, fps, 2 Audiostreams.
Bekannte Fehler
- Falsches Video bearbeitet -> bestätige Übereinstimmung von neuestem/Thema vor der Pipeline.
- Untertitel/Kapitel auf der Quellzeitleiste -> nach dem Schnitt neu transkribieren (Schritt 12).
- Hostname in der Ausgabe sichtbar -> scrollender Text zwischen OCR-Samples; verwische das gesamte Fenster, erweitere das Fenster, dann ausgabeseitige OCR.
- Silencedetect schneidet Tippen/Video-Wiedergabe -> Gate auf verbessertem Audio-RMS (
pause.loud_db), nicht nur Stille. - Abgehackter schwarzer Anfang -> überprüfe Ausgabe 0:00-1:00 Frames, kalter Einstieg mit echtem Inhalt.
cp -iÜberschreibaufforderung / Sandbox TCC blockiert~/Downloads-> verwende/bin/cpmit deaktiviertem Sandbox.- ffmpeg-Filter stirbt („Cannot allocate memory“) bei mehr als ~100
between()-Termen -> wenigerrender_groups. - Blinkender Cursor zählt als Aktivität in der Frame-Differenzierung -> maskiere/schätze Schwellwert, überprüfe Zwischenframes.
render.pyFrame-Konflikt -> es verweigert concat; leserender_<n>.log(-ssvor einem Nicht-Keyframe, defekter Decoder).- Whisper läuft noch, wenn du
transcript.jsonliest ->transcript_txt.pymeldet leere Segmente; warte auf das Ende vonwhisper.log.
Beispiele
- Talk vom 02.09.2026, 47 min -> 26 min: 32 Behaltensbereiche, 2 Privatsphären-Schnitte (9:52-9:58, 26:08-26:14), 2 Verwischungsfenster + 1 Box für einen
*.ts.net-Hostnamen, Render ~2 h Wandzeit, Leck nur durch ausgabeseitige OCR erfasst. - OBS-Tutorial-Session vom 24.09.2026: Nutzer lehnte ersten Schnitt ab („Hintergrundgeräusche, Tippen, Anfang sehr langweilig“) -> Tippgeräusche entfernt, besseren Einstieg gewählt, Transkripte neu erstellt, dann wörtlicher Kopfschnitt
0:00-1:12, Leck-Scan, weißes/Creme-Thumbnail mit größeren Logos, 2 Metadatenvarianten, nach Downloads verschoben. - Podcast (18.09.2026): 1h40m Video + 5 Kandidaten-Audiodateien -> identifizierte die 2 richtigen Pro-Sprecher-Spuren, ordnete Stimme Video zu, 1080p, Kopf trimmen, SRT + ES/AR/HI-Übersetzungen, Kapitel-Zeitstempel, Thumbnail mit beiden Sprechern, Text oben, kein schwarzer Hintergrund.