Transcribe and cut video
Use when the user sends an MP4 video and wants it transcribed and split by topic. Triggers on "process video", "transcribe audio", "cut video by topic", "split lesson", "lecture", "MP4 transcription", or any workflow combining faster-whisper audio transcription with ffmpeg video segmentation.From its SKILL.md
npx -y skills add ciro-rosa/claude-skills --skill transcribe-and-cut-videoAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.5 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it
Transcribe and Cut Video by Topic
Overview
Transcribes the audio of an MP4 using faster-whisper (CPU, tiny model), identifies topics from the spoken content, and cuts the video with ffmpeg — no re-encoding, no quality loss.
Works in memory-constrained environments (3–4 GB RAM, no GPU, no swap).
When to Use
- User sends an
.mp4to transcribe and/or split by topic - Lectures, webinars, testimonials, podcasts — any spoken-word video
- Low-resource environment: CPU-only, limited RAM, no swap
Full Workflow
1. Check Dependencies
python3 -c "import faster_whisper; print('OK')" 2>/dev/null || \
pip install faster-whisper --break-system-packages -q
which ffmpeg
⚠️ Do NOT use
openai-whisper— it requires PyTorch (~530 MB) and will likely run out of disk space.faster-whisperuses CTranslate2 and is much lighter.
2. Extract Audio (always do this first)
Reduces memory footprint and speeds up transcription:
ffmpeg -i "video.mp4" -vn -ar 16000 -ac 1 -c:a pcm_s16le audio.wav -y
3. Transcribe
Short videos (< 30 min): transcribe the WAV directly.
Long videos (≥ 30 min): split into 30-minute chunks and transcribe each one separately — prevents OOM kill.
# Create chunks (replace TOTAL_SECONDS with actual video duration)
mkdir -p chunks
for i in $(seq 0 1800 TOTAL_SECONDS); do
IDX=$((i / 1800 + 1))
ffmpeg -i audio.wav -ss $i -t 1800 -c copy \
chunks/chunk_$(printf "%02d" $IDX).wav -y 2>/dev/null
done
Save as transcribe_chunk.py and run once per chunk:
import sys, json, os
from faster_whisper import WhisperModel
chunk_idx = int(sys.argv[1])
chunk_start = (chunk_idx - 1) * 1800 # time offset in seconds
model = WhisperModel("tiny", device="cpu", compute_type="int8",
download_root=os.path.expanduser("~/whisper_models"))
segments, _ = model.transcribe(
f"chunks/chunk_{chunk_idx:02d}.wav",
language="pt", # change to "en" for English
beam_size=3,
vad_filter=True,
vad_parameters=dict(min_silence_duration_ms=700)
)
results = [
{
"start": round(s.start + chunk_start, 2),
"end": round(s.end + chunk_start, 2),
"text": s.text.strip()
}
for s in segments
]
with open(f"chunks/chunk_{chunk_idx:02d}.json", "w", encoding="utf-8") as f:
json.dump(results, f, ensure_ascii=False, indent=2)
print(f"[Chunk {chunk_idx}] {len(results)} segments saved.")
Run for each chunk:
for i in $(seq 1 NUM_CHUNKS); do
python3 transcribe_chunk.py $i
done
4. Merge Chunks and Save Transcript as .md
import json, os
all_segs = []
for i in range(1, NUM_CHUNKS + 1):
with open(f"chunks/chunk_{i:02d}.json", encoding="utf-8") as f:
all_segs.extend(json.load(f))
def fmt(s):
h = int(s) // 3600
m = (int(s) % 3600) // 60
sec = s % 60
return f"{h}h{m:02d}m{sec:04.1f}s" if h else f"{m:02d}m{sec:04.1f}s"
video_name = "your-video-name"
output_dir = f"output/{video_name}"
os.makedirs(output_dir, exist_ok=True)
md = f"# Transcript — {video_name}\n\n"
for seg in all_segs:
md += f"**[{fmt(seg['start'])} → {fmt(seg['end'])}]** {seg['text']}\n\n"
with open(f"{output_dir}/{video_name}_transcript.md", "w", encoding="utf-8") as f:
f.write(md)
5. Identify Topics and Present to User
Analyze the transcript and propose 3–8 coherent topics with timestamps. Present as a table before cutting:
| # | Topic | Start | End |
|---|---|---|---|
| 1 | Introduction | 00:00:00 | 00:15:00 |
| 2 | Core Concept | 00:15:00 | 00:45:00 |
| … | … | … | … |
⚠️ Always wait for user confirmation before cutting.
6. Cut with ffmpeg (after confirmation)
ffmpeg -i "video.mp4" -ss HH:MM:SS -to HH:MM:SS -c copy \
"output/Part N - Topic Name.mp4" -y
-c copy = stream copy, no re-encoding — fast and lossless.
Output Structure
/VideoName/
├── VideoName_transcript.md
├── Part 1 - Introduction.mp4
├── Part 2 - Core Concept.mp4
└── Part N - Conclusion.mp4
Rules
- File names must not contain accents, special characters, or characters invalid for the filesystem
- Temporary files (WAV, chunks, JSONs) stay in the session's temp folder — not delivered to user
- Default language:
"pt"for Portuguese, change to"en"for English - Never cut the video without user confirmation
- Output files always go in a subfolder named after the original video
Common Errors
| Problem | Cause | Fix |
|---|---|---|
Killed (exit 137) | OOM — long video loaded entirely into RAM | Use chunk strategy |
No space left on device | openai-whisper tries to install PyTorch (530 MB) | Use faster-whisper instead |
| Transcription interrupted | Session timeout on long video | Transcribe chunk by chunk |
| Wrong timestamps after merging | Missing time offset | Add (chunk_idx - 1) * 1800 to each segment's start/end |
| Model re-downloaded every session | Cache path is session-specific | Use ~/whisper_models as download_root |
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.