Metadata-Version: 2.4
Name: immich-memories
Version: 0.28.1
Summary: Turn your Immich photo library into video memory compilations with music and smart cuts
Project-URL: Homepage, https://github.com/sam-dumont/immich-video-memory-generator
Project-URL: Documentation, https://sam-dumont.github.io/immich-video-memory-generator/
Project-URL: Repository, https://github.com/sam-dumont/immich-video-memory-generator
Project-URL: Issues, https://github.com/sam-dumont/immich-video-memory-generator/issues
Project-URL: Changelog, https://github.com/sam-dumont/immich-video-memory-generator/releases
Author: Immich Memories Contributors
License-Expression: MIT
License-File: LICENSE
Keywords: compilation,immich,memories,photo-management,video
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Multimedia :: Video :: Conversion
Requires-Python: >=3.11
Requires-Dist: apprise>=1.9
Requires-Dist: click>=8.1
Requires-Dist: croniter>=1.3
Requires-Dist: geopy>=2.4
Requires-Dist: httpx>=0.27
Requires-Dist: imagehash>=4.3
Requires-Dist: moviepy>=1.0.3
Requires-Dist: nicegui>=3.9.0
Requires-Dist: numpy>=1.24
Requires-Dist: opencv-python>=4.9
Requires-Dist: pillow-heif>=1.0
Requires-Dist: pillow>=12.1.1
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0
Requires-Dist: scenedetect[opencv]>=0.6
Requires-Dist: staticmap>=0.5
Requires-Dist: videohash>=3.0
Requires-Dist: watchdog>=3.0
Provides-Extra: all
Requires-Dist: demucs>=4.0; extra == 'all'
Requires-Dist: dlib>=19.24; extra == 'all'
Requires-Dist: face-recognition>=1.3; extra == 'all'
Requires-Dist: freetype-py>=2.4; extra == 'all'
Requires-Dist: mutagen>=1.47; extra == 'all'
Requires-Dist: panns-inference>=0.1; extra == 'all'
Requires-Dist: taichi>=1.7.0; extra == 'all'
Requires-Dist: torch>=2.0; extra == 'all'
Provides-Extra: all-mac
Requires-Dist: demucs>=4.0; extra == 'all-mac'
Requires-Dist: dlib>=19.24; extra == 'all-mac'
Requires-Dist: face-recognition>=1.3; extra == 'all-mac'
Requires-Dist: freetype-py>=2.4; extra == 'all-mac'
Requires-Dist: mutagen>=1.47; extra == 'all-mac'
Requires-Dist: panns-inference>=0.1; extra == 'all-mac'
Requires-Dist: pyobjc-core>=9.0; (sys_platform == 'darwin') and extra == 'all-mac'
Requires-Dist: pyobjc-framework-metal>=9.0; (sys_platform == 'darwin') and extra == 'all-mac'
Requires-Dist: pyobjc-framework-quartz>=9.0; (sys_platform == 'darwin') and extra == 'all-mac'
Requires-Dist: pyobjc-framework-vision>=9.0; (sys_platform == 'darwin') and extra == 'all-mac'
Requires-Dist: taichi>=1.7.0; extra == 'all-mac'
Requires-Dist: torch>=2.0; extra == 'all-mac'
Provides-Extra: audio
Requires-Dist: mutagen>=1.47; extra == 'audio'
Provides-Extra: audio-ml
Requires-Dist: panns-inference>=0.1; extra == 'audio-ml'
Requires-Dist: torch>=2.0; extra == 'audio-ml'
Provides-Extra: auth
Requires-Dist: authlib>=1.3; extra == 'auth'
Provides-Extra: demucs
Requires-Dist: demucs>=4.0; extra == 'demucs'
Provides-Extra: dev
Requires-Dist: commitizen>=3.0; extra == 'dev'
Requires-Dist: deptry>=0.20; extra == 'dev'
Requires-Dist: diff-cover>=9.0; extra == 'dev'
Requires-Dist: grimp>=3.0; extra == 'dev'
Requires-Dist: import-linter>=2.0; extra == 'dev'
Requires-Dist: mutmut>=2.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: oidc-provider-mock>=0.3; extra == 'dev'
Requires-Dist: pre-commit>=3.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-benchmark>=5.2.3; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest-playwright>=0.5; extra == 'dev'
Requires-Dist: pytest-xdist>=3.5; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: python-semantic-release>=9.0; extra == 'dev'
Requires-Dist: refurb>=2.0; extra == 'dev'
Requires-Dist: ruff>=0.1; extra == 'dev'
Requires-Dist: types-croniter>=6.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
Provides-Extra: face
Requires-Dist: dlib>=19.24; extra == 'face'
Requires-Dist: face-recognition>=1.3; extra == 'face'
Provides-Extra: gpu
Requires-Dist: freetype-py>=2.4; extra == 'gpu'
Requires-Dist: taichi>=1.7.0; extra == 'gpu'
Provides-Extra: mac
Requires-Dist: pyobjc-core>=9.0; (sys_platform == 'darwin') and extra == 'mac'
Requires-Dist: pyobjc-framework-metal>=9.0; (sys_platform == 'darwin') and extra == 'mac'
Requires-Dist: pyobjc-framework-quartz>=9.0; (sys_platform == 'darwin') and extra == 'mac'
Requires-Dist: pyobjc-framework-vision>=9.0; (sys_platform == 'darwin') and extra == 'mac'
Description-Content-Type: text/markdown

