Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
agricidaniel avatar

Claude Video Caption

  • 6 installs
  • 23 repo stars
  • Updated April 6, 2026
  • agricidaniel/claude-video

claude-video-caption is a Claude Code skill that transcribes video speech with Whisper and generates or burns in animated subtitles.

About

claude-video-caption is a Claude Code skill that transcribes speech and generates subtitles using Whisper and FFmpeg. It produces word-by-word animated karaoke captions, SRT, ASS, and VTT files, burns subtitles into video, and styles them with custom fonts and colors. A developer uses it to add captions to a video for accessibility or social clips.

  • Whisper transcription with word-level timestamps in 99 languages
  • Generates animated karaoke-style captions and SRT/ASS/VTT subtitles
  • Burns subtitles into video with FFmpeg and custom styles

Claude Video Caption by the numbers

  • 6 all-time installs (skills.sh)
  • Ranked #1,096 of 1,335 Generative Media skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

claude-video-caption capabilities & compatibility

Free; runs Whisper and FFmpeg locally with no API keys.

Capabilities
transcription · subtitle generation · caption styling · subtitle burn in
Use cases
transcription · translation
Pricing
Free
From the docs

What claude-video-caption says it does

Speech-to-text transcription and animated subtitle generation using Whisper and FFmpeg.
SKILL.md
npx skills add https://github.com/agricidaniel/claude-video --skill claude-video-caption

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs6
repo stars23
Last updatedApril 6, 2026
Repositoryagricidaniel/claude-video

What it does

Transcribe a video's speech and generate or burn in animated subtitles in SRT, ASS, or VTT format.

Who is it for?

Transcribing speech and producing animated karaoke captions or SRT/ASS/VTT subtitles

Skip if: Speaker diarization or advanced AI audio separation, which other sub-skills cover

When should I use this skill?

You need to transcribe a video and add SRT, ASS, VTT, or burned-in animated captions

What you get

Produces subtitle files or a captioned video with word-level animated text.

  • SRT/ASS/VTT subtitle files
  • Video with burned-in animated captions
  • Whisper JSON transcript

By the numbers

  • 99 languages supported
  • 5 caption styles (default, minimal, bold, neon, shadow)
  • 6 Whisper model sizes documented

Files

SKILL.mdMarkdownGitHub ↗

claude-video-caption — Transcription and Animated Subtitles

Pre-Flight

1. Check Whisper is installed: command -v whisper-ctranslate2 || echo "Run /video setup" 2. Run bash scripts/preflight.sh "$INPUT" "$OUTPUT" 3. Analyze existing subtitle tracks: ffprobe -v error -select_streams s -show_entries stream=codec_name,codec_type -of json "$INPUT"

One-Command Caption Pipeline

For the most common use case (transcribe + animated captions + burn-in):

bash scripts/caption_pipeline.sh "$INPUT" "$OUTPUT" [language] [style]
  • language: auto (default), en, es, fr, de, ja, zh, etc. (99 languages supported)
  • style: default, minimal, bold, neon, shadow

Step-by-Step Manual Pipeline

Step 1: Extract Audio for Whisper

ffmpeg -y -i "$INPUT" -vn -ar 16000 -ac 1 -f wav /tmp/claude_video_audio.wav

Step 2: Transcribe with faster-whisper

# Auto-detect language, word-level timestamps
whisper-ctranslate2 /tmp/claude_video_audio.wav \
  --model large-v3 \
  --output_format json \
  --word_timestamps True \
  --vad_filter True \
  --compute_type int8 \
  --output_dir /tmp/

# For faster transcription (slight accuracy tradeoff)
whisper-ctranslate2 /tmp/claude_video_audio.wav \
  --model large-v3-turbo \
  --output_format json \
  --word_timestamps True \
  --vad_filter True \
  --compute_type float16 \
  --output_dir /tmp/

Model selection:

ModelSizeVRAMSpeedAccuracyUse Case
tiny75M~1 GB32xLowQuick drafts
base142M~1 GB16xFairQuick subtitles
small466M~2 GB6xGoodGeneral use
medium1.5B~5 GB2xVery goodQuality subtitles
large-v3-turbo809M~6 GB8xVery goodBest speed/accuracy (recommended)
large-v31.5B~10 GB1xBestProfessional captioning

Step 3: Generate ASS Subtitles with Karaoke Timing

Convert Whisper JSON output to ASS format with word-by-word highlighting.

Generate this Python script inline and run it:

#!/usr/bin/env python3
"""Convert Whisper JSON word timestamps to ASS karaoke subtitles."""
import json, sys

