Skip to main content
Camera Workflow converts your media to modern, efficient formats with built-in safety checks and intelligent processing.

Image Conversion

Supported Formats

Input Formats:
  • RAW formats (CR2, NEF, ARW, DNG, etc.)
  • JPEG/JPG
  • PNG
  • HEIC/HEIF
  • TIFF
Output Formats:
  • AVIF (default) - Best compression, modern format
  • WebP - Wide browser support, excellent compression

Image Conversion Process

Images are converted using ImageMagick with metadata preservation:
cmd = exec.CommandContext(ctx, "magick", inputPath,
    "-auto-orient",
    "-quality", fmt.Sprintf("%d", quality),
    "-define", "heic:preserve-orientation=true",
    "-define", "avif:preserve-exif=true",
    "-define", "webp:preserve-exif=true",
    fmt.Sprintf("%s:%s", c.config.PhotoFormat, tempPath))
EXIF metadata (including original date/time) is preserved during conversion to maintain file organization accuracy.

Quality Settings

# Default quality: 80 (range: 1-100)
media-converter --photo-format avif --photo-quality-avif 80 /source /dest
AVIF provides the best compression with typical savings of 30-50% over WebP.

Example: Convert RAW to AVIF

1

Basic conversion

media-converter --photo-format avif /Volumes/Camera/DCIM /Volumes/Archive
2

Adjust quality

media-converter --photo-format avif --photo-quality-avif 90 /source /dest
Higher quality = larger files but better image fidelity.
3

Parallel processing

media-converter --photo-format avif --jobs 8 /source /dest
Process 8 images simultaneously for faster conversion.

Video Conversion

Supported Codecs

Input: Any format supported by FFmpeg (MOV, MP4, AVI, MKV, etc.) Output Codecs:
  • H.265/HEVC (default) - Best balance of quality and compatibility
  • H.264/AVC - Maximum compatibility
  • AV1 - Best compression, slower encoding

Video Conversion Process

Videos are converted using FFmpeg with configurable quality:
# H.265 with hardware acceleration (macOS VideoToolbox)
ffmpeg -hwaccel videotoolbox \
  -i input.mov \
  -c:v hevc_videotoolbox \
  -b:v 4.5M \
  -c:a aac -b:a 128k \
  -movflags +faststart \
  -map_metadata 0 \
  output.mp4

Hardware Acceleration

Camera Workflow automatically detects and uses hardware acceleration:
VideoToolbox - Native macOS hardware encoding
# Enabled by default
media-converter --video-codec h265 /source /dest
Provides 3-5x faster encoding with minimal quality loss.

CRF Quality Control

CRF (Constant Rate Factor) controls quality - lower values = better quality:
# High quality (larger files)
media-converter --video-codec h265 --video-crf 23 /source /dest

# Balanced (default)
media-converter --video-codec h265 --video-crf 28 /source /dest

# Smaller files (lower quality)
media-converter --video-codec h265 --video-crf 32 /source /dest
Recommended CRF values:
  • H.265: 23-32 (default: 28)
  • H.264: 18-28 (default: 23)
  • AV1: 28-45 (default: 32)

Example: Convert Videos to H.265

1

Basic conversion

media-converter --video-codec h265 /Videos /Archive
Uses hardware acceleration with balanced quality (CRF 28).
2

High quality conversion

media-converter --video-codec h265 --video-crf 23 /source /dest
Lower CRF produces larger files with better quality.
3

AV1 for maximum compression

media-converter --video-codec av1 --video-crf 32 /source /dest
AV1 encoding is significantly slower but produces the smallest files.

Parallel Processing

Worker Configuration

Control concurrent conversions for optimal performance:
# Auto-detect (CPU cores - 1)
media-converter /source /dest

# Explicit worker count
media-converter --jobs 4 /source /dest

# Maximum parallelism (use all cores)
media-converter --jobs 16 /source /dest
Video conversions are automatically limited to 2 concurrent jobs for CPU protection unless adaptive workers are enabled.

Adaptive Workers (Videos)

Dynamically adjust workers based on system resources:
media-converter \
  --adaptive-workers \
  --adaptive-workers-min 1 \
  --adaptive-workers-max 6 \
  --adaptive-workers-cpu-high 80.0 \
  --adaptive-workers-cpu-low 50.0 \
  /source /dest
