Automated video processing: metadata extraction, thumbnails, transcoding, audio extraction with DuckDB tracking
Trit: 0 (ERGODIC - pipeline coordinator) Foundation: Babashka + FFmpeg + DuckDB
Automated video processing pipeline that:
ffprobe(def video-extensions
#{"mp4" "mov" "mkv" "webm" "avi" "m4v" "flv" "wmv" "mpg" "mpeg"})
bb video-processor.bb /path/to/video.mp4
bb video-processor.bb /path/to/watch/dir
| Variable | Default | Description |
|----------|---------|-------------|
| VIDEO_OUTPUT_DIR | /tmp/processed_videos | Output directory |
| AMP_THREAD_ID | video-processor | Session ID for DuckDB |
(defn extract-metadata [path]
(shell {:out :string}
"ffprobe" "-v" "quiet"
"-print_format" "json"
"-show_format" "-show_streams"
path))
Returns JSON with duration, codec, bitrate, resolution.
(defn generate-thumbnail [input output]
(shell "ffmpeg" "-y" "-i" input
"-ss" "00:00:05" "-vframes" "1"
"-vf" "scale=320:-1"
output))
Creates 320px wide JPEG at 5 second mark.
(defn transcode-web [input output]
(shell "ffmpeg" "-y" "-i" input
"-c:v" "libx264" "-preset" "fast" "-crf" "23"
"-c:a" "aac" "-b:a" "128k"
"-movflags" "+faststart"
output))
H.264/AAC with fast-start for streaming.
(defn extract-audio [input output]
(shell "ffmpeg" "-y" "-i" input
"-vn" "-c:a" "libmp3lame" "-q:a" "2"
output))
High-quality MP3 (VBR ~190kbps).
(defn record-processing! [path metadata outputs]
(shell "duckdb" db-path
(format "INSERT INTO fs_events
(path, event_type, size, checksum, session_id)
VALUES ('%s', 'video_processed', %s, '%s', '%s')"
path size checksum session-id)))
/tmp/processed_videos/
├── video_thumb.jpg # Thumbnail
├── video_web.mp4 # Transcoded (if needed)
└── video_audio.mp3 # Extracted audio
CREATE TABLE IF NOT EXISTS fs_events (
path VARCHAR,
event_type VARCHAR,
size BIGINT,
checksum VARCHAR,
session_id VARCHAR,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Query processed videos
SELECT * FROM fs_events
WHERE event_type = 'video_processed'
ORDER BY timestamp DESC;
spi-parallel-verify (-1) ⊗ video-processor (0) ⊗ ffmpeg-media (+1) = 0 ✓
video-downloader (-1) ⊗ video-processor (0) ⊗ gay-mcp (+1) = 0 ✓
Processing stages announced via macOS say:
(defn announce [message]
(shell "say" "-v" "Samantha (Enhanced)" message))
Install via:
brew install babashka ffmpeg duckdb
# 1. Download video
/video-downloader https://youtube.com/watch?v=...
# 2. Process and extract frames
bb video-processor.bb ~/Downloads/video.mp4
# 3. Analyze frames with Claude
# (frames available as thumbnails or extract more with ffmpeg)
ffmpeg -i video.mp4 -vf "fps=1" frames/frame_%04d.jpg
# Model video as temporal graph
@present SchVideo(FreeSchema) begin
Frame::Ob
Segment::Ob
frame_of::Hom(Frame, Segment)
next_frame::Hom(Frame, Frame)
Timestamp::AttrType
time::Attr(Frame, Timestamp)
end
# Process single video
just video-process /path/to/video.mp4
# Watch directory
just video-watch /path/to/dir
# Query processed videos
just video-list
Trit: 0 (ERGODIC)
Home: Prof
Poly Op: ⊗
Kan Role: Adj
Color: #26D826
The skill participates in triads satisfying:
(-1) + (0) + (+1) ≡ 0 (mod 3)
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer