# Anforderungen: auto-video-cut Stand: 2026-03-20 (aktualisiert: KI-Features, Übergänge, Audio-Ducking) --- ## 1. Ziel `auto-video-cut` ist ein vollständig automatisiertes Kommandozeilen-Tool für Videoschnitt, -zusammenführung und Musikunterlegung. Keine GUI, keine manuelle Timeline. Zielgruppe: technisch versierte Einzelnutzer mit wiederholenden Video-Workflows. --- ## 2. Systemvoraussetzungen | Anforderung | Detail | |-------------|--------| | Python | >= 3.10 | | ffmpeg | Im PATH verfügbar (für alle Video-/Audio-Operationen) | | ffprobe | Im PATH verfügbar (für Metadaten-Abfragen) | | Betriebssystem | Plattformunabhängig (getestet unter Linux/WSL, macOS, Windows) | --- ## 3. Python-Abhängigkeiten | Paket | Version | Verwendung | |-------|---------|------------| | `typer` | >= 0.12 | CLI-Framework | | `pyyaml` | >= 6.0 | YAML-Konfiguration und Sequenz-Dateien | | `scenedetect[opencv]` | >= 0.6 | Szenen-Erkennung via ContentDetector | | `ffmpeg-python` | >= 0.2 | ffmpeg-Binding (Hilfsfunktionen) | | `discord.py` | >= 2.3 | Discord-Bot für Fernsteuerung | | `rich` | >= 13.0 | Fortschrittsanzeige und Terminal-UI | Optionale KI-Abhängigkeiten (`pip install -e ".[ai]"`): | Paket | Version | Verwendung | |-------|---------|------------| | `faster-whisper` | >= 1.0 | Lokale Sprach-Transkription (Whisper) | | `anthropic` | >= 0.40 | LLM-Anbindung für Auto-Kapitel, Highlights, Beschreibungen | Installation: `pip install -e .` CLI-Einstiegspunkt: `video-cut` --- ## 4. Funktionale Anforderungen ### 4.1 Stille-Erkennung und -Entfernung - **F-01** Das Tool erkennt Stille-Abschnitte in einem Video via `ffmpeg silencedetect`. - **F-02** Erkannte Stille-Abschnitte werden aus dem Video herausgeschnitten; die verbleibenden Ton-Abschnitte werden nahtlos zusammengefügt. - **F-03** Konfigurierbare Parameter: - `threshold_db` — Schwelle in dB, ab der Stille erkannt wird (Standard: `-40`) - `min_duration` — Mindestdauer in Sekunden, ab der Stille als solche gilt (Standard: `0.5`) - **F-04** Stille-Erkennung ist pro Clip in der Sequenz-Datei einzeln aktivierbar (`remove_silence: true` / `trim_silence: true`). ### 4.2 Szenen-Erkennung - **F-05** Das Tool erkennt Szenen-Grenzen via PySceneDetect (`ContentDetector`). - **F-06** Das Video wird an erkannten Szenen-Grenzen in einzelne Clips aufgeteilt und in einen Ausgabe-Ordner gespeichert. - **F-07** Konfigurierbare Parameter: - `threshold` — Empfindlichkeit der Szenen-Erkennung (Standard: `27.0`) ### 4.3 Clips zusammenführen - **F-08** Mehrere Video-Clips werden via `ffmpeg concat` zu einem einzigen Video zusammengeführt. - **F-09** Vor dem Zusammenführen werden Clips optional auf ein einheitliches Format re-encodet (H.264, AAC, yuv420p, 25fps), um Kompatibilitätsprobleme zu vermeiden. - **F-10** Optional: Intro-Clip vor dem ersten und Outro-Clip nach dem letzten Inhalt einfügen. ### 4.4 Hintergrundmusik - **F-11** Musik-Dateien werden aus einem konfigurierbaren Ordner (`resources/music/`) gelesen. - **F-12** Unterstützte Musikformate: `.mp3`, `.wav`, `.flac`, `.aac`, `.ogg` - **F-13** Auswahlmodus für Musik: - `random` — zufällig aus dem Ordner - `alphabetical` — erste Datei alphabetisch - `loop` — erste Datei alphabetisch (wird geloopt) - **F-14** Musik wird auf die Länge des Videos getrimmt (`-shortest`) oder geloopt (`-stream_loop -1`). - **F-15** Original-Audio und Hintergrundmusik werden gemischt via `ffmpeg amix` mit konfigurierbaren Lautstärken: - `volume_original` — Lautstärke des Original-Tons (Standard: `1.0`) - `volume_music` — Lautstärke der Hintergrundmusik (Standard: `0.3`) - **F-16** Hat das Video keinen Audio-Track, wird die Musik direkt als einziger Audio-Track eingefügt. - **F-17** In der Sequenz-Datei kann eine konkrete Musikdatei oder `"random"` angegeben werden; Lautstärken sind pro Sequenz überschreibbar. ### 4.5 Text-Einblendungen - **F-18** Text wird als Standbild-Clip auf einem konfigurierbaren Hintergrund (Farbe oder schwarz) gerendert via `ffmpeg drawtext` + `lavfi color`. - **F-19** Text-Overlays können über laufende Video-Clips gelegt werden, mit optionaler Zeitbegrenzung (`enable='between(t,0,N)'`). - **F-20** Konfigurierbare Text-Optionen: - `content` — Text-Inhalt - `duration` — Anzeigedauer in Sekunden (für Standbild-Clips) - `font_size` — Schriftgröße (Standard: `72` für Clips, `48` für Overlays) - `font_color` — Schriftfarbe (Standard: `"white"`) - `background_color` — Hintergrundfarbe oder `"transparent"` (Standard: `"black"`) - `position` — `center` | `top` | `bottom` (Standard: `"center"`) - **F-21** Sonderzeichen im Text (`'`, `:`, `\`) werden für ffmpeg korrekt escapt. ### 4.6 Bilder als Clips - **F-22** Einzelne Bilder (`.png`, `.jpg`, `.jpeg`) werden in Video-Clips konvertiert (`ffmpeg -loop 1`). - **F-23** Konfigurierbare Anzeigedauer in Sekunden. - **F-24** Bilder werden auf die Zielauflösung skaliert und bei abweichendem Seitenverhältnis mit schwarzen Balken aufgefüllt (letterbox). - **F-25** Standard-Auflösung: 1920×1080, 25fps. ### 4.7 Sequenz-Verarbeitung - **F-26** Eine `sequence.yaml`-Datei definiert die Timeline des finalen Videos: Reihenfolge, Quellen und Verarbeitungsoptionen aller Elemente. - **F-27** Unterstützte Sequenz-Typen: | Typ | Beschreibung | |-----|-------------| | `video` | Einzelne Videodatei | | `image` | Standbild für konfigurierbare Dauer | | `text` | Text auf Hintergrundfarbe als Clip | | `folder` | Alle Medien in einem Ordner, sortierbar | - **F-28** Ordner-Einträge (`type: folder`) unterstützen Sortierung nach: - `alphabetical` — alphabetisch nach Dateiname - `date` — nach Änderungsdatum - **F-29** Datei-Pfade in der Sequenz werden aufgelöst: absolut → relativ → aus `resources/`-Unterordner. - **F-30** Musik-Konfiguration kann direkt in der `sequence.yaml` angegeben werden und überschreibt die globale `config.yaml`. ### 4.8 Batch-Verarbeitung - **F-31** Alle Video-Dateien in einem Ordner werden sequenziell verarbeitet. - **F-32** Unterstützte Video-Formate: `.mp4`, `.mov`, `.avi`, `.mkv` - **F-33** Jede Verarbeitungs-Option (Stille entfernen, Szenen, Musik) ist einzeln für den Batch aktivierbar. - **F-34** Ausgabe-Dateien werden in den konfigurierten Output-Ordner gespeichert. --- ## 5. Ressourcen-Struktur ``` resources/ ├── music/ ← .mp3, .wav, .flac, .aac, .ogg ├── videos/ ← Intros, Outros, Übergänge (.mp4, .mov, .avi, .mkv) └── images/ ← Titelkarten, Folien (.png, .jpg, .jpeg) ``` - **F-35** Der Ressourcen-Ordner ist über `resources.folder` in der Konfiguration frei wählbar. - **F-36** Das Tool gibt eine Warnung aus, wenn der Ressourcen-Ordner oder der Musik-Unterordner nicht existiert oder leer ist — kein harter Abbruch. --- ## 6. Konfiguration (`config.yaml`) Alle Parameter haben Standardwerte; eine Konfigurationsdatei ist optional. | Schlüssel | Typ | Standard | Beschreibung | |-----------|-----|---------|--------------| | `resources.folder` | string | `"./resources"` | Basis-Ordner für Ressourcen | | `music.mode` | string | `"random"` | Musik-Auswahlmodus | | `music.volume_original` | float | `1.0` | Lautstärke Original-Ton | | `music.volume_music` | float | `0.3` | Lautstärke Hintergrundmusik | | `videos.intro` | string | `null` | Dateiname des Intro-Clips | | `videos.outro` | string | `null` | Dateiname des Outro-Clips | | `videos.transitions` | bool | `false` | Übergangs-Clips einsetzen | | `images.title_card` | string | `null` | Dateiname der Titelkarte | | `images.duration` | int | `3` | Standard-Anzeigedauer für Bilder (s) | | `silence.threshold_db` | float | `-40` | Stille-Schwelle in dB | | `silence.min_duration` | float | `0.5` | Minimale Stille-Dauer in Sekunden | | `scenes.threshold` | float | `27.0` | Szenen-Erkennungs-Schwelle | | `output.format` | string | `"mp4"` | Ausgabeformat | | `output.folder` | string | `"./output"` | Ausgabe-Ordner | - **F-37** Fehlende Schlüssel in der Konfigurationsdatei werden mit Standardwerten aufgefüllt (Deep-Merge). - **F-38** Beim Laden der Konfiguration werden Warnungen für ungültige Lautstärke-Werte ausgegeben. --- ## 7. CLI-Befehle ### `video-cut cut` ``` video-cut cut --input VIDEO [--output DATEI] [--config CONFIG] [--remove-silence] [--scene-detect] ``` | Option | Beschreibung | |--------|-------------| | `--input`, `-i` | Eingabe-Videodatei (Pflicht) | | `--output`, `-o` | Ausgabedatei (Standard: `_no_silence.mp4`) | | `--config`, `-c` | Konfigurationsdatei | | `--remove-silence` | Stille entfernen | | `--scene-detect` | Szenen erkennen und aufteilen | ### `video-cut merge` ``` video-cut merge --inputs CLIP1 CLIP2 [...] --output DATEI [--intro CLIP] [--outro CLIP] [--no-normalize] ``` | Option | Beschreibung | |--------|-------------| | `--inputs` | Eingabe-Clips (Pflicht, mehrfach) | | `--output`, `-o` | Ausgabedatei (Pflicht) | | `--intro` | Optionaler Intro-Clip | | `--outro` | Optionaler Outro-Clip | | `--no-normalize` | Re-Encoding überspringen | ### `video-cut music` ``` video-cut music --input VIDEO [--output DATEI] [--config CONFIG] [--music-file DATEI] [--vol-orig 1.0] [--vol-music 0.3] ``` | Option | Beschreibung | |--------|-------------| | `--input`, `-i` | Eingabe-Videodatei (Pflicht) | | `--output`, `-o` | Ausgabedatei (Standard: `_music.mp4`) | | `--config`, `-c` | Konfigurationsdatei | | `--music-file` | Direkte Musikdatei (überschreibt config) | | `--vol-orig` | Lautstärke Original (Standard: `1.0`) | | `--vol-music` | Lautstärke Musik (Standard: `0.3`) | ### `video-cut batch` ``` video-cut batch --input ORDNER [--config CONFIG] [--remove-silence] [--scene-detect] [--music] ``` | Option | Beschreibung | |--------|-------------| | `--input`, `-i` | Ordner mit Videos (Pflicht) | | `--config`, `-c` | Konfigurationsdatei | | `--remove-silence` | Stille aus allen Videos entfernen | | `--scene-detect` | Szenen in allen Videos erkennen | | `--music` | Musik zu allen Videos hinzufügen | ### `video-cut sequence` ``` video-cut sequence --seq SEQUENZ.yaml [--config CONFIG] [--output DATEI] [--music/--no-music] ``` | Option | Beschreibung | |--------|-------------| | `--seq`, `-s` | Sequenz-Datei (Pflicht) | | `--config`, `-c` | Konfigurationsdatei | | `--output`, `-o` | Ausgabedatei (Standard: `output/output.mp4`) | | `--music` / `--no-music` | Musik hinzufügen oder nicht (Standard: an) | --- ## 8. Discord-Integration (Fernsteuerung) ### 8.1 Überblick Die Applikation soll über einen Discord-Bot ferngesteuert werden können. Der Bot läuft als Hintergrund-Prozess auf demselben Server wie `auto-video-cut` und empfängt Befehle über Discord-Slash-Commands. Ergebnisse und Fortschrittsmeldungen werden in den aufrufenden Discord-Kanal zurückgemeldet. ### 8.2 Architektur ``` Discord-Nutzer │ Slash-Command (/cut, /music, ...) ▼ Discord API │ discord.py Bot (auto_video_cut/bot.py) ▼ CLI-Logik (cutter, merger, audio, sequencer, ...) │ Ergebnis / Fortschritt ▼ Discord API → Antwort im Kanal ``` Der Bot ruft intern dieselben Python-Funktionen auf wie die CLI — kein separater Prozess, keine HTTP-API. ### 8.3 Konfiguration Neue Schlüssel in `config.yaml`: ```yaml discord: token: "BOT_TOKEN" # Discord-Bot-Token (Pflicht) allowed_channel_ids: # Whitelist der erlaubten Kanal-IDs - 123456789012345678 allowed_user_ids: # Whitelist der erlaubten Nutzer-IDs (optional) - 987654321098765432 upload_results: true # Fertige Videos direkt in Discord hochladen (≤ 25 MB) notify_on_complete: true # Abschluss-Meldung immer senden ``` - **F-39** Der Bot-Token wird aus der Konfigurationsdatei oder alternativ aus der Umgebungsvariable `VIDEO_CUT_DISCORD_TOKEN` gelesen. - **F-40** Befehle werden nur in explizit erlaubten Kanälen akzeptiert; alle anderen Anfragen werden still ignoriert. - **F-41** Optional: Whitelist auf bestimmte Discord-Nutzer-IDs einschränken. ### 8.4 Bot starten ```bash video-cut bot --config config.yaml ``` Der Bot läuft als Langzeit-Prozess (Blocking Event Loop). Empfohlen: `systemd`-Service oder `screen`/`tmux`-Session. ### 8.5 Slash-Commands Alle CLI-Befehle werden als Discord-Slash-Commands gespiegelt. Dateipfade beziehen sich immer auf den Server, auf dem der Bot läuft. #### `/cut` ``` /cut input: [remove_silence:true|false] [scene_detect:true|false] [config:] ``` - Schneidet ein Video (Stille entfernen und/oder Szenen aufteilen) - Antwort: Fortschritts-Embed → Abschluss-Embed mit Ausgabepfad #### `/merge` ``` /merge inputs: output: [intro:] [outro:] ``` - Fügt mehrere Clips zusammen #### `/music` ``` /music input: [config:] [music_file:] [vol_orig:1.0] [vol_music:0.3] ``` - Legt Hintergrundmusik unter ein Video #### `/batch` ``` /batch input: [config:] [remove_silence:true] [music:true] ``` - Verarbeitet alle Videos in einem Ordner #### `/sequence` ``` /sequence seq: [config:] [output:] [music:true|false] ``` - Rendert ein Video aus einer `sequence.yaml` #### `/status` ``` /status ``` - Zeigt laufende Jobs, Warteschlange und System-Status (ffmpeg vorhanden, Ressourcen-Ordner erreichbar) #### `/cancel` ``` /cancel [job_id:] ``` - Bricht den aktuellen oder einen bestimmten Job ab ### 8.6 Antwort-Format - **F-42** Jeder Befehl wird mit einem Discord-Embed bestätigt: Job-ID, Eingabe-Parameter, Startzeitpunkt. - **F-43** Während der Verarbeitung werden Fortschritts-Updates als bearbeitete Embed-Nachricht gesendet (alle ~10 Sekunden oder bei Meilenstein: Stille erkannt, Clips zusammengeführt, Musik gemischt). - **F-44** Bei Abschluss: Embed mit Ausgabepfad, Dauer der Verarbeitung, Dateigröße. - **F-45** Ist die fertige Datei ≤ 25 MB und `upload_results: true`, wird sie direkt in Discord hochgeladen. - **F-46** Bei Fehlern: Embed mit Fehlermeldung und dem betroffenen Verarbeitungsschritt (roter Embed-Rand). ### 8.7 Job-Verwaltung - **F-47** Jobs werden sequenziell in einer FIFO-Warteschlange abgearbeitet — kein paralleles Rendering, da ffmpeg die CPU auslastet. - **F-48** Jeder Job erhält eine eindeutige Job-ID (kurzer UUID-Präfix), die in allen Nachrichten angezeigt wird. - **F-49** Läuft bereits ein Job, wird der neue Job mit geschätzter Warteposition bestätigt (`"Job #3 in Warteschlange"`). - **F-50** `/cancel` bricht laufende ffmpeg-Subprozesse sauber ab (`process.terminate()`). ### 8.8 Sicherheit - **F-51** Dateipfade aus Discord-Nachrichten werden auf erlaubte Basis-Verzeichnisse beschränkt (konfigurierbar: `allowed_paths`). Path-Traversal-Angriffe (`../`) werden abgewiesen. - **F-52** Shell-Injection ist ausgeschlossen, da alle ffmpeg-Aufrufe als Argument-Listen via `subprocess` erfolgen (kein `shell=True`). - **F-53** Der Bot-Token wird niemals in Logs oder Discord-Nachrichten ausgegeben. ### 8.9 Neue Projektdatei ``` auto_video_cut/ └── bot.py ← Discord-Bot (discord.py, Slash-Commands, Job-Queue) ``` --- ## 9. Video-Übergänge und Effekte ### 9.1 Crossfade - **F-54** Zwischen zwei Clips kann ein Crossfade (weicher Übergang) eingefügt werden via ffmpeg `xfade` Filter. - **F-55** Konfigurierbare Parameter pro Sequenz-Eintrag: - `transition` — Übergangstyp: `crossfade` | `dissolve` | `wipeleft` (Standard: keiner) - `transition_duration` — Dauer in Sekunden (Standard: `0.5`) - **F-56** Globale Fade-Optionen: - `fade_in` — Einblende-Dauer am Anfang des Gesamtvideos - `fade_out` — Ausblende-Dauer am Ende des Gesamtvideos ### 9.2 Audio-Ducking - **F-57** Hintergrundmusik wird automatisch leiser wenn Original-Audio (Sprache) erkannt wird, via ffmpeg `sidechaincompress`. - **F-58** Konfigurierbare Ducking-Parameter: - `ducking` — aktivieren/deaktivieren (Standard: `false`) - `duck_threshold` — ab welcher Lautstärke die Musik abgesenkt wird (Standard: `0.02`) - `duck_ratio` — Stärke der Absenkung (Standard: `4.0`) - `duck_attack` — wie schnell die Musik leiser wird in Sekunden (Standard: `0.3`) - `duck_release` — wie schnell die Musik wieder lauter wird in Sekunden (Standard: `1.0`) ### 9.3 Fortschrittsanzeige - **F-59** Alle ffmpeg-Operationen zeigen einen Echtzeit-Fortschrittsbalken mit Prozent und geschätzter Restzeit via `rich`. - **F-60** ffmpeg wird mit `-progress pipe:1` gestartet; `out_time_ms` wird geparst und gegen die Gesamt-Dauer gerechnet. ### 9.4 Preview und Dry-Run - **F-61** `--preview` erzeugt eine niedrig aufgelöste Schnellversion (360p, ultrafast-Preset) im Temp-Ordner. - **F-62** `--dry-run` zeigt die geplante Verarbeitung ohne zu rendern: Clip-Liste, geschätzte Gesamtdauer, geschätzte Dateigröße. --- ## 10. KI-Features ### 10.1 Whisper-Transkription - **F-63** Audio wird aus dem Video extrahiert (WAV, 16kHz Mono) und lokal mit `faster-whisper` transkribiert. - **F-64** Konfigurierbare Whisper-Parameter: - `whisper_model` — Modellgröße: `tiny` | `base` | `small` | `medium` | `large-v3` (Standard: `base`) - `whisper_language` — Sprache oder `null` für Auto-Erkennung (Standard: `null`) - `whisper_device` — Gerät: `auto` | `cpu` | `cuda` (Standard: `auto`) - **F-65** Das Transkript enthält Wort-Level-Timestamps (Start, Ende, Konfidenz pro Wort). - **F-66** KI-Features sind optional: fehlt `faster-whisper`, wird eine verständliche Fehlermeldung ausgegeben mit Installationshinweis. ### 10.2 Automatische Untertitel - **F-67** Aus dem Whisper-Transkript wird eine `.srt`-Datei mit korrekten Timestamps erzeugt. - **F-68** Untertitel werden via ffmpeg `subtitles`-Filter ins Video eingebrannt. - **F-69** Konfigurierbare Stil-Optionen: Schriftgröße, Farbe, Umrissfarbe, Position. - **F-70** In der Sequenz-Datei pro Clip aktivierbar: `auto_subtitles: true`. - **F-71** Alternativ: bestehende `.srt`-Datei direkt einbrennen ohne Whisper. ### 10.3 Intelligentes Schneiden (Smart Cut) - **F-72** Füllwort-Erkennung: Deutsche und englische Füllwörter ("äh", "ähm", "also", "halt", "uh", "um") werden im Transkript erkannt und als Schnitt-Kandidaten markiert. - **F-73** Fehlstart-Erkennung: Sätze die abbrechen und neu begonnen werden, werden erkannt (Heuristik: kurzes Segment + Pause + ähnlicher Neubeginn). - **F-74** Pausen-Kürzung: Pausen zwischen Segmenten werden auf eine konfigurierbare Maximaldauer gekürzt (Standard: `1.0s` → `0.3s`). - **F-75** `--analyze-only` zeigt eine Aufschlüsselung aller erkannten Schnitt-Kandidaten (Typ, Zeitposition, eingesparte Sekunden) ohne das Video zu schneiden. - **F-76** Jede Schnitt-Kategorie (Füllwörter, Fehlstarts, Pausen) ist einzeln aktivierbar/deaktivierbar. - **F-77** In der Sequenz-Datei pro Clip aktivierbar: `smart_cut: true`. ### 10.4 Auto-Kapitel - **F-78** Das Whisper-Transkript wird an ein LLM (Claude oder lokales Modell via Ollama) gesendet, das inhaltliche Kapitel mit Titeln erzeugt. - **F-79** Unterstützte LLM-Provider: - `anthropic` — Claude API (API-Key aus Config oder `ANTHROPIC_API_KEY`) - `ollama` — lokales Modell (URL und Modellname konfigurierbar) - **F-80** Export-Formate für Kapitel: - YouTube-kompatibel (`0:00 Intro`, `0:45 Ankunft in Berlin`, ...) - Als `type: text`-Einträge für die Sequenz-Datei (Kapitelmarken einblenden) - **F-81** Maximale Kapitelanzahl konfigurierbar (Standard: `10`). ### 10.5 Highlight-Reel - **F-82** Transkript + Szenen-Erkennung → LLM bewertet jede Szene nach inhaltlichem Interesse (Schlüsselaussagen, Emotionen, Themenwechsel). - **F-83** Die besten Szenen werden chronologisch ausgewählt und zu einem Highlight-Video zusammengeschnitten. - **F-84** Ziel-Dauer des Highlight-Reels ist konfigurierbar (Standard: `60s`). - **F-85** Zwischen Highlight-Szenen werden automatisch Crossfades eingefügt. ### 10.6 Natürlichsprachliche Sequenz-Erstellung - **F-86** Eine natürlichsprachliche Beschreibung wird per LLM in eine vollständige `sequence.yaml` übersetzt. - **F-87** Das LLM erhält als Kontext: verfügbare Ressourcen (Musik, Intros, Bilder), Dateien im angegebenen Ordner, und das Schema der Sequenz-Datei. - **F-88** Die generierte Sequenz wird zur Bestätigung angezeigt, bevor optional direkt gerendert wird (`--execute`). --- ## 11. KI-Konfiguration Neuer Block in `config.yaml`: ```yaml ai: whisper_model: "base" whisper_language: null whisper_device: "auto" llm_provider: "anthropic" llm_model: "claude-haiku-4-5-20251001" anthropic_api_key: null ollama_url: "http://localhost:11434" ollama_model: "llama3" ``` - **F-89** Der Anthropic-API-Key wird aus der Config oder der Umgebungsvariable `ANTHROPIC_API_KEY` gelesen. - **F-90** Fehlt der API-Key, funktionieren alle Features außer Auto-Kapitel, Highlights und natürlichsprachliche Sequenzen. --- ## 12. Neue CLI-Befehle ### `video-cut smart-cut` ``` video-cut smart-cut --input VIDEO [--output DATEI] [--keep-fillers] [--no-false-starts] [--max-pause 1.0] [--analyze-only] ``` ### `video-cut transcribe` ``` video-cut transcribe --input VIDEO [--output DATEI.srt] [--model base] [--language de] ``` ### `video-cut subtitle` ``` video-cut subtitle --input VIDEO [--output DATEI] [--srt DATEI.srt] ``` ### `video-cut chapters` ``` video-cut chapters --input VIDEO [--output chapters.txt] [--format youtube|sequence] [--inject-titles] ``` ### `video-cut highlights` ``` video-cut highlights --input VIDEO [--output highlights.mp4] [--duration 60] ``` ### `video-cut describe` ``` video-cut describe "Beschreibung des gewünschten Videos" [--execute] [--output sequence.yaml] ``` --- ## 13. Nicht-funktionale Anforderungen - **NF-01** Kein GUI — ausschließlich Kommandozeile. - **NF-02** Alle Video-Operationen laufen über `subprocess` + `ffmpeg`/`ffprobe`; kein proprietäres Video-Framework. - **NF-03** Temporäre Dateien werden in einem `tempfile.TemporaryDirectory()` erzeugt und nach Abschluss automatisch gelöscht. - **NF-04** Fehlermeldungen erscheinen auf `stderr`; Fortschritts-Ausgaben auf `stdout`. - **NF-05** Exit-Code `0` bei Erfolg, `1` bei Fehler. - **NF-06** Ausgabe-Ordner werden automatisch angelegt, wenn sie nicht existieren. - **NF-07** Standardauflösung für generierte Clips (Text, Bilder): 1920×1080 @ 25fps, H.264, AAC. - **NF-08** Das Paket ist via `pip install -e .` installierbar (PEP 517, `setuptools`). - **NF-09** Der Discord-Bot läuft als Langzeit-Prozess; er blockiert nicht den CLI-Betrieb — beide Modi sind unabhängig voneinander nutzbar. - **NF-10** Discord-Befehle und CLI-Befehle rufen dieselbe interne Logik auf — keine duplizierte Implementierung. - **NF-11** KI-Features (`faster-whisper`, `anthropic`) sind optionale Abhängigkeiten — das Tool funktioniert ohne sie. - **NF-12** Whisper läuft lokal, keine Daten werden an externe Server gesendet (außer bei LLM-Provider `anthropic`). --- ## 14. Bekannte Einschränkungen - **E-01** `--no-normalize` beim `merge`-Befehl kann zu Kompatibilitätsproblemen führen, wenn die Clips unterschiedliche Codecs oder Framerates haben. - **E-02** `type: folder` in der Sequenz-Datei erkennt Dateitypen nur anhand der Dateiendung, nicht des tatsächlichen Inhalts. - **E-03** Text-Overlays setzen voraus, dass die Standard-Schriftart von ffmpeg (`default`) auf dem System verfügbar ist; für abweichende Fonts muss `fontfile` in der drawtext-Option ergänzt werden (aktuell nicht konfigurierbar). - **E-04** Szenen-Erkennung via `split_scenes` setzt PySceneDetect und OpenCV voraus; fehlt das Paket, wird eine klare Fehlermeldung ausgegeben. - **E-05** `music.mode: loop` wiederholt aktuell nur die erste alphabetische Datei, kein echter Playlist-Loop über mehrere Dateien. - **E-06** Discord-Uploads sind auf 25 MB begrenzt (Discord-Limit für reguläre Server). Größere Ausgabe-Videos können nur als Pfad-Referenz zurückgemeldet werden. - **E-07** Slash-Commands müssen einmalig bei Discord registriert werden (`bot.tree.sync()`); nach Deployment kann die Synchronisation einige Minuten dauern. - **E-08** Der Bot unterstützt nur einen Server gleichzeitig sinnvoll — `allowed_channel_ids` verhindert ungewollten Multi-Server-Betrieb. - **E-09** Whisper-Modelle `medium` und `large-v3` benötigen signifikant mehr RAM/VRAM; auf CPU-only-Systemen empfohlen: `tiny` oder `base`. - **E-10** Füllwort-Erkennung kann kontextabhängige Wörter falsch markieren (z.B. "also" als Satzanfang vs. Füllwort). `--analyze-only` ermöglicht Review vor dem Schnitt. - **E-11** Auto-Kapitel und Highlights benötigen einen LLM-API-Zugang (Anthropic oder Ollama). Ohne API-Key sind diese Features deaktiviert. - **E-12** ffmpeg `xfade` erfordert ffmpeg >= 4.3. Ältere Versionen fallen auf harten Schnitt zurück. --- ## 15. Verifikation | Test | Erwartetes Ergebnis | |------|---------------------| | `pip install -e .` | `video-cut --help` zeigt alle Befehle | | `video-cut cut --input test.mp4 --remove-silence` | Stille-freie MP4 im gleichen Ordner | | `video-cut cut --input test.mp4 --scene-detect` | Ordner `test_scenes/` mit Szenen-Clips | | `video-cut music --input test.mp4 --config config.yaml` | MP4 mit Hintergrundmusik aus `resources/music/` | | `video-cut batch --input ./videos/ --config config.yaml --remove-silence` | Alle Videos in `output/` ohne Stille | | `video-cut sequence --seq sequence.yaml --config config.yaml` | Finales Video gemäß Timeline in `output/` | | `video-cut bot --config config.yaml` | Bot startet, registriert Slash-Commands, wartet auf Befehle | | Discord: `/cut input:/pfad/test.mp4 remove_silence:true` | Bot bestätigt Job, verarbeitet Video, meldet Ergebnis zurück | | Discord: `/status` | Embed mit aktuellem Job-Status und Warteschlange | | Discord: `/cancel` | Laufender ffmpeg-Prozess wird beendet, Bestätigung im Kanal | | `video-cut transcribe --input test.mp4` | SRT-Datei mit Timestamps im gleichen Ordner | | `video-cut subtitle --input test.mp4` | Video mit eingebrannten Untertiteln | | `video-cut smart-cut --input test.mp4 --analyze-only` | Aufschlüsselung: Füllwörter, Fehlstarts, Pausen | | `video-cut smart-cut --input test.mp4` | Video ohne Füllwörter und mit gekürzten Pausen | | `video-cut chapters --input test.mp4 --format youtube` | YouTube-Kapitel-Beschreibung auf stdout | | `video-cut highlights --input test.mp4 --duration 60` | 60-Sekunden-Highlight-Video | | `video-cut merge --inputs a.mp4 b.mp4 -o out.mp4 --crossfade 0.5` | Video mit Crossfade-Übergang | | `video-cut sequence --seq s.yaml --preview` | Schnelle 360p-Vorschau | | `video-cut sequence --seq s.yaml --dry-run` | Clip-Liste und Dauer-Schätzung ohne Rendering |