Camsnap Skill
Production-grade IP camera capture system for RTSP/ONVIF cameras with comprehensive error handling and multi-brand support.
When to Use
✅ USE this skill when:
-
Capturing snapshots from IP security cameras
-
Recording security camera footage
-
Testing RTSP stream connectivity
-
Needing automated camera monitoring
-
Recording clips from security cameras
-
Multi-camera snapshot capture
-
Long-term camera monitoring
-
Security or timelapse applications
❌ DON'T use this skill when:
-
Needing webcam capture → Use system webcam tools
-
Capturing video frames from files → Use video-frames
-
Needing live streaming → Use streaming tools
-
Video editing → Use video editing software
Prerequisites
Install FFmpeg
brew install ffmpeg # macOS sudo apt install ffmpeg # Ubuntu/Debian
Verify RTSP support
ffmpeg -formats | grep rtsp
Camera must be:
- Network accessible
- RTSP enabled
- Credentials known (if required)
Camera URL Formats
Supported Camera Types
Type Pattern Default Port
Generic rtsp://ip:port/path
554
Hikvision rtsp://ip:554/Streaming/Channels/101
554
Dahua rtsp://ip:554/cam/realmonitor?channel=1&subtype=0
554
Axis rtsp://ip:554/axis-media/media.amp
554
Reolink rtsp://ip:554/h264Preview_01_main
554
UniFi rtsp://ip:554/livestream/ch00_0
554
Wyze rtsp://ip:554/live
554
Sample URLs
Generic with authentication
rtsp://admin:password@192.168.1.100:554/stream
Hikvision (channel 1, high quality)
rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101
Hikvision (channel 1, low quality)
rtsp://admin:password@192.168.1.100:554/Streaming/Channels/102
Dahua (channel 1)
rtsp://admin:password@192.168.1.100:554/cam/realmonitor?channel=1&subtype=0
Axis
rtsp://root:password@192.168.1.100:554/axis-media/media.amp
Reolink (main stream)
rtsp://admin:password@192.168.1.100:554/h264Preview_01_main
Reolink (sub stream - lower quality)
rtsp://admin:password@192.168.1.100:554/h264Preview_01_sub
UniFi Protect
rtsp://192.168.1.100:554/livestream/ch00_0
Wyze Cam
rtsp://your_username:password@192.168.1.100:554/live
Commands
- Capture Snapshot
Capture a single frame from camera.
Basic snapshot (requires credentials)
{baseDir}/camsnap.js snapshot --url rtsp://admin:pass@192.168.1.100/stream --output camera.jpg
Using separate credentials
{baseDir}/camsnap.js snapshot --ip 192.168.1.100 --port 554
--username admin --password secret --output camera.jpg
Hikvision camera
{baseDir}/camsnap.js snapshot --type hikvision --ip 192.168.1.100
--username admin --password secret --output camera.jpg
With quality settings
{baseDir}/camsnap.js snapshot --url rtsp://cam.example.com/stream
--format png --quality 1 --output high-quality.png
Resized snapshot
{baseDir}/camsnap.js snapshot --url rtsp://192.168.1.100/stream
--resize 1280x720 --output thumb.jpg
No timestamp overlay
{baseDir}/camsnap.js snapshot --url rtsp://192.168.1.100/stream
--no-timestamp --output clean.jpg
Output Options:
Option Values Description
--format
jpg, png, bmp, tiff Output format
--quality
1-31 JPEG quality (1=best)
--resize
WxH Resize dimensions
--no-timestamp
Disable overlay
- Record Video Clip
Record a short video clip from camera.
Basic recording
{baseDir}/camsnap.js record --url rtsp://192.168.1.100/stream
--duration 10 --output clip.mp4
High quality, 30 seconds
{baseDir}/camsnap.js record --url rtsp://192.168.1.100/stream
--duration 30 --quality high --no-audio --output recording.mp4
With specific frame rate
{baseDir}/camsnap.js record --url rtsp://192.168.1.100/stream
--duration 60 --fps 15 --quality medium --output clip.mp4
Maximum quality (large file)
{baseDir}/camsnap.js record --url rtsp://192.168.1.100/stream
--duration 300 --quality maximum --fps 30 --output high-quality.mp4
Quality Presets:
Preset FPS Bitrate Use Case
low
10 ~500k Archival, long recordings
medium
15 ~1000k Default balance
high
25 ~2000k Detailed recording
maximum
30 ~4000k Best quality
Recording Limits:
-
Minimum: 1 second
-
Maximum: 3600 seconds (1 hour)
-
Recommended: 10-300 seconds
- Test Camera Connection
Verify camera connectivity and get stream information.
Test basic connection
{baseDir}/camsnap.js test --url rtsp://192.168.1.100/stream
Test with credentials
{baseDir}/camsnap.js test --ip 192.168.1.100 --username admin --password secret
Test Hikvision
{baseDir}/camsnap.js test --type hikvision --ip 192.168.1.100
--username admin --password secret
Extended timeout for slow cameras
{baseDir}/camsnap.js test --url rtsp://192.168.1.100/stream
--timeout 30000
Sample Output:
{ "connected": true, "url": "rtsp://:@192.168.1.100...", "format": "rtsp", "video": { "codec": "h264", "resolution": "1920x1080", "fps": 25, "bitrate": "4096000" }, "audio": { "codec": "aac", "sampleRate": "48000", "channels": 2 } }
- Motion Detection
Monitor camera for motion events.
Monitor for 60 seconds
{baseDir}/camsnap.js detect --url rtsp://192.168.1.100/stream
--duration 60
With custom threshold
{baseDir}/camsnap.js detect --url rtsp://192.168.1.100/stream
--duration 300 --threshold 0.05 --clip-duration 10
On motion, record clip
{baseDir}/camsnap.js detect --url rtsp://192.168.1.100/stream
--duration 600 --clip-duration 15 --output-dir ./motion-clips
Detection Options:
Option Default Description
--duration
10 How long to monitor (seconds)
--threshold
0.02 Motion sensitivity (0.01-1.0)
--clip-duration
5 Clip length on detection
- Credential Management
Store camera credentials securely.
Save credentials
{baseDir}/camsnap.js credentials --save --name front-door
--username admin --password secret --type hikvision
List saved credentials
{baseDir}/camsnap.js credentials --list
Use saved credentials
{baseDir}/camsnap.js snapshot --ip 192.168.1.100
--use-credentials front-door --output camera.jpg
Credentials Storage:
-
Location: ~/.camsnap_credentials
-
Permissions: 600 (owner read/write only)
-
Format: JSON with base64-encoded passwords
-
No encryption (OS file permissions only)
Camera Setup Guides
Hikvision
1. Enable RTSP in camera settings:
Configuration > Network > Advanced > RTSP
(Port 554 by default)
2. Main stream (high quality)
{baseDir}/camsnap.js snapshot --type hikvision --ip 192.168.1.100
--username admin --password password --output camera.jpg
3. Sub stream (lower quality, less bandwidth)
{baseDir}/camsnap.js snapshot --url "rtsp://admin:password@192.168.1.100:554/Streaming/Channels/102"
--output camera-low.jpg
Channel Numbers:
-
Channel 1: 101 (main), 102 (sub)
-
Channel 2: 201 (main), 202 (sub)
-
Channel N: N01 (main), N02 (sub)
Dahua
1. Enable RTSP in camera:
Settings > Network > Connection > RTSP
2. Capture snapshot
{baseDir}/camsnap.js snapshot --type dahua --ip 192.168.1.100
--username admin --password password --channel 1 --output camera.jpg
3. Higher quality (subtype=0)
{baseDir}/camsnap.js snapshot --url "rtsp://admin:password@192.168.1.100:554/cam/realmonitor?channel=1&subtype=0"
--output camera.jpg
4. Lower quality (subtype=1)
{baseDir}/camsnap.js snapshot --url "rtsp://admin:password@192.168.1.100:554/cam/realmonitor?channel=1&subtype=1"
--output camera-low.jpg
Axis
1. Enable RTSP in camera:
Plain Config > Network > Network > VAPIX
2. Test connection
{baseDir}/camsnap.js snapshot --type axis --ip 192.168.1.100
--username root --password pass --output camera.jpg
Reolink
1. Enable RTSP in Reolink app:
Settings > Device > Stream Protocol > RTSP
2. Main stream (1080p)
{baseDir}/camsnap.js snapshot --type reolink --ip 192.168.1.100
--username admin --password password --stream 01 --output camera.jpg
3. Sub stream (480p)
{baseDir}/camsnap.js snapshot --url "rtsp://admin:password@192.168.1.100:554/h264Preview_01_sub"
--output camera-low.jpg
UniFi Protect
1. In UniFi Protect, enable RTSP for camera
Settings > System > RTSP Service
2. Get stream URL from UniFi dashboard
3. Capture snapshot
{baseDir}/camsnap.js snapshot --type unifi --ip 192.168.1.100
--output camera.jpg
Wyze Cam
1. Enable RTSP firmware on Wyze
(Requires custom firmware)
2. Capture snapshot
{baseDir}/camsnap.js snapshot --type wyze --ip 192.168.1.100
--username username --password password --output camera.jpg
Connection Troubleshooting
Common Errors
"Connection timed out"
Causes:
1. Camera not responding
2. Network issue
3. RTSP not enabled
Solutions:
ping 192.168.1.100 # Test connectivity telnet 192.168.1.100 554 # Test RTSP port {baseDir}/camsnap.js test --url rtsp://192.168.1.100 --timeout 30000
"Authentication failed"
Causes:
1. Wrong username/password
2. Camera requires digest auth
3. Credentials have special characters
Solutions:
- Verify credentials in camera web UI
- URL-encode special characters
{baseDir}/camsnap.js snapshot --url "rtsp://admin:p%40ssword@192.168.1.100/stream"
--output camera.jpg
"Stream not found"
Causes:
1. Wrong stream path
2. Camera type mismatch
Solutions:
Check camera documentation for correct RTSP URL
{baseDir}/camsnap.js snapshot --type hikvision --ip 192.168.1.100
--username admin --password secret --output camera.jpg
"FFmpeg error"
Causes:
1. FFmpeg not installed
2. RTSP support missing
3. Codec not supported
Solutions:
ffmpeg -protocols | grep rtsp # Check RTSP support brew reinstall ffmpeg --with-librtsp # Reinstall with RTSP (macOS)
Error Handling
Error Codes
Code Name Description
0 SUCCESS Operation completed
1 INVALID_INPUT Bad parameter
2 CAMERA_UNREACHABLE Can't connect
3 AUTHENTICATION_FAILED Wrong credentials
4 STREAM_ERROR Stream issue
5 FFMPEG_ERROR FFmpeg failed
6 TIMEOUT Operation timed out
7 STORAGE_ERROR Can't write file
8 MOTION_DETECTION_ERROR Detection failed
99 UNKNOWN Unexpected error
Exit Status
{baseDir}/camsnap.js test --url rtsp://192.168.1.100/stream echo $? # 0 = success
{baseDir}/camsnap.js snapshot --url invalid echo $? # 1 = error (see above codes)
Examples
Security Snapshot Script
#!/bin/bash
Capture hourly snapshots from security cameras
CAMERAS=( "rtsp://admin:pass@192.168.1.100/Streaming/Channels/101" "rtsp://admin:pass@192.168.1.101/cam/realmonitor?channel=1" )
OUTPUT_DIR="/var/security/snapshots/$(date +%Y/%m/%d)" mkdir -p "$OUTPUT_DIR"
for url in "${CAMERAS[@]}"; do name=$(echo "$url" | grep -o '[0-9]+.|[0-9]+$' | head -1) timestamp=$(date +%H%M%S)
{baseDir}/camsnap.js snapshot --url "$url"
--output "$OUTPUT_DIR/camera_${name}_${timestamp}.jpg" 2>/dev/null
if [ $? -eq 0 ]; then echo "[$timestamp] Captured: Camera $name" else echo "[$timestamp] Failed: Camera $name" fi done
Keep only last 30 days of snapshots
find /var/security/snapshots -name "*.jpg" -mtime +30 -delete
Timelapse Recording
#!/bin/bash
Capture snapshot every minute for timelapse
URL="rtsp://admin:password@192.168.1.100/stream" OUTPUT="/var/timelapse/$(date +%Y%m%d)" mkdir -p "$OUTPUT"
duration=3600 # Record for 1 hour interval=60 # Every 60 seconds
Note: This is simplified - use cron for production
cd "$OUTPUT"
for ((i=0; i<duration; i+=interval)); do
{baseDir}/camsnap.js snapshot --url "$URL"
--output "frame_$(printf %05d $i).jpg" 2>/dev/null
sleep $interval
done
Create timelapse video from frames
ffmpeg -framerate 30 -i frame_%05d.jpg -c:v libx264 -crf 18 timelapse.mp4
Motion Detection with Alert
#!/bin/bash
Monitor camera and send alert on motion
URL="rtsp://admin:password@192.168.1.100/stream"
{baseDir}/camsnap.js detect --url "$URL" --duration 3600 --threshold 0.05
if [ $? -eq 0 ]; then
Motion detected - send notification
echo "Motion detected at $(date)" | mail -s "Security Alert" admin@example.com
Capture evidence
{baseDir}/camsnap.js snapshot --url "$URL" --output "/alerts/motion_$(date +%s).jpg" fi
Multi-Camera Capture
#!/bin/bash
Capture from multiple cameras simultaneously
CAMERA1="rtsp://admin:pass@192.168.1.100/stream" CAMERA2="rtsp://admin:pass@192.168.1.101/stream" CAMERA3="rtsp://admin:pass@192.168.1.102/stream"
{baseDir}/camsnap.js snapshot --url "$CAMERA1" --output /tmp/cam1.jpg & c1=$! {baseDir}/camsnap.js snapshot --url "$CAMERA2" --output /tmp/cam2.jpg & c2=$! {baseDir}/camsnap.js snapshot --url "$CAMERA3" --output /tmp/cam3.jpg & c3=$!
Wait for all
wait $c1 $c2 $c3
Create contact sheet
montage /tmp/cam1.jpg /tmp/cam2.jpg /tmp/cam3.jpg
-tile 3x1 -geometry +4+4 +label "Cam 1" "Cam 2" "Cam 3"
-output multisource.jpg
Periodic Recording Scheduler
#!/bin/bash
Record 10-minute clips every hour
URL="rtsp://admin:password@192.168.1.100/stream" OUTPUT_DIR="/var/recordings/$(date +%Y%m)" mkdir -p "$OUTPUT_DIR"
Add to crontab:
0 * * * * /path/to/record-hourly.sh
{baseDir}/camsnap.js record --url "$URL"
--duration 600
--quality high
--output "$OUTPUT_DIR/recording_$(date +%Y%m%d_%H%M).mp4"
Performance Tips
- Use TCP Transport (Default)
TCP is more reliable
{baseDir}/camsnap.js snapshot --url rtsp://192.168.1.100/stream
For UDP (may drop packets)
{baseDir}/camsnap.js snapshot --url rtsp://192.168.1.100/stream --transport udp
- Optimize Quality
Quick preview
{baseDir}/camsnap.js snapshot --url "..." --resize 640x480 --quality 5
Quality capture
{baseDir}/camsnap.js snapshot --url "..." --format png --resize 1
- Use Lower Stream
For Hikvision: use channel 102 (sub-stream) instead of 101
{baseDir}/camsnap.js snapshot --url "rtsp://admin:pass@192.168.1.100/Streaming/Channels/102"
- Parallel Operations
Start multiple captures in parallel
{baseDir}/camsnap.js snapshot --url rtsp://cam1/stream --out /tmp/c1.jpg & cam1_id=$! {baseDir}/camsnap.js snapshot --url rtsp://cam2/stream --out /tmp/c2.jpg & cam2_id=$!
Wait for completion
wait $cam1_id $cam2_id
Technical Details
Connection Flow
-
Parse camera configuration ├── URL or constructed from params ├── Credentials embedded └── Type-specific formatting
-
Test connection ├── ffprobe RTSP stream ├── Verify authentication └── Get stream info
-
Capture ├── FFmpeg connects ├── Extract frame/record └── Save with timestamp
-
Return result └── File path, size, metadata
RTSP Parameters
Default FFmpeg settings:
-rtsp_transport tcp # Use TCP (reliable) -stimeout 5000000 # 5 second read timeout -frames:v 1 # Capture single frame -q:v 2 # JPEG quality
Recording Settings
Quality presets use H.264 with AAC audio:
-low: -crf 28 -preset ultrafast -b:v 500k -r 10 -medium: -crf 23 -preset fast -b:v 1000k -r 15 -high: -crf 20 -preset medium -b:v 2000k -r 25 -maximum: -crf 18 -preset slow -b:v 4000k -r 30
Security Notes
-
Credential Storage: Stored in ~/.camsnap_credentials with 600 permissions
-
URL Handling: Passwords are hidden in output
-
No Encryption: Use system file permissions on credential file
-
Network Security: Camera should be on local network or VPN
-
HTTPS: Not used (RTSP protocol limitation)
-
Rotate Credentials: Periodically update camera passwords
Notes
-
Snapshots include timestamp overlay by default
-
Recording shows progress in terminal
-
Maximum clip duration: 1 hour
-
Supports both TCP and UDP RTSP transport
-
FFmpeg required for all operations
-
Credential names can be any string
-
Camera types automate URL building
-
All output files are verified for non-zero size
-
Special characters in passwords must be URL-encoded
-
Timelapse creation requires separate ffmpeg command
-
Motion detection is basic (sampling only)
-
For production monitoring, use dedicated NVR software