mediaproc
Process media files (video, audio, images) via a locked-down SSH container with ffmpeg, sox, and imagemagick
mediaproc
Setup Required
This skill requires MEDIAPROC_HOST and MEDIAPROC_PORT environment variables pointing to a running mediaproc instance.
Configure OpenClaw (~/.openclaw/openclaw.json):
{
"skills": {
"entries": {
"mediaproc": {
"env": {
"MEDIAPROC_HOST": "localhost",
"MEDIAPROC_PORT": "2222"
}
}
}
}
}
Or set the environment variables directly:
export MEDIAPROC_HOST=localhost
export MEDIAPROC_PORT=2222
Locked-down media processing over SSH. Uses a Python wrapper that whitelists commands - no shell access, no injection, no bullshit.
First Connection
Before running any commands, you must accept the host key so it gets added to known_hosts. Run a simple ls and accept the fingerprint:
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ls"
If this is the first time connecting, SSH will prompt to verify the host key. Type yes to accept. This only needs to happen once per host. If you skip this step, all subsequent SSH commands will fail with a host key verification error.
How It Works
All commands are executed via SSH against the mediaproc container. The container forces every connection through a Python wrapper that only allows whitelisted commands. All file paths are locked to /work inside the container.
SSH command format:
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "<command> [args]"
Media Tools
| Command | Binary | Description |
|---|---|---|
ffmpeg | /usr/bin/ffmpeg | Video/audio encoding, transcoding, filtering |
ffprobe | /usr/bin/ffprobe | Media file analysis |
sox | /usr/bin/sox | Audio processing |
soxi | /usr/bin/soxi | Audio file info |
convert | /usr/bin/convert | Image conversion/manipulation (ImageMagick) |
identify | /usr/bin/identify | Image file info (ImageMagick) |
magick | /usr/bin/magick | ImageMagick CLI |
File Operations
All paths are relative to /work. Traversal attempts are blocked. Absolute paths get remapped under /work.
| Command | Description | Example |
|---|---|---|
ls | List /work or a subdirectory (ls -alph style, use --json for JSON) | ls or ls --json subdir |
put | Upload file from stdin | put video.mp4 (pipe file via stdin) |
get | Download file to stdout | get output.mp4 (redirect stdout to file) |
rm | Delete a file (not directories) | rm old.mp4 |
mkdir | Create directory (recursive) | mkdir project1 |
rmdir | Remove empty directory | rmdir project1 |
rrmdir | Remove directory and everything in it recursively | rrmdir project1 |
Usage Examples
Upload and process a file
# Upload
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "put input.mp4" < input.mp4
# Transcode
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ffmpeg -i /work/input.mp4 -c:v libx264 /work/output.mp4"
# Download result
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "get output.mp4" > output.mp4
# Clean up
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "rm input.mp4"
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "rm output.mp4"
Video operations
# Get video info as JSON
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ffprobe -v quiet -print_format json -show_format -show_streams /work/video.mp4"
# Apply frei0r glow effect
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ffmpeg -i /work/in.mp4 -vf frei0r=glow:0.5 /work/out.mp4"
# Extract audio from video
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ffmpeg -i /work/video.mp4 -vn -acodec libmp3lame /work/audio.mp3"
# Create thumbnail from video
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ffmpeg -i /work/video.mp4 -ss 00:00:05 -vframes 1 /work/thumb.jpg"
Audio operations
# Convert audio format
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "sox /work/input.wav /work/output.mp3"
# Get audio info
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "soxi /work/audio.wav"
# Normalize audio
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "sox /work/input.wav /work/output.wav norm"
Image operations
# Resize image
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "convert /work/input.png -resize 50% /work/output.png"
# Create thumbnail
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "convert /work/input.jpg -thumbnail 200x200 /work/thumb.jpg"
# Get image info
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "identify /work/image.png"
File management
# List files (ls -alph style, no . and ..)
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ls"
# drwxrwxr-x 2 mediaproc mediaproc 4096 Jan 25 14:30 project1/
# -rw-rw-r-- 1 mediaproc mediaproc 1048576 Jan 25 14:32 video.mp4
# List files as JSON (use --json flag)
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ls --json"
# [{"name": "video.mp4", "size": 1048576, "modified": 1706140800, "isDir": false, "mode": "rw-rw-r--", "owner": "mediaproc", "group": "mediaproc", "links": 1}, ...]
# List subdirectory
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "ls project1"
# Create subdirectory
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "mkdir project1"
# Remove directory recursively
ssh -p $MEDIAPROC_PORT mediaproc@$MEDIAPROC_HOST "rrmdir project1"
Available Plugins
- frei0r - Video effect plugins (used via
-vf frei0r=...) - LADSPA - Audio effect plugins: SWH, TAP, CMT (used via
-af ladspa=...) - LV2 - Audio plugins (used via
-af lv2=...)
Fonts
2200+ fonts included covering emoji, CJK, Arabic, Thai, Indic, monospace, and more. Custom fonts can be mounted to /usr/share/fonts/custom.
Security Notes
- No shell access - all commands go through a Python wrapper
- Whitelist only - unlisted commands are rejected
- No injection -
&&,;,|,$()are treated as literal arguments (no shell involved) - SSH key auth only - no passwords
- All forwarding disabled
- All file paths locked to
/work