# Immich Memories

[![CI](https://github.com/sam-dumont/immich-video-memory-generator/actions/workflows/ci.yml/badge.svg)](https://github.com/sam-dumont/immich-video-memory-generator/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/sam-dumont/immich-video-memory-generator/graph/badge.svg)](https://codecov.io/gh/sam-dumont/immich-video-memory-generator)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/sam-dumont/immich-video-memory-generator/badge)](https://scorecard.dev/viewer/?uri=github.com/sam-dumont/immich-video-memory-generator)
[![Release](https://github.com/sam-dumont/immich-video-memory-generator/actions/workflows/release.yml/badge.svg)](https://github.com/sam-dumont/immich-video-memory-generator/actions/workflows/release.yml)
[![Python](https://img.shields.io/pypi/pyversions/immich-memories)](https://pypi.org/project/immich-memories/)
[![License](https://img.shields.io/github/license/sam-dumont/immich-video-memory-generator)](LICENSE)
[![Docs](https://img.shields.io/badge/docs-Docusaurus-blue)](https://sam-dumont.github.io/immich-video-memory-generator/)

**Create beautiful yearly video compilations from your [Immich](https://immich.app/) photo library.**

Immich Memories connects to your self-hosted Immich server, intelligently selects the best moments from your videos, and compiles them into shareable memory videos — perfect for year-end recaps or celebrating specific people in your life.

> **Full documentation**: [sam-dumont.github.io/immich-video-memory-generator](https://sam-dumont.github.io/immich-video-memory-generator/)

### Reference Setup

```mermaid
graph LR
    subgraph "Apple M2 Pro – 16GB RAM"
        IM["Immich Memories<br/>Python + FFmpeg"]
        LLM["omlx (mlx-vlm)<br/>Qwen2.5-VL local"]
    end

    subgraph "K8s Cluster (GPUs)"
        ACE["ACE-Step 1.5<br/>T1000 8GB"]
        MG["MusicGen API<br/>GTX 1070 8GB"]
    end

    subgraph "Synology NAS"
        Immich["Immich v2.5.6<br/>Photos + Videos"]
    end

    IM -->|"API reads<br/>(download clips)"| Immich
    IM -->|"Vision analysis<br/>(clip scoring)"| LLM
    IM -->|"Background music<br/>(AI-generated)"| ACE
    ACE -.->|"fallback"| MG
    IM -->|"Upload back<br/>(optional)"| Immich
```

*The LLM runs locally on the Mac via [omlx](https://github.com/nicepkg/omlx) (Apple Silicon MLX). Music generation runs on a K8s cluster with dedicated GPUs. Both are optional — the tool works without them, just without AI clip descriptions and generated music.*

---

## Docker (recommended for self-hosters)

```bash
# 1. Download the compose file
curl -O https://raw.githubusercontent.com/sam-dumont/immich-video-memory-generator/main/docker-compose.yml

# 2. Set your Immich connection
export IMMICH_URL="http://your-immich-server:2283"
export IMMICH_API_KEY="your-api-key"

# 3. Start
docker compose up -d

# 4. Open http://localhost:8080
```

### Resource Requirements

| Phase | RAM | CPU | Time estimate |
|-------|-----|-----|---------------|
| Idle (UI) | ~100MB | minimal | — |
| Analyzing clips | 2-4GB | 2+ cores | ~1 min per 10 clips |
| Encoding (1080p) | 4GB | 4 cores | ~2 min for 5 min video |
| Encoding (4K) | 6-8GB | 4+ cores | ~5 min for 5 min video |

Default Docker limits: 4GB RAM, 4 CPUs. This is **not a NAS app** — video analysis and encoding need real compute. Best run on a machine with 8GB+ RAM.

> **Developed and tested on:** Apple M2 Pro, 16GB RAM, macOS. Not yet tested on other hardware. If you run it on Linux/x86, Synology, Unraid, or Raspberry Pi — please [report your experience](https://github.com/sam-dumont/immich-video-memory-generator/issues).

### Supported Immich Versions

Developed and tested against **Immich v2.5.6**. Should work with v1.100+ (uses the `/api/` endpoint prefix), but no guarantees for older versions.

### Optional: LLM for smart clip analysis

For AI-powered content analysis (identifies what's happening in each clip), point to any OpenAI-compatible vision model:

```yaml
# In ~/.immich-memories/config.yaml
advanced:
  llm:
    provider: "openai-compatible"
    base_url: "http://your-llm-server:8080/v1"
    model: "qwen2.5-vl"
```

## Quick Install

```bash
# One-liner (no clone needed)
uvx immich-memories --help

# Or clone and install
git clone https://github.com/sam-dumont/immich-video-memory-generator.git
cd immich-video-memory-generator
uv sync
```

## Quick Start

```bash
# 1. Configure
mkdir -p ~/.immich-memories
cat > ~/.immich-memories/config.yaml << EOF
immich:
  url: "https://photos.example.com"
  api_key: "your-api-key-here"
EOF

# 2. Launch the UI
immich-memories ui
# Opens at http://localhost:8080

# 3. Or use the CLI
immich-memories generate --year 2024 --person "John" --output ~/Videos/john_2024.mp4
```

## Key Features

- **Immich Integration** — Direct REST API connection with face recognition support
- **Smart Clip Selection** — Scene detection, interest scoring, duplicate filtering
- **Face-Aware Cropping** — Keeps faces centered when converting aspect ratios
- **Hardware Acceleration** — NVIDIA NVENC, Apple VideoToolbox, Intel QSV, AMD VAAPI
- **AI Music Generation** — ACE-Step or MusicGen with automatic mood detection
- **Audio Ducking** — Music lowers automatically during speech
- **Web UI + CLI** — 4-step wizard or headless automation
- **Docker & Kubernetes** — Containerized deployment with GPU support

## Documentation

See the [full documentation](https://sam-dumont.github.io/immich-video-memory-generator/) for:

- [Installation](https://sam-dumont.github.io/immich-video-memory-generator/docs/deploy/installation/docker) (Docker, uv/pip, Kubernetes, Terraform)
- [Web UI Walkthrough](https://sam-dumont.github.io/immich-video-memory-generator/docs/create/web-ui/step1-configuration)
- [CLI Reference](https://sam-dumont.github.io/immich-video-memory-generator/docs/reference/cli-reference)
- [Configuration](https://sam-dumont.github.io/immich-video-memory-generator/docs/deploy/configuration/config-file)
- [Hardware Acceleration](https://sam-dumont.github.io/immich-video-memory-generator/docs/deploy/hardware/overview)
- [Audio & Music](https://sam-dumont.github.io/immich-video-memory-generator/docs/create/pipeline/audio-and-music)
- [Recipes](https://sam-dumont.github.io/immich-video-memory-generator/docs/create/recipes/birthday-compilations) (birthday compilations, automation, best practices)

## Development

```bash
make dev      # Install all dependencies
make check    # Run all checks (lint, format, typecheck, tests)
make ci       # Full CI pipeline
make help     # Show all available targets
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## Built with AI

> This entire codebase was written with AI (Claude) as an experiment in building complex
> software cleanly with AI assistance. 1,100+ tests, strict quality gates, the works.
> See [DISCLAIMER.md](DISCLAIMER.md) for the full story.

## License

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

---

**Made with ❤️ for the Immich community**