def words_to_ass(json_path, output_path, words_per_line=3, style="default"):
    with open(json_path) as f:
        data = json.load(f)

    # Collect all words with timestamps
    words = []
    for segment in data.get("segments", []):
        for w in segment.get("words", []):
            words.append({
                "word": w["word"].strip(),
                "start": w["start"],
                "end": w["end"]
            })

    # Style presets (full 23-field ASS V4+ format)
    # Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour,
    #         BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing,
    #         Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
    styles = {
        "default":  "Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H80000000,0,0,0,0,100,100,0,0,1,2,1,2,10,10,40,1",
        "bold":     "Default,Impact,24,&H00FFFFFF,&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,3,2,2,10,10,40,1",
        "minimal":  "Default,Helvetica,18,&H00FFFFFF,&H000000FF,&H80000000,&H80000000,0,0,0,0,100,100,0,0,1,1,0,2,10,10,30,1",
        "neon":     "Default,Arial Black,22,&H0000FFFF,&H00FF00FF,&H00000000,&H80000000,0,0,0,0,100,100,0,0,1,2,0,2,10,10,40,1",
        "shadow":   "Default,Georgia,20,&H00FFFFFF,&H000000FF,&H00000000,&H80000000,0,0,0,0,100,100,0,0,1,0,3,2,10,10,40,1",
    }
    style_line = styles.get(style, styles["default"])

    # ASS header
    ass = f"""[Script Info]
Title: claude-video captions
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: {style_line}

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
"""

    def fmt_time(seconds):
        h = int(seconds // 3600)
        m = int((seconds % 3600) // 60)
        s = seconds % 60
        return f"{h}:{m:02d}:{s:05.2f}"

    # Group words into lines
    for i in range(0, len(words), words_per_line):
        chunk = words[i:i + words_per_line]
        if not chunk:
            continue
        start = chunk[0]["start"]
        end = chunk[-1]["end"]

        # Build karaoke text with \kf tags
        text_parts = []
        for w in chunk:
            duration_cs = max(1, int((w["end"] - w["start"]) * 100))
            text_parts.append(f"{{\\kf{duration_cs}}}{w['word']}")

        text = " ".join(text_parts)
        ass += f"Dialogue: 0,{fmt_time(start)},{fmt_time(end)},Default,,0,0,0,,{text}\n"

    with open(output_path, "w") as f:
        f.write(ass)

if __name__ == "__main__":
    words_to_ass(sys.argv[1], sys.argv[2],
                 int(sys.argv[3]) if len(sys.argv) > 3 else 3,
                 sys.argv[4] if len(sys.argv) > 4 else "default")

Step 4: Burn Subtitles into Video

# ASS subtitles (styled, animated)
ffmpeg -n -i "$INPUT" -vf "ass=/tmp/captions.ass" -c:a copy "$OUTPUT"

# SRT subtitles (simple, with basic styling)
ffmpeg -n -i "$INPUT" -vf "subtitles=/tmp/captions.srt:force_style='FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2'" -c:a copy "$OUTPUT"

Subtitle Extraction

# Extract first subtitle track as SRT
ffmpeg -n -i "$INPUT" -map 0:s:0 subtitles.srt

# Extract as ASS
ffmpeg -n -i "$INPUT" -map 0:s:0 subtitles.ass

# Extract all subtitle tracks
ffprobe -v error -select_streams s -show_entries stream=index,codec_name:stream_tags=language -of json "$INPUT"
# Then extract each: ffmpeg -n -i "$INPUT" -map 0:s:INDEX output.srt

Subtitle Format Conversion

# SRT to ASS
ffmpeg -n -i input.srt output.ass

# ASS to SRT
ffmpeg -n -i input.ass output.srt

# SRT to WebVTT (add "WEBVTT" header)
echo "WEBVTT" > output.vtt && echo "" >> output.vtt && cat input.srt >> output.vtt

Subtitle Timing Adjustment

# Delay subtitles by 2 seconds
ffmpeg -n -i input.srt -itsoffset 2 output.srt

# For manual offset, edit SRT timestamps with awk or Python

ASS Styling Reference

Key ASS override tags for caption customization:

  • \fn{FontName} — change font
  • \fs{Size} — font size
  • \c&HBBGGRR& — primary color (BGR format, not RGB)
  • \3c&HBBGGRR& — outline color
  • \bord{Width} — outline width
  • \shad{Depth} — shadow depth
  • \fscx{%}\fscy{%} — scale X/Y (for "pop" animation: \fscx120\fscy120)
  • \fad(FadeIn,FadeOut) — fade timing in ms
  • \kf{Duration} — karaoke smooth fill (duration in centiseconds)
  • \K{Duration} — karaoke instant fill
  • \an{Position} — alignment (1-9 numpad layout, 2=bottom-center, 8=top-center)
  • \pos(x,y) — absolute position

Common Presets

TikTok/Reels style (large, centered, bold):

FontName=Impact,FontSize=28,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=3,Shadow=0,Alignment=2,MarginV=300

YouTube style (clean, bottom):

FontName=Arial,FontSize=20,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,Shadow=1,Alignment=2,MarginV=40

Podcast/interview (minimal, lower third):

FontName=Helvetica,FontSize=16,PrimaryColour=&H00FFFFFF,BackColour=&H80000000,BorderStyle=4,Alignment=2,MarginV=20

Related skills

FAQ

How many languages does the caption pipeline support?

The transcription supports 99 languages, with auto-detection by default.

What subtitle formats can it produce?

It generates SRT, ASS, and VTT subtitles, and can burn ASS karaoke captions into the video.

Generative Mediaagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.