Communitygithub.com

Tofuswang/video-subtitle-skill

Claude Code Skill: Untertitel zu Videos hinzufügen mit lokalem Whisper + ffmpeg. 5★.

Was ist video-subtitle-skill?

Dieses Skill für Claude Code ermöglicht es, Videodateien automatisch mit Untertiteln zu versehen, indem es das lokale Whisper-Modell (mlx-whisper oder openai-whisper) zur Transkription und ffmpeg zum Einbrennen der Untertitel nutzt. Es unterstützt drei Arbeitsmodi: vollständige Pipeline (Transkription + Bereinigung + Einbrennen), reine SRT-Erstellung oder reines Einbrennen eines vorhandenen SRT. Das Skill erkennt automatisch verfügbare Whisper-Varianten und Caches, wählt das größte verfügbare Modell aus und bereitet die Audiodaten optimal (16 kHz Mono WAV) auf. Nach der Transkription werden Halluzinationen entfernt, Eigennamen korrigiert und Fragmente sinnvoll zusammengeführt. Die Untertitel werden mit anpassbaren Stilen (Schriftgröße, Farbe, Kontur) eingebrannt. Fehlerhafte ffmpeg-Installationen ohne libass werden durch Soft-Embedding der SRT-Spur umgangen. Plattformen: macOS (Apple Silicon empfohlen) und Linux.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor
npx skills add Tofuswang/video-subtitle-skill

In Ihrer bevorzugten KI fragen

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

Dokumentation

/video-subtitle – Video-Untertitel-Werkzeug

Transkribiere Video-Audio in SRT-Untertitel mit einem lokalen Whisper-Modell und brenne sie dann in das Video ein.

Benutzeraufruf

Wenn der Benutzer /video-subtitle eingibt, führe dieses Skill aus.

Voraussetzungen

Dieses Skill benötigt zwei Werkzeuge. Überprüfe die Verfügbarkeit, bevor du fortfährst:

1. mlx-whisper (Apple Silicon) oder openai-whisper

Erkenne, welches verfügbar ist:

which mlx_whisper whisper 2>/dev/null

Falls keines gefunden wird, leite den Benutzer zur Installation an:

  • Apple Silicon Mac (empfohlen): pip install mlx-whisper
  • Beliebige Plattform: pip install openai-whisper

2. ffmpeg mit libass

Überprüfe auf libass-Unterstützung:

ffmpeg -filters 2>&1 | grep subtitles

Wenn keine Ausgabe erfolgt (libass fehlt), ist der subtitles-Filter nicht verfügbar:

  • macOS: brew install ffmpeg-full (keg-only, /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg verwenden)
  • Linux: sudo apt install ffmpeg (enthält normalerweise libass)
  • Fallback: Wenn der Benutzer normales ffmpeg ohne libass hat, bette die SRT als Untertitelspur ein (Soft-Embedding) anstatt sie einzubrennen.

Whisper-Modellauswahl

Erkenne zwischengespeicherte Modelle:

ls ~/.cache/huggingface/hub/ 2>/dev/null | grep whisper

Bevorzuge das größte verfügbare Modell. Wenn keines zwischengespeichert ist, verwende:

  • mlx-whisper: mlx-community/whisper-large-v3-mlx
  • openai-whisper: large-v3

Modi

  • /video-subtitle pfad/zum/video.mov → Vollständige Pipeline (transkribieren + korrigieren + einbrennen)
  • /video-subtitle srt pfad/zum/video.mov → Nur SRT (transkribieren, ohne einbrennen)
  • /video-subtitle burn pfad/zum/video.mov pfad/zum/sub.srt → Nur einbrennen (vorhandene SRT verwenden)
  • /video-subtitle (keine Argumente) → Interaktiv, nach Videopfad fragen

Vollständige Pipeline

Schritt 1: Video überprüfen

Wenn kein Pfad angegeben wurde, frage mit AskUserQuestion nach. Bestätige, dass die Datei existiert, und lese Metadaten aus:

ffmpeg -i "<video_path>" 2>&1 | grep -E "Duration|Stream.*(Video|Audio)"

Melde dem Benutzer Dauer, Auflösung und Dateigröße.

Schritt 2: Audio extrahieren

ffmpeg -i "<video_path>" -vn -acodec pcm_s16le -ar 16000 -ac 1 "<output_dir>/<basename>_audio.wav" -y

16 kHz Mono WAV ist das optimale Eingabeformat für Whisper.

Schritt 3: Sprache bestätigen

