FFmpeg
FFmpeg and ffprobe are installed in the Docker image and power the server-side media pipeline (behind enable_media_optimization) plus media inspection in the compatibility scan.
Commands Used by the Platform
Probe dimensions
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4
Optimize an image in place
Scales to max 1920×1080 preserving aspect ratio, then applies format-specific quality:
# JPEG
ffmpeg -i input.jpg -vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" -q:v 3 output.jpg -y
# WebP
ffmpeg -i input.webp -vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" -c:v libwebp -quality 85 output.webp -y
# PNG
ffmpeg -i input.png -vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" -compression_level 9 output.png -y
Generate an image variant
Widths used: 320, 640, 1024, 1920 (skipped when wider than the source). -threads 1 keeps CPU usage predictable on a shared VPS.
ffmpeg -i input.jpg -vf scale=640:-1 -c:v libwebp -quality 80 -threads 1 output_640w.webp -y
Oversized sources (over 8000 px) are downscaled first:
ffmpeg -i input.jpg -vf "scale='min(8000,iw)':'min(8000,ih)':force_original_aspect_ratio=decrease" -c:v libwebp -quality 80 -threads 1 downscaled.webp -y
Optimize a video in place
ffmpeg -i input.mp4 \
-vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" \
-c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k \
-movflags +faststart \
output.mp4 -y
Generate a video variant
Heights used: 480, 720, 1080 (skipped when taller than the source). scale=-2 keeps an even pixel count, required by H.264.
ffmpeg -i input.mp4 -vf scale=-2:720 \
-c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k \
-movflags +faststart -threads 1 \
output_720p.mp4 -y
Common Operations
| Task | Command |
|---|---|
| Trim without re-encoding | ffmpeg -ss 00:00:10 -to 00:00:30 -i input.mp4 -c copy out.mp4 |
| Extract a frame | ffmpeg -i input.mp4 -ss 00:00:05 -frames:v 1 out.jpg |
| Strip audio | ffmpeg -i input.mp4 -an -c:v copy out.mp4 |
| Move the index for streaming | ffmpeg -i input.mp4 -c copy -movflags +faststart out.mp4 |
| Re-encode to H.264/AAC | ffmpeg -i input.mov -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart out.mp4 |
Operational Notes
- Processes are started with
ArgumentList(never a shell), so file paths are not re-parsed. - Timeouts: images 5 minutes, videos 30 minutes, ffprobe 30 seconds; on timeout the process tree is killed.
- A non-zero exit code fails the job; the background service retries up to 3 times.
- The optimizer only replaces the original when the result is smaller; otherwise the original is kept.