- Add video-360 extra for core 360° processing (py360convert, opencv, numpy, scipy) - Add spatial-audio extra for spatial audio processing (librosa, soundfile) - Add metadata-360 extra for enhanced metadata extraction (exifread) - Add video-360-full extra for complete 360° feature set - Update README with installation options and feature documentation - Maintain backward compatibility with existing basic installation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
536 lines
14 KiB
Markdown
536 lines
14 KiB
Markdown
<div align="center">
|
|
|
|
# 🎬 Video Processor
|
|
|
|
**A Modern Python Library for Professional Video Processing**
|
|
|
|
[](https://www.python.org/downloads/)
|
|
[](https://github.com/astral-sh/uv)
|
|
[](https://github.com/astral-sh/ruff)
|
|
[](http://mypy-lang.org/)
|
|
[](https://pytest.org/)
|
|
|
|
*Extracted from the demostar Django application, now a standalone powerhouse for video encoding, thumbnail generation, and sprite creation.*
|
|
|
|
[Features](#-features) •
|
|
[Installation](#-installation) •
|
|
[Quick Start](#-quick-start) •
|
|
[Examples](#-examples) •
|
|
[API Reference](#-api-reference)
|
|
|
|
</div>
|
|
|
|
---
|
|
|
|
## ✨ Features
|
|
|
|
<table>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
### 🎥 **Video Encoding**
|
|
- **Multi-format support**: MP4 (H.264), WebM (VP9), OGV (Theora)
|
|
- **Two-pass encoding** for optimal quality
|
|
- **Professional presets**: Low, Medium, High, Ultra
|
|
- **Customizable bitrates** and quality settings
|
|
|
|
</td>
|
|
<td width="50%">
|
|
|
|
### 🖼️ **Thumbnails & Sprites**
|
|
- **Smart thumbnail extraction** at any timestamp
|
|
- **Seekbar sprite sheets** with WebVTT files
|
|
- **Configurable intervals** and dimensions
|
|
- **Mobile-optimized** output options
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td width="50%">
|
|
|
|
### ⚡ **Background Processing**
|
|
- **Procrastinate integration** for async tasks
|
|
- **PostgreSQL job queue** management
|
|
- **Scalable worker architecture**
|
|
- **Progress tracking** and error handling
|
|
|
|
</td>
|
|
<td width="50%">
|
|
|
|
### 🛠️ **Modern Development**
|
|
- **Type-safe** with full type hints
|
|
- **Pydantic V2** configuration validation
|
|
- **uv** for lightning-fast dependency management
|
|
- **ruff** for code quality and formatting
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2">
|
|
|
|
### 🌐 **360° Video Support** *(Optional)*
|
|
- **Spherical video detection** and metadata extraction
|
|
- **Projection conversions** (equirectangular, cubemap, stereographic)
|
|
- **360° thumbnail generation** with multiple viewing angles
|
|
- **Spatial audio processing** for immersive experiences
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
---
|
|
|
|
## 📦 Installation
|
|
|
|
### Quick Install
|
|
|
|
```bash
|
|
# Basic installation (standard video processing)
|
|
uv add video-processor
|
|
|
|
# With 360° video support
|
|
uv add "video-processor[video-360]"
|
|
|
|
# With spatial audio processing
|
|
uv add "video-processor[spatial-audio]"
|
|
|
|
# Complete 360° feature set
|
|
uv add "video-processor[video-360-full]"
|
|
|
|
# Or using pip
|
|
pip install video-processor
|
|
pip install "video-processor[video-360-full]"
|
|
```
|
|
|
|
### Optional Features
|
|
|
|
#### 🌐 360° Video Processing
|
|
For immersive video processing capabilities:
|
|
- **`video-360`**: Core 360° video processing (py360convert, opencv, numpy, scipy)
|
|
- **`spatial-audio`**: Spatial audio processing (librosa, soundfile)
|
|
- **`metadata-360`**: Enhanced 360° metadata extraction (exifread)
|
|
- **`video-360-full`**: Complete 360° package (includes all above)
|
|
|
|
#### 📦 Dependency Details
|
|
```bash
|
|
# Core 360° processing
|
|
uv add "video-processor[video-360]"
|
|
# Includes: py360convert, opencv-python, numpy, scipy
|
|
|
|
# Spatial audio support
|
|
uv add "video-processor[spatial-audio]"
|
|
# Includes: librosa, soundfile
|
|
|
|
# Complete 360° experience
|
|
uv add "video-processor[video-360-full]"
|
|
# Includes: All 360° dependencies + exifread
|
|
```
|
|
|
|
### Development Setup
|
|
|
|
```bash
|
|
git clone <repository>
|
|
cd video_processor
|
|
|
|
# Install with all development dependencies
|
|
uv sync --dev
|
|
|
|
# Install with dev + 360° features
|
|
uv sync --dev --extra video-360-full
|
|
|
|
# Verify installation
|
|
uv run pytest
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### Basic Video Processing
|
|
|
|
```python
|
|
from pathlib import Path
|
|
from video_processor import VideoProcessor, ProcessorConfig
|
|
|
|
# 📋 Configure your processor
|
|
config = ProcessorConfig(
|
|
base_path=Path("/tmp/video_output"),
|
|
output_formats=["mp4", "webm"],
|
|
quality_preset="high" # 🎯 Professional quality
|
|
)
|
|
|
|
# 🎬 Initialize and process
|
|
processor = VideoProcessor(config)
|
|
result = processor.process_video(
|
|
input_path="input_video.mp4",
|
|
output_dir="outputs"
|
|
)
|
|
|
|
# 📊 Results
|
|
print(f"🎥 Video ID: {result.video_id}")
|
|
print(f"📁 Formats: {list(result.encoded_files.keys())}")
|
|
print(f"🖼️ Thumbnail: {result.thumbnail_file}")
|
|
print(f"🎞️ Sprites: {result.sprite_files}")
|
|
```
|
|
|
|
### Async Background Processing
|
|
|
|
```python
|
|
import asyncio
|
|
from video_processor.tasks import setup_procrastinate
|
|
|
|
async def process_in_background():
|
|
# 🗄️ Connect to PostgreSQL
|
|
app = setup_procrastinate("postgresql://user:pass@localhost/db")
|
|
|
|
# 📤 Submit job
|
|
job = await app.tasks.process_video_async.defer_async(
|
|
input_path="/path/to/video.mp4",
|
|
output_dir="/path/to/output",
|
|
config_dict={"quality_preset": "ultra"}
|
|
)
|
|
|
|
print(f"✅ Job queued: {job.id}")
|
|
|
|
asyncio.run(process_in_background())
|
|
```
|
|
|
|
---
|
|
|
|
## ⚙️ Configuration
|
|
|
|
### Quality Presets Comparison
|
|
|
|
<div align="center">
|
|
|
|
| 🎯 Preset | 📺 Video Bitrate | 🔊 Audio Bitrate | 🎨 CRF | 💡 Best For |
|
|
|-----------|------------------|------------------|---------|-------------|
|
|
| **Low** | 1,000k | 128k | 28 | 📱 Mobile, limited bandwidth |
|
|
| **Medium** | 2,500k | 192k | 23 | 🌐 Standard web delivery |
|
|
| **High** | 5,000k | 256k | 18 | 🎬 High-quality streaming |
|
|
| **Ultra** | 10,000k | 320k | 15 | 🏛️ Archive, professional use |
|
|
|
|
</div>
|
|
|
|
### Advanced Configuration
|
|
|
|
```python
|
|
from video_processor import ProcessorConfig
|
|
from pathlib import Path
|
|
|
|
config = ProcessorConfig(
|
|
# 📂 Storage & Paths
|
|
base_path=Path("/media/videos"),
|
|
storage_backend="local", # 🔮 S3 coming soon!
|
|
|
|
# 🎥 Video Settings
|
|
output_formats=["mp4", "webm", "ogv"],
|
|
quality_preset="ultra",
|
|
|
|
# 🖼️ Thumbnails & Sprites
|
|
thumbnail_timestamp=30, # 📍 30 seconds in
|
|
sprite_interval=5.0, # 🎞️ Every 5 seconds
|
|
|
|
# 🛠️ System
|
|
ffmpeg_path="/usr/local/bin/ffmpeg" # 🔧 Custom FFmpeg
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 💡 Examples
|
|
|
|
Explore our comprehensive examples in the [`examples/`](examples/) directory:
|
|
|
|
### 📝 Available Examples
|
|
|
|
| Example | Description | Features |
|
|
|---------|-------------|-----------|
|
|
| [`basic_usage.py`](examples/basic_usage.py) | 🎯 Simple synchronous processing | Configuration, encoding, thumbnails |
|
|
| [`async_processing.py`](examples/async_processing.py) | ⚡ Background task processing | Procrastinate, job queuing, monitoring |
|
|
| [`custom_config.py`](examples/custom_config.py) | 🛠️ Advanced configuration scenarios | Quality presets, validation, custom paths |
|
|
|
|
### 🎬 Real-World Usage Patterns
|
|
|
|
<details>
|
|
<summary><b>🏢 Production Video Pipeline</b></summary>
|
|
|
|
```python
|
|
# Multi-format encoding for video platform
|
|
config = ProcessorConfig(
|
|
base_path=Path("/var/media/uploads"),
|
|
output_formats=["mp4", "webm"], # Cross-browser support
|
|
quality_preset="high",
|
|
sprite_interval=10.0 # Balanced performance
|
|
)
|
|
|
|
processor = VideoProcessor(config)
|
|
result = processor.process_video(user_upload, output_dir)
|
|
|
|
# Generate multiple qualities
|
|
for quality in ["medium", "high"]:
|
|
config.quality_preset = quality
|
|
processor = VideoProcessor(config)
|
|
# Process to different quality folders...
|
|
```
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><b>📱 Mobile-Optimized Processing</b></summary>
|
|
|
|
```python
|
|
# Lightweight encoding for mobile delivery
|
|
mobile_config = ProcessorConfig(
|
|
base_path=Path("/tmp/mobile_videos"),
|
|
output_formats=["mp4"], # Mobile-friendly format
|
|
quality_preset="low", # Reduced bandwidth
|
|
sprite_interval=15.0 # Fewer sprites
|
|
)
|
|
```
|
|
|
|
</details>
|
|
|
|
---
|
|
|
|
## 📚 API Reference
|
|
|
|
### 🎬 VideoProcessor
|
|
|
|
The main orchestrator for all video processing operations.
|
|
|
|
#### 🔧 Methods
|
|
|
|
```python
|
|
# Process video to all configured formats
|
|
result = processor.process_video(
|
|
input_path: Path | str,
|
|
output_dir: Path | str | None = None,
|
|
video_id: str | None = None
|
|
) -> VideoProcessingResult
|
|
|
|
# Encode to specific format
|
|
output_path = processor.encode_video(
|
|
input_path: Path,
|
|
output_dir: Path,
|
|
format_name: str,
|
|
video_id: str
|
|
) -> Path
|
|
|
|
# Generate thumbnail at timestamp
|
|
thumbnail = processor.generate_thumbnail(
|
|
video_path: Path,
|
|
output_dir: Path,
|
|
timestamp: int,
|
|
video_id: str
|
|
) -> Path
|
|
|
|
# Create sprite sheet and WebVTT
|
|
sprites = processor.generate_sprites(
|
|
video_path: Path,
|
|
output_dir: Path,
|
|
video_id: str
|
|
) -> tuple[Path, Path]
|
|
```
|
|
|
|
### ⚙️ ProcessorConfig
|
|
|
|
Type-safe configuration with automatic validation.
|
|
|
|
#### 📋 Essential Fields
|
|
|
|
```python
|
|
class ProcessorConfig:
|
|
base_path: Path # 📂 Base directory
|
|
output_formats: list[str] # 🎥 Video formats
|
|
quality_preset: str # 🎯 Quality level
|
|
storage_backend: str # 💾 Storage type
|
|
ffmpeg_path: str # 🛠️ FFmpeg binary
|
|
thumbnail_timestamp: int # 🖼️ Thumbnail position
|
|
sprite_interval: float # 🎞️ Sprite frequency
|
|
```
|
|
|
|
### 📊 VideoProcessingResult
|
|
|
|
Comprehensive result object with all output information.
|
|
|
|
```python
|
|
@dataclass
|
|
class VideoProcessingResult:
|
|
video_id: str # 🆔 Unique identifier
|
|
encoded_files: dict[str, Path] # 📁 Format → file mapping
|
|
thumbnail_file: Path | None # 🖼️ Thumbnail image
|
|
sprite_files: tuple[Path, Path] | None # 🎞️ Sprite + WebVTT
|
|
metadata: VideoMetadata # 📊 Video properties
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 Development
|
|
|
|
### 🛠️ Development Commands
|
|
|
|
```bash
|
|
# 📦 Install dependencies
|
|
uv sync
|
|
|
|
# 🧪 Run test suite
|
|
uv run pytest -v
|
|
|
|
# 📊 Test coverage
|
|
uv run pytest --cov=video_processor
|
|
|
|
# ✨ Code formatting
|
|
uv run ruff format .
|
|
|
|
# 🔍 Linting
|
|
uv run ruff check .
|
|
|
|
# 🎯 Type checking
|
|
uv run mypy src/
|
|
```
|
|
|
|
### 📈 Test Coverage
|
|
|
|
Our comprehensive test suite covers:
|
|
|
|
- ✅ Configuration validation and type checking
|
|
- ✅ Path utilities and file operations
|
|
- ✅ FFmpeg integration and error handling
|
|
- ✅ Video metadata extraction
|
|
- ✅ Background task processing
|
|
|
|
```bash
|
|
========================== test session starts ==========================
|
|
tests/test_config.py ✅✅✅✅ [33%]
|
|
tests/test_utils.py ✅✅✅✅✅✅✅✅ [100%]
|
|
|
|
======================== 12 passed in 0.11s ========================
|
|
```
|
|
|
|
---
|
|
|
|
## 📦 Dependencies
|
|
|
|
### 🎯 Core Dependencies
|
|
|
|
| Package | Purpose | Why We Use It |
|
|
|---------|---------|---------------|
|
|
| `ffmpeg-python` | FFmpeg integration | 🎬 Professional video processing |
|
|
| `msprites2` | Sprite generation | 🎞️ Seekbar thumbnails (forked for fixes) |
|
|
| `procrastinate` | Background tasks | ⚡ Scalable async processing |
|
|
| `pydantic` | Configuration | ⚙️ Type-safe settings validation |
|
|
| `pillow` | Image processing | 🖼️ Thumbnail manipulation |
|
|
|
|
### 🔧 Development Tools
|
|
|
|
| Tool | Purpose | Benefits |
|
|
|------|---------|----------|
|
|
| `uv` | Package management | 🚀 Ultra-fast dependency resolution |
|
|
| `ruff` | Linting & formatting | ⚡ Lightning-fast code quality |
|
|
| `pytest` | Testing framework | 🧪 Reliable test execution |
|
|
| `mypy` | Type checking | 🎯 Static type analysis |
|
|
| `coverage` | Test coverage | 📊 Quality assurance |
|
|
|
|
---
|
|
|
|
## 🌟 Why Video Processor?
|
|
|
|
<div align="center">
|
|
|
|
### 🆚 Comparison with Alternatives
|
|
|
|
| Feature | Video Processor | FFmpeg CLI | moviepy | OpenCV |
|
|
|---------|----------------|------------|---------|--------|
|
|
| **Two-pass encoding** | ✅ | ✅ | ❌ | ❌ |
|
|
| **Multiple formats** | ✅ | ✅ | ✅ | ❌ |
|
|
| **Background processing** | ✅ | ❌ | ❌ | ❌ |
|
|
| **Type safety** | ✅ | ❌ | ❌ | ❌ |
|
|
| **Sprite generation** | ✅ | ❌ | ❌ | ❌ |
|
|
| **Modern Python** | ✅ | N/A | ❌ | ❌ |
|
|
|
|
</div>
|
|
|
|
---
|
|
|
|
## 📋 Requirements
|
|
|
|
### 🖥️ System Requirements
|
|
|
|
- **Python 3.11+** - Modern Python features
|
|
- **FFmpeg** - Video processing engine
|
|
- **PostgreSQL** - Background job processing (optional)
|
|
|
|
### 🐧 Installation Commands
|
|
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt install ffmpeg postgresql-client
|
|
|
|
# macOS
|
|
brew install ffmpeg postgresql
|
|
|
|
# Arch Linux
|
|
sudo pacman -S ffmpeg postgresql
|
|
```
|
|
|
|
---
|
|
|
|
## 🤝 Contributing
|
|
|
|
We welcome contributions! Here's how to get started:
|
|
|
|
### 🚀 Quick Contribution Guide
|
|
|
|
1. **🍴 Fork** the repository
|
|
2. **🌿 Create** a feature branch (`git checkout -b feature/amazing-feature`)
|
|
3. **📝 Make** your changes with tests
|
|
4. **🧪 Test** everything (`uv run pytest`)
|
|
5. **✨ Format** code (`uv run ruff format .`)
|
|
6. **📤 Submit** a pull request
|
|
|
|
### 🎯 Areas We'd Love Help With
|
|
|
|
- 🌐 **S3 storage backend** implementation
|
|
- 🎞️ **Additional video formats** (AV1, HEVC)
|
|
- 📊 **Progress tracking** and monitoring
|
|
- 🐳 **Docker integration** examples
|
|
- 📖 **Documentation** improvements
|
|
|
|
---
|
|
|
|
## 📜 License
|
|
|
|
This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.
|
|
|
|
---
|
|
|
|
## 🎉 Changelog
|
|
|
|
### 🌟 v0.1.0 - Initial Release
|
|
|
|
- ✨ **Multi-format encoding**: MP4, WebM, OGV support
|
|
- 🖼️ **Thumbnail generation** with customizable timestamps
|
|
- 🎞️ **Sprite sheet creation** with WebVTT files
|
|
- ⚡ **Background processing** with Procrastinate
|
|
- ⚙️ **Type-safe configuration** with Pydantic V2
|
|
- 🛠️ **Modern tooling**: uv, ruff, pytest integration
|
|
- 📚 **Comprehensive documentation** and examples
|
|
|
|
---
|
|
|
|
<div align="center">
|
|
|
|
### 🙋♀️ Questions? Issues? Ideas?
|
|
|
|
**Found a bug?** [Open an issue](https://github.com/your-repo/issues/new/choose)
|
|
**Have a feature request?** [Start a discussion](https://github.com/your-repo/discussions)
|
|
**Want to contribute?** Check out our [contribution guide](#-contributing)
|
|
|
|
---
|
|
|
|
**Built with ❤️ for the video processing community**
|
|
|
|
*Making professional video encoding accessible to everyone*
|
|
|
|
</div> |