video-rendering 1.0.1
Convert image sequences to MP4/GIF and MP4 videos to GIF using FFmpeg
License: MIT
Requires Python: >=3.10
Keywords: animation, ffmpeg, gif, images, mp4, rendering, video

# video-rendering

Convert image sequences to MP4/GIF and MP4 videos to GIF using FFmpeg.

[![PyPI version](https://badge.fury.io/py/video-rendering.svg)](https://badge.fury.io/py/video-rendering)
[![CI](https://github.com/silviobaratto/video-rendering/actions/workflows/ci.yml/badge.svg)](https://github.com/silviobaratto/video-rendering/actions/workflows/ci.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- Convert image sequences to MP4 video
- Convert image sequences to GIF with palette optimization
- Convert MP4 videos to optimized GIFs
- Natural sorting of images (1, 2, 10 instead of 1, 10, 2)
- Quality presets for different use cases
- Progress feedback during rendering
- Full type hints and PEP 561 compliance

## Requirements

- Python 3.10+
- FFmpeg (must be installed and in PATH)

## Installation

```bash
pip install video-rendering
```

### Installing FFmpeg

**macOS:**
```bash
brew install ffmpeg
```

**Ubuntu/Debian:**
```bash
sudo apt install ffmpeg
```

**Windows:**
Download from [ffmpeg.org](https://ffmpeg.org/download.html) or use:
```bash
choco install ffmpeg
```

## Quick Start

### Command Line

```bash
# Convert images to video
video-render images ./frames/ -o output.mp4

# Convert images to GIF
video-render images ./frames/ -o output.gif --fps 15

# Convert video to GIF
video-render convert video.mp4 -o output.gif --fps 10 --width 480

# Check FFmpeg installation
video-render doctor
```

### Python API

```python
from video_rendering import VideoRenderer, GifConverter

# Images to video
renderer = VideoRenderer()
renderer.render("./frames/", "output.mp4", fps=30)

# Images to GIF
renderer.render("./frames/", "output.gif", fps=15)

# Video to GIF
converter = GifConverter()
converter.convert("video.mp4", "output.gif", fps=10, width=480)
```

## CLI Reference

### `video-render images`

Convert image sequence to video or GIF.

```bash
video-render images <FOLDER> -o <OUTPUT> [OPTIONS]
```

| Option | Default | Description |
|--------|---------|-------------|
| `-o, --output` | Required | Output file path (.mp4, .gif, etc.) |
| `--fps` | 30 | Frames per second |
| `--pattern` | None | Glob pattern (e.g., "frame_*.png") |
| `--sort` | natural | Sorting: natural, alphabetical, mtime, ctime |
| `--codec` | h264 | Video codec: h264, h265, vp9 |
| `--quality` | auto | Quality: low, medium, high, lossless |

### `video-render convert`

Convert video to GIF with palette optimization.

```bash
video-render convert <VIDEO> -o <OUTPUT> [OPTIONS]
```

| Option | Default | Description |
|--------|---------|-------------|
| `-o, --output` | Required | Output GIF path |
| `--fps` | 10 | Output frames per second |
| `--width` | None | Resize width (maintains aspect ratio) |
| `--start` | None | Start time in seconds |
| `--duration` | None | Duration in seconds |

### `video-render doctor`

Check FFmpeg installation and system requirements.

```bash
video-render doctor
```

## Python API Reference

### VideoRenderer

```python
from video_rendering import VideoRenderer, Quality, Codec, SortOrder

renderer = VideoRenderer()

# Basic usage
renderer.render("./frames/", "output.mp4")

# All options
renderer.render(
    input_directory="./frames/",
    output_path="output.mp4",
    fps=30,
    pattern="frame_*.png",
    sort_order=SortOrder.NATURAL,
    codec=Codec.H264,
    quality=Quality.HIGH,
    show_progress=True,
)

# List images that would be rendered
images = renderer.list_images("./frames/")

# Get image count
count = renderer.get_image_count("./frames/")
```

### GifConverter

```python
from video_rendering import GifConverter

converter = GifConverter()

# Basic usage
converter.convert("video.mp4", "output.gif")

# All options
converter.convert(
    input_path="video.mp4",
    output_path="output.gif",
    fps=10,
    width=480,
    start_time=5.0,
    duration=10.0,
    show_progress=True,
)

# Get video info
info = converter.get_video_info("video.mp4")
print(f"Duration: {info['duration']}s")
print(f"Resolution: {info['width']}x{info['height']}")
```

### Quality Presets

| Preset | CRF | Use Case |
|--------|-----|----------|
| `Quality.LOW` | 28 | Quick previews, small files |
| `Quality.MEDIUM` | 23 | Balanced (default for GIF) |
| `Quality.HIGH` | 18 | High quality (default for video) |
| `Quality.LOSSLESS` | 0 | Maximum quality |

### Exceptions

```python
from video_rendering import (
    VideoRenderingError,    # Base exception
    FFmpegNotFoundError,    # FFmpeg not installed
    FFmpegError,            # FFmpeg command failed
    NoImagesFoundError,     # No images in directory
    InvalidImageError,      # Invalid image file
    InvalidVideoError,      # Invalid video file
    OutputPathError,        # Invalid output path
)
```

## Development

```bash
# Clone repository
git clone https://github.com/silviobaratto/video-rendering.git
cd video-rendering

# Install with dev dependencies
pip install -e ".[dev]"

# Setup pre-commit hooks
pre-commit install

# Run tests
make test

# Run linter
make lint

# Run type checker
make typecheck

# Run all checks
make check
```

## License

MIT License - see [LICENSE](LICENSE) for details.