# Video Optimization Guide

**Last Updated:** 2026-04-08

Guide for optimizing video files for web delivery, ensuring files stay under GitHub's 100MB limit while maintaining visual quality.

## Problem

GitHub.com has a **100MB file size limit** for standard Git operations. Files over 100MB will prevent pushing to GitHub. Large video files (especially 4K/vertical videos) can easily exceed this limit.

## Solution

We use an automated optimization script (`v2/scripts/optimize-events-videos.py`) that:

1. **Scales resolution** - Reduces 4K videos to web-appropriate sizes (max 1920x2160)
2. **Optimizes compression** - Uses CRF (Constant Rate Factor) encoding for quality-based compression
3. **Generates multiple formats** - Creates both MP4 (H.264) and WebM (VP9) for browser compatibility
4. **Reduces audio bitrate** - Optimizes audio to 96kbps (sufficient for speech/music)

## Optimization Settings

### MP4 (H.264) Settings
- **CRF:** 26 (balanced) or 28 (aggressive)
- **Preset:** medium (balance between speed and quality)
- **Max bitrate:** 5M
- **Audio:** AAC 96kbps
- **Faststart:** Enabled (moov atom at start for web streaming)

### WebM (VP9) Settings
- **CRF:** 35 (balanced) or 38 (aggressive)
- **Audio:** Opus 96kbps
- **Multi-threading:** Enabled (row-mt)
- **Deadline:** good (quality vs speed balance)

### Resolution Limits
- **Max width:** 1920px
- **Max height:** 2160px
- **Aspect ratio:** Maintained automatically

## Usage

### Basic Optimization (Balanced Quality)
```bash
python3 v2/scripts/optimize-events-videos.py
```

### Aggressive Compression (Smaller Files)
```bash
python3 v2/scripts/optimize-events-videos.py --aggressive
```

### Dry Run (Preview Changes)
```bash
python3 v2/scripts/optimize-events-videos.py --dry-run
```

## Results

### Before Optimization
- `supper-club-2-hero.mp4`: **100MB** ❌ (GitHub limit exceeded)
- `supper-club-1-hero.mp4`: 40MB
- `intergastra-2026-hero.mp4`: 56MB

### After Optimization (Aggressive Mode)
- `supper-club-2-hero.mp4`: **18MB** ✅ (82% reduction)
- `supper-club-1-hero.mp4`: 6.8MB (83% reduction)
- `intergastra-2026-hero.mp4`: 16MB (71% reduction)

### INTERNORGA 2026 (balanced, 2026-04)
- Source: `v2/img/events/internorga-2026/internorga-2026.MOV` (~49.5MB ProRes/H.264 camera export)
- Outputs: `internorga-2026-hero.mp4` (~6.8MB), `internorga-2026-hero.webm` (~5.3MB), poster WebP
- Used on `/veranstaltungen` (`v2/pages/static_events.php`). Prefer committing optimized outputs; keep the raw `.MOV` local if you want to avoid large blobs in git.

## Best Practices

### 1. Always Optimize Before Committing
Run the optimization script before committing video files to ensure they're under 100MB.

### 2. Use WebM as Primary Format
Modern browsers prefer WebM (VP9) for better compression. Serve WebM first, MP4 as fallback:

```html
<video>
  <source src="video.webm" type="video/webm">
  <source src="video.mp4" type="video/mp4">
</video>
```

### 3. CRF Value Guidelines

| CRF | Quality | Use Case | File Size |
|-----|---------|----------|-----------|
| 18 | Visually lossless | Archiving | ~80% of original |
| 23 | High quality | Web streaming | ~50% of original |
| 26 | Good quality | Web (balanced) | ~40% of original |
| 28 | Medium quality | Web (aggressive) | ~30% of original |
| 32 | Lower quality | Preview clips | ~15% of original |

### 4. Resolution Guidelines

- **Desktop:** Max 1920px width
- **Mobile:** Max 1080px width
- **Vertical videos:** Max 2160px height
- **Always maintain aspect ratio**

### 5. Audio Optimization

- **Speech:** 64-96kbps AAC/Opus
- **Music:** 96-128kbps AAC/Opus
- **Background:** Can be removed entirely (`-an` flag)

### 6. Testing Quality

After optimization:
1. **Visual inspection** - Check for artifacts, blurriness
2. **File size** - Verify under 100MB
3. **Browser testing** - Test playback in Chrome, Firefox, Safari
4. **Performance** - Check Core Web Vitals (LCP, FID)

## Technical Details

### CRF (Constant Rate Factor)
- **Lower CRF = Higher quality, larger files**
- **Higher CRF = Lower quality, smaller files**
- CRF 23-28 is the sweet spot for web delivery
- VP9 can use higher CRF values (30-40) than H.264

### Two-Pass Encoding
For maximum quality/size ratio, two-pass encoding can be used:
```bash
# First pass
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -f null /dev/null

# Second pass
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 output.mp4
```

However, CRF encoding (single-pass) is faster and produces similar results for web delivery.

### Faststart Flag
The `-movflags +faststart` flag moves the moov atom to the beginning of the MP4 file, enabling:
- **Progressive download** - Video can start playing before fully downloaded
- **Better streaming** - Improved compatibility with CDNs and web servers
- **Faster initial playback** - Reduced buffering time

## Troubleshooting

### Video Still Too Large
1. Use `--aggressive` flag for higher compression
2. Reduce resolution further (adjust MAX_WIDTH/MAX_HEIGHT in script)
3. Increase CRF values (reduce quality slightly)
4. Remove audio if not needed (`-an` flag)

### Quality Too Low
1. Use balanced mode (default) instead of aggressive
2. Reduce CRF values (increase quality)
3. Check if source video quality is sufficient

### Encoding Errors
1. Verify ffmpeg is installed: `ffmpeg -version`
2. Check video codec compatibility
3. Ensure sufficient disk space
4. Check file permissions

## Dependencies

- **ffmpeg** - Video encoding/decoding
  - Install: `brew install ffmpeg` (macOS) or `apt-get install ffmpeg` (Linux)
- **Python 3** - Script execution
- **PIL/Pillow** (optional) - WebP conversion for posters/thumbnails

## Related Files

- `v2/scripts/optimize-events-videos.py` - Main optimization script
- `v2/pages/static_events.php` - Events page using optimized videos
- `docs/performance-optimization/` - General performance optimization guides

## References

- [FFmpeg Documentation](https://ffmpeg.org/documentation.html)
- [Web.dev Video Performance](https://web.dev/learn/performance/video-performance)
- [CRF Guide](https://trac.ffmpeg.org/wiki/Encode/H.264#crf)
- [VP9 Encoding Guide](https://developers.google.com/media/vp9)