Frage den Benutzer mit AskUserQuestion. Übliche Optionen:

SpracheFlag
Chinesisch--language zh
Englisch--language en
Japanisch--language ja
Automatisch--language weglassen

Schritt 4: Transkribieren

mlx-whisper:

mlx_whisper --model "<model>" --language <lang> --output-format srt --output-dir "<output_dir>" "<audio_wav>"

openai-whisper:

whisper "<audio_wav>" --model large-v3 --language <lang> --output_format srt --output_dir "<output_dir>"

Sage dem Benutzer: „Transkribiere, bitte warten …“

Schritt 5: SRT bereinigen

Lese die generierte SRT und korrigiere:

  1. Halluzinationen entfernen: Lösche Einträge mit Zeitstempeln der Dauer null (z. B. 00:00:57,640 --> 00:00:57,640) oder leeren Texten
  2. Eigennamen korrigieren: Whisper erkennt Markennamen und Fachbegriffe häufig falsch – nutze den Gesprächskontext zur Korrektur
  3. Fragmente zusammenführen: Fasse Einträge kürzer als 0,5 s, die semantisch zusammenhängen
  4. Neu nummerieren: Führe dieses Python-Snippet aus, um alle Einträge neu zu nummerieren:
python3 -c "
import re
with open('<srt_path>', 'r') as f:
    content = f.read()
blocks = re.split(r'\n\n+', content.strip())
out = []
for i, block in enumerate(blocks, 1):
    lines = block.strip().split('\n')
    if len(lines) >= 2:
        lines[0] = str(i)
        out.append('\n'.join(lines))
with open('<srt_path>', 'w') as f:
    f.write('\n\n'.join(out) + '\n')
"

Zeige dem Benutzer die korrigierte SRT und frage, ob weitere Bearbeitungen vor dem Einbrennen nötig sind.

Schritt 6: Untertitel einbrennen

Ermittle das richtige ffmpeg-Binary (bevorzuge ffmpeg-full, wenn normales ffmpeg libass fehlt):

FFMPEG="ffmpeg"
if ! ffmpeg -filters 2>&1 | grep -q subtitles; then
  if [ -x /opt/homebrew/opt/ffmpeg-full/bin/ffmpeg ]; then
    FFMPEG="/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg"
  fi
fi

Dann einbrennen:

$FFMPEG \
  -i "<video_path>" \
  -vf "subtitles=<srt_path>:force_style='FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,MarginV=30'" \
  -c:v libx264 -preset medium -crf 23 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  "<output_dir>/<basename>_subtitled.mp4" -y

force_style-Optionen:

ParameterStandardBeschreibung
FontSize24Schriftgröße
PrimaryColour&H00FFFFFFWeißer Text
OutlineColour&H00000000Schwarze Kontur
Outline2Konturstärke
MarginV30Unterer Rand

Wichtig: Der SRT-Dateipfad darf keine Sonderzeichen enthalten, die den ffmpeg-Filterparser stören. Verwende bei Bedarf relative Pfade oder Symlinks.

Schritt 7: Fertig

Melde den Ausgabedateipfad und die -größe. Schlage vor, open <pfad> zur Vorschau zu verwenden. Erinnere den Benutzer daran, dass die Zwischendatei _audio.wav gelöscht werden kann.


Fehlerbehebung

ProblemUrsacheLösung
No such filter: 'subtitles'ffmpeg fehlt libassffmpeg-full verwenden oder libass installieren
No such filter: 'drawtext'ffmpeg fehlt libfreetypeffmpeg-full verwenden
Doppelte/leere SRT-EinträgeWhisper-HalluzinationBereinigen in Schritt 5
Chinesische Zeichen als KästchenFehlende CJK-SchriftartmacOS: automatischer Fallback auf PingFang. Linux: apt install fonts-noto-cjk
Error parsing filterchainSonderzeichen im SRT-PfadRelativen Pfad verwenden, Leerzeichen vermeiden

Qualitätsregeln

  • Getreue Transkription: Transkribiere nur, was tatsächlich gesagt wurde – füge keine Bedeutung hinzu oder schreibe sie um
  • Eigennamen-Korrektur: Korrigiere häufige Whisper-Fehler, aber bestätige mit dem Benutzer
  • Untertitel-Rhythmus: Maximal zwei Zeilen pro Eintrag, maximal ~20 CJK-Zeichen pro Zeile
  • Aufräumen: Erinnere den Benutzer daran, die Zwischendateien (_audio.wav) nach Abschluss zu löschen

Verwandte Skills