How it works:
  • Starts with minimum workers (1)
  • Increases workers when CPU < 50% and memory available
  • Decreases workers when CPU > 80% or memory low
  • Checks every 3 seconds (configurable)

Safety Features

Atomic Operations

All conversions use atomic operations:
1

Temporary conversion

Files are converted to .tmp suffix:
IMG_1234.CR2 β†’ IMG_1234.avif.tmp
2

Integrity verification

Output file is verified using ImageMagick or FFprobe:
cmd := exec.Command("magick", "identify", imagePath)
if err := cmd.Run(); err != nil {
    return fmt.Errorf("image is corrupted")
}
3

Atomic rename

After verification, atomic rename to final name:
os.Rename(tempPath, outputPath)

Timeout Protection

Conversions have configurable timeouts to prevent hanging:
# Photo timeout (default: 300s)
media-converter --timeout-photo 600 /source /dest

# Video timeout (default: 1800s = 30 min)
media-converter --timeout-video 3600 /source /dest
If a conversion exceeds the timeout, it’s cancelled and marked as failed.

Idempotency & Recovery

Run safely multiple times:
# First run - converts all files
media-converter /source /dest

# Interrupted with Ctrl+C
# ...

# Resume - skips already converted files
media-converter /source /dest
Recovery features:
  • Detects existing converted files and skips them
  • Verifies file integrity on resume
  • Re-converts corrupted files automatically
  • Cleans up abandoned .tmp and .processing files
See Security Features for detailed recovery mechanisms.

Progress Tracking

Real-time Progress

πŸ“ˆ Progress: [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘] 156/234 (66.7%) | ETA: 12m34s

πŸ“· IMG_5678.CR2 (42.3 MB) -> avif
βœ… IMG_5678.CR2 -> 20240315_IMG_5678.avif | -68% (42.3->13.5 MB) | 3.2s

πŸ“Ή VID_1234.MOV (1.2 GB) - converting...
   VID_1234.MOV: [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘] 35.2% (2.1x, ETA: 8m15s)

Statistics Report

╔══════════════════════════════════════════════════════════════╗
β•‘                 Conversion Complete                          β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

βœ… Files processed: 234/234
⏭️  Files skipped (already exist): 12
πŸ”„ Files recovered from corruption: 3
🧹 Abandoned files cleaned: 2
⏱️  Total time: 45m12s
πŸ“Š Original size: 45.2 GB
πŸ“¦ Compressed size: 18.7 GB
πŸ’Ύ Space saved: 26.5 GB (58.6% reduction)
πŸ’° Estimated S3 savings: $0.61/month ($7.32/year)

Common Use Cases

RAW Photo Workflow

# Convert RAW photos to AVIF, preserve originals
media-converter \
  --photo-format avif \
  --photo-quality-avif 85 \
  --keep-originals \
  --organize-by-date \
  --jobs 8 \
  /Volumes/Camera/DCIM /Volumes/Archive/Photos

Video Archive Optimization

# Convert videos to H.265 with hardware acceleration
media-converter \
  --video-codec h265 \
  --video-crf 28 \
  --video-acceleration \
  --adaptive-workers \
  --adaptive-workers-max 4 \
  /Videos/Original /Videos/Compressed

Mixed Media with Deletion

# Convert everything, delete originals after verification
media-converter \
  --photo-format avif \
  --video-codec h265 \
  --keep-originals=false \
  --organize-by-date \
  /source /dest
Always test with --dry-run first when using --keep-originals=false!

Configuration File

Store preferences in ~/.media-converter.yaml:
# Photo settings
photo_format: avif
photo_quality_avif: 85
photo_quality_webp: 90

# Video settings
video_codec: h265
video_crf: 28
video_acceleration: true

# Processing
max_jobs: 8
keep_originals: true
organize_by_date: true

# Adaptive workers
adaptive_workers:
  enabled: true
  min_workers: 1
  max_workers: 6
  cpu_high_threshold: 80.0
  cpu_low_threshold: 50.0
  mem_low_percent: 20.0
  check_interval: 3
Then simply run:
media-converter /source /dest

Build docs developers (and LLMs) love