Agent skill
video-processing
Use when processing YouTube videos, extracting subtitles, parsing VTT files, analyzing video content, generating timestamps, or creating video summaries
Stars
163
Forks
31
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/marketing/video-processing
SKILL.md
Video Processing & Analysis
When to use: YouTube video automation, subtitle extraction, transcript analysis, video content indexing, or generating show notes.
Overview
Production-ready tools for video content processing with subtitle extraction, timestamp handling, and AI-powered analysis.
Key Capabilities
- ✅ YouTube subtitle download (multiple languages)
- ✅ VTT subtitle parsing with timestamp preservation
- ✅ Video duration checking
- ✅ Timestamp validation
- ✅ Batch screenshot generation
- ✅ Video metadata extraction
Prerequisites
bash
# Install required tools
npm install -g yt-dlp # or: pip install yt-dlp
# Install ffmpeg (for video processing)
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt-get install ffmpeg
# Windows
# Download from: https://ffmpeg.org/download.html
Core Operations
1. Download YouTube Subtitles
bash
# Download auto-generated English subtitles
yt-dlp --write-auto-sub --sub-lang en --skip-download \
--sub-format vtt -o "subtitle.%(ext)s" \
"https://www.youtube.com/watch?v=VIDEO_ID"
# Download manual subtitles (if available)
yt-dlp --write-sub --sub-lang en --skip-download \
--sub-format vtt -o "subtitle.%(ext)s" \
"https://www.youtube.com/watch?v=VIDEO_ID"
# Multiple languages
yt-dlp --write-auto-sub --sub-lang en,zh,ja --skip-download \
--sub-format vtt -o "subtitle.%(ext)s" \
"VIDEO_URL"
2. Parse VTT Subtitles with Timestamps
Key Feature: Preserves timing information for quote attribution.
javascript
// VTT Parser (ES5 compatible)
function parseVTT(vttContent) {
var lines = vttContent.split('\n');
var segments = [];
var currentSegment = null;
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
// Timestamp line: 00:01:23.456 --> 00:01:26.789
if (line.match(/^\d{2}:\d{2}:\d{2}\.\d{3}/)) {
var timestamps = line.split(' --> ');
currentSegment = {
start: timestamps[0],
end: timestamps[1],
text: ''
};
}
// Text line
else if (currentSegment && line.length > 0 && !line.match(/^\d+$/)) {
currentSegment.text += (currentSegment.text ? ' ' : '') + line;
}
// Empty line (segment end)
else if (currentSegment && line.length === 0) {
segments.push(currentSegment);
currentSegment = null;
}
}
return segments;
}
// Convert to timestamped text
function formatWithTimestamps(segments) {
var result = '';
for (var i = 0; i < segments.length; i++) {
var seg = segments[i];
result += '[' + seg.start.substring(0, 8) + '] ' + seg.text + '\n';
}
return result;
}
// Usage
var vttContent = $input.item.binary.data.toString('utf-8');
var segments = parseVTT(vttContent);
var timestampedText = formatWithTimestamps(segments);
return {
json: {
transcript: timestampedText,
segments: segments,
segmentCount: segments.length
}
};
3. Video Duration Check
bash
# Get video duration
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 \
video.mp4
# Get duration in HH:MM:SS format
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 \
-sexagesimal video.mp4
javascript
// Validate timestamp against video duration
function validateTimestamp(timestamp, videoDuration) {
// Parse timestamp: 00:01:23 or 01:23
var parts = timestamp.split(':').map(function(p) {
return parseInt(p, 10);
});
var seconds;
if (parts.length === 3) {
seconds = parts[0] * 3600 + parts[1] * 60 + parts[2];
} else if (parts.length === 2) {
seconds = parts[0] * 60 + parts[1];
} else {
return false;
}
return seconds <= videoDuration;
}
4. Batch Screenshot Generation
bash
# Single screenshot at timestamp
ffmpeg -ss 00:01:23 -i video.mp4 -vframes 1 -q:v 2 screenshot.jpg
# Multiple screenshots
# timestamps.txt:
# 00:00:30
# 00:01:45
# 00:03:20
while read timestamp; do
filename="screenshot_${timestamp//:/}.jpg"
ffmpeg -ss $timestamp -i video.mp4 -vframes 1 -q:v 2 $filename
done < timestamps.txt
javascript
// Generate screenshot filenames for batch
function generateScreenshotBatch(timestamps, videoFile) {
var commands = [];
for (var i = 0; i < timestamps.length; i++) {
var ts = timestamps[i];
var filename = 'screenshot_' + ts.replace(/:/g, '') + '.jpg';
var command = 'ffmpeg -ss ' + ts + ' -i ' + videoFile +
' -vframes 1 -q:v 2 ' + filename;
commands.push({
timestamp: ts,
filename: filename,
command: command
});
}
return commands;
}
5. Extract Video Metadata
bash
# Get all metadata
ffprobe -v quiet -print_format json -show_format -show_streams video.mp4
# Get specific fields
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,codec_name,bit_rate \
-of json video.mp4
Complete Workflow: YouTube → Analysis → Notion
[Manual/Webhook Trigger]
Video URL
↓
[Download Subtitle]
yt-dlp --write-auto-sub
↓
[Parse VTT]
Extract segments with timestamps
↓
[AI Analysis]
Generate summary, quotes, tags
↓
[Validate Timestamps]
Check quotes are within video duration
↓
[Download Video]
(if screenshots needed)
↓
[Generate Screenshots]
For key moments/quotes
↓
[Save to Notion]
Structured data with timestamps
n8n Implementation
Workflow Structure
javascript
// Node 1: Download Subtitle
var execSync = require('child_process').execSync;
var videoUrl = $input.item.json.url;
var outputPath = '/tmp/subtitle.vtt';
var command = 'yt-dlp --write-auto-sub --sub-lang en ' +
'--skip-download --sub-format vtt ' +
'-o "' + outputPath + '" "' + videoUrl + '"';
execSync(command);
return {
json: {
videoUrl: videoUrl,
subtitlePath: outputPath
}
};
javascript
// Node 2: Parse VTT
var fs = require('fs');
var vttContent = fs.readFileSync($input.item.json.subtitlePath, 'utf8');
var segments = parseVTT(vttContent);
var fullTranscript = formatWithTimestamps(segments);
return {
json: Object.assign({}, $input.item.json, {
transcript: fullTranscript,
segments: segments
})
};
javascript
// Node 3: AI Analysis (use ai-integration skill)
var prompt = 'Analyze this video transcript and extract:\n' +
'1. Summary (2-3 sentences)\n' +
'2. Key quotes with their timestamps\n' +
'3. Main topics/tags\n\n' +
'Transcript:\n' + $input.item.json.transcript;
// Call AI API...
javascript
// Node 4: Validate Timestamps
var quotes = $input.item.json.aiAnalysis.quotes;
var videoDuration = $input.item.json.duration;
var validQuotes = [];
for (var i = 0; i < quotes.length; i++) {
var quote = quotes[i];
if (validateTimestamp(quote.timestamp, videoDuration)) {
validQuotes.push(quote);
} else {
// Adjust or skip invalid timestamps
console.log('Invalid timestamp: ' + quote.timestamp);
}
}
return {
json: Object.assign({}, $input.item.json, {
validatedQuotes: validQuotes
})
};
Best Practices
- Language Detection: Try auto-generated subtitles first, fall back to manual
- Timestamp Format: Always use HH:MM:SS format for consistency
- Validation: Check timestamps against video duration before using
- Caching: Save downloaded subtitles to avoid re-downloading
- Error Handling: Not all videos have subtitles, handle gracefully
- File Cleanup: Delete temporary files after processing
Common Patterns
Pattern 1: Video Indexing
YouTube Channel → Get New Videos → Download Subtitles →
Parse & Index → Searchable Database
Pattern 2: Show Notes Generation
Video URL → Subtitles → AI Analysis →
Generate Summary + Timestamps → Export Markdown
Pattern 3: Quote Attribution
Transcript with Timestamps → AI Extract Quotes →
Validate Timestamps → Generate Screenshots →
Create Social Media Posts
Troubleshooting
No subtitles available
javascript
// Try both auto and manual
try {
execSync('yt-dlp --write-sub ...'); // Manual first
} catch (e) {
execSync('yt-dlp --write-auto-sub ...'); // Fallback to auto
}
VTT parsing errors
javascript
// Handle malformed VTT
if (!line.match(/^WEBVTT/) && i === 0) {
throw new Error('Invalid VTT format');
}
Timestamp validation fails
javascript
// Adjust out-of-range timestamps to video end
if (seconds > videoDuration) {
seconds = videoDuration - 5; // 5 seconds before end
}
ffmpeg not found
bash
# Check PATH includes ffmpeg
export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
Integration with Other Skills
- oauth-automation: Authenticate YouTube API
- ai-integration: Analyze transcript content
- notion-operations: Save structured video data
- error-handling: Retry on download failures
Full Code and Documentation
Complete implementations:
/mnt/d/work/n8n_agent/n8n-skills/video-processing/
Files:
vtt-subtitle-parser.js- VTT parsing with timestampsvideo-duration-checker.js- Duration validationbatch-screenshot.js- Screenshot generationyoutube-downloader.js- Download wrapperREADME.md- Complete guide and examples
Didn't find tool you were looking for?