Observed since 20 Oct, 19:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Professional video processing pipeline with computer vision analysis, 360° processing, adaptive streaming, and AI-powered transcription (msprites2)
A Modern Python Library for Professional Video Processing
Extracted from the demostar Django application, now a standalone powerhouse for video encoding, thumbnail generation, and sprite creation.
🔭 Computer Vision Analysis • 🎥 AV1/HEVC/HDR • 📡 Adaptive Streaming • 🌐 360° Video Processing • ✅ Production Ready
📚 Full Documentation • 🚀 Features • ⚡ Quick Start • 💻 Examples • 🔄 Upgrade
docs/| Documentation | Description |
|---|---|
| 📖 User Guide | Complete getting started guides and feature overviews |
| 🔄 Migration | Upgrade instructions and migration guides |
| 🛠️ Development | Technical implementation details and architecture |
| 📋 Reference | API references, roadmaps, and feature lists |
| 💻 Examples | 11 comprehensive examples covering all features |
🎥 Video Encoding
|
🖼️ Thumbnails & Sprites
|
⚡ Background Processing
|
🛠️ Modern Development
|
🌐 360° Video Support (Optional)
| |
# 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]"
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)# 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
This library supports both Procrastinate 2.x and 3.x for smooth migration:
from video_processor.tasks.compat import get_version_info, IS_PROCRASTINATE_3_PLUS
version_info = get_version_info()
print(f"Using Procrastinate {version_info['procrastinate_version']}")
print(f"Features available: {list(version_info['features'].keys())}")
# Version-aware setup
if IS_PROCRASTINATE_3_PLUS:
# Use 3.x features like improved performance, graceful shutdown
pass
Install compatible version:
uv add "procrastinate>=3.5.2,<4.0.0" # Or keep 2.x support: ">=2.15.1,<4.0.0"
Apply database migrations:
# Procrastinate 3.x (two-step process)
procrastinate schema --apply --mode=pre # Before deploying
# Deploy new code
procrastinate schema --apply --mode=post # After deploying
# Procrastinate 2.x (single step)
procrastinate schema --apply
Use migration helper:
from video_processor.tasks.migration import migrate_database
# Automatic version-aware migration
success = await migrate_database("postgresql://localhost/mydb")
Update worker configuration:
from video_processor.tasks import get_worker_kwargs
# Automatically normalizes options for your version
worker_options = get_worker_kwargs(
concurrency=4,
timeout=5, # Maps to fetch_job_polling_interval in 3.x
remove_error=True, # Maps to remove_failed in 3.x
)
shutdown_graceful_timeoutgit 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
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}")
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())
| 🎯 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 |
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
)
Video Processor now includes a world-class testing framework with 108+ video fixtures and perfect test compatibility!
# Run all tests
make test
# Unit tests only (fast)
uv run pytest tests/unit/
# Integration tests with Docker
make test-docker
# Test specific categories
uv run pytest -m "smoke" # Quick smoke tests
uv run pytest -m "edge_cases" # Edge case scenarios
uv run pytest -m "codecs" # Codec compatibility
Our comprehensive test suite includes:
✅ 52 passing tests (0 failures!)
✅ 108+ test video fixtures
✅ Complete Docker integration
✅ Perfect API compatibility
# Complete integration testing environment
make test-docker
# Test specific services
make test-db-migration # Database migration testing
make test-worker # Procrastinate worker testing
make clean-docker # Clean up test environment
# Generate/update test video fixtures
uv run python tests/fixtures/test_suite_manager.py --setup
# Validate test suite integrity
uv run python tests/fixtures/test_suite_manager.py --validate
# Generate synthetic videos for edge cases
uv run python tests/fixtures/generate_synthetic_videos.py
# Download open source test videos
uv run python tests/fixtures/download_test_videos.py
| Category | Description | Video Count |
|---|---|---|
| smoke | Quick validation tests | 2 videos |
| basic | Standard functionality | 5 videos |
| codecs | Format compatibility | 9 videos |
| edge_cases | Boundary conditions | 12+ videos |
| stress | Performance testing | 2+ videos |
| full | Complete test suite | 108+ videos |
Explore our comprehensive examples in the examples/ directory:
| Example | Description | Features |
|---|---|---|
basic_usage.py | 🎯 Simple synchronous processing | Configuration, encoding, thumbnails |
async_processing.py | ⚡ Background task processing | Procrastinate, job queuing, monitoring |
custom_config.py | 🛠️ Advanced configuration scenarios | Quality presets, validation, custom paths |
docker_demo.py | 🐳 Complete containerized demo | Docker, PostgreSQL, async workers |
web_demo.py | 🌐 Flask web interface | Browser-based processing, job submission |
Get up and running in seconds with our complete Docker environment:
# Start all services (PostgreSQL, Redis, app, workers)
docker-compose up -d
# View logs from the demo application
docker-compose logs -f app
# Access web demo at http://localhost:8080
docker-compose up demo
# Run tests in Docker
docker-compose run test
# Clean up
docker-compose down -v
Services included:
# 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...
# 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
)
The main orchestrator for all video processing operations.
# 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]
Type-safe configuration with automatic validation.
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
Comprehensive result object with all output information.
@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
# 📦 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/
Our comprehensive test suite covers:
========================== test session starts ==========================
tests/test_config.py ✅✅✅✅✅ [15%]
tests/test_utils.py ✅✅✅✅✅✅✅✅ [30%]
tests/test_procrastinate_compat.py ✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ [85%]
tests/test_procrastinate_migration.py ✅✅✅✅✅✅✅✅✅✅✅✅✅ [100%]
======================== 43 passed in 0.52s ========================
| 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 |
| 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 |
| Feature | Video Processor | FFmpeg CLI | moviepy | OpenCV |
|---|---|---|---|---|
| Two-pass encoding | ✅ | ✅ | ❌ | ❌ |
| Multiple formats | ✅ | ✅ | ✅ | ❌ |
| Background processing | ✅ | ❌ | ❌ | ❌ |
| Type safety | ✅ | ❌ | ❌ | ❌ |
| Sprite generation | ✅ | ❌ | ❌ | ❌ |
| Modern Python | ✅ | N/A | ❌ | ❌ |
# Ubuntu/Debian
sudo apt install ffmpeg postgresql-client
# macOS
brew install ffmpeg postgresql
# Arch Linux
sudo pacman -S ffmpeg postgresql
We welcome contributions! Here's how to get started:
git checkout -b feature/amazing-feature)uv run pytest)uv run ruff format .)This project is licensed under the MIT License - see the LICENSE file for details.
Video Processor v0.4.0 maintains 100% backward compatibility while adding powerful new features:
# Your existing code continues to work unchanged
processor = VideoProcessor(config)
result = await processor.process_video("video.mp4", "./output/")
# But now you get additional features automatically:
if result.is_360_video:
print(f"360° projection: {result.video_360.projection_type}")
if result.quality_analysis:
print(f"Quality score: {result.quality_analysis.overall_quality:.1f}/10")
Found a bug? Open an issue
Have a feature request? Start a discussion
Want to contribute? Check out our contribution guide
Built with ❤️ for the video processing community
Making professional video encoding accessible to everyone
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.6.0 | 2 Oct 2025 | 25 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 19:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:b02986054e4e4bbd1468164285139358dc4875982e699dc6c700a09ced1638f4