Local-first image and video archive search with SQLite, FAISS, FastAPI, and Typer.
Project description
Media Indexer
A local-first image and video search tool for your own folders.
Point it at a folder of media, let it build a local index, then search your archive in plain English from a localhost web UI.
Examples:
dragon
warm editorial portrait
sunset over water
video with a person walking on a beach
No cloud upload. No external APIs. Your media stays on your machine.
What It Does
- Indexes local image and video folders recursively.
- Supports
.jpg,.jpeg,.png,.mp4,.mov,.m4v,.avi,.mkv, and.webm. - Creates local thumbnails for fast browsing.
- Generates local CLIP embeddings for text search and similarity search.
- Adds simple local auto-labels like content type, style tags, and object tags.
- Uses sparse frame selection for videos so search stays useful without indexing every frame.
- Lets you search from a browser at
http://127.0.0.1:8000. - Lets you upload an image to find visually similar media.
- Skips unchanged files when you index the same folder again.
How To Use
Install locally from source:
git clone https://github.com/sachin1705s/media-indexer.git
cd media-indexer
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -e ".[dev]"
Video indexing requires:
brew install ffmpeg
Run the guided workflow:
media-indexer run
Or run directly from source without an editable install:
PYTHONPATH=backend python -m image_archive.cli run
When the server starts, open:
http://127.0.0.1:8000
Folder Picker
Inside the terminal picker:
↑ / ↓ move
Space select or unselect a folder
Enter open folder
→ open folder
← go up
d done, start indexing
q cancel
Other Commands
# Guided setup, folder selection, indexing, and optional server start
media-indexer run
# Index one folder directly
media-indexer index ~/Pictures
# Start the local web app for already-indexed media
media-indexer serve
# Show archive status
media-indexer status
# Recheck configured folders and index only changed or missing files
media-indexer reindex
# Delete local index data, thumbnails, vectors, and cached video frames
# This does not delete your original files.
media-indexer reset
What Gets Stored
For each indexed asset, the app stores local metadata such as:
- file path
- source path for video-backed frame hits
- file hash or stable video-frame signature
- width and height
- created and modified timestamps when available
- thumbnail path
- local search embedding
- local labels and tags
- matched timestamp for video frame assets
The original media files are not modified.
By default, app data is stored in your user app-data folder:
macOS: ~/Library/Application Support/media-indexer/
Linux: ~/.local/share/media-indexer/
Windows: %LOCALAPPDATA%/media-indexer/
Why Local-First?
This tool is meant for personal and creative archives where privacy matters.
- Your media is indexed locally.
- Search runs locally.
- The web UI is served from localhost.
- No account is required.
- No cloud media upload is required.
The first run may download local model weights, then reuse them from your machine afterward.
Current Limitations
- Video search works through sparse representative frames, not full clip understanding.
- Very large archives may still need future optimization work.
- CLIP labels are useful but not as detailed as a large vision-language model.
- Deleted files are not fully cleaned up automatically yet.
Development
Run tests:
PYTHONPATH=backend python -m pytest -q
Run the app from source:
PYTHONPATH=backend python -m image_archive.cli run
Project Structure
backend/image_archive/ Python package, CLI, API, indexing, search
backend/image_archive/frontend/
Packaged localhost web UI
frontend/ Source copy of the minimal UI
tests/ Test suite
config.example.yaml Example config
pyproject.toml Python package metadata
Building
Build distributions locally:
python -m pip install --upgrade build twine
rm -rf dist build *.egg-info backend/*.egg-info
python -m build
python -m twine check dist/*.whl dist/*.tar.gz
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file media_indexer-0.2.0.tar.gz.
File metadata
- Download URL: media_indexer-0.2.0.tar.gz
- Upload date:
- Size: 48.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb242a6bc4bd606b623e5eedda591c388bab9e2d00ef856e364d8f4ab6008c28
|
|
| MD5 |
ccdaff968a4f3cbe637cace2e27794d4
|
|
| BLAKE2b-256 |
8d7b73072bd49a94679bf7cafb14ab210f57c272d0bf6f8ea727b8e106f33938
|
File details
Details for the file media_indexer-0.2.0-py3-none-any.whl.
File metadata
- Download URL: media_indexer-0.2.0-py3-none-any.whl
- Upload date:
- Size: 50.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ea300292a1ef0961d025772f96a8b2103879a073be7aacd6884daeb00070fb4
|
|
| MD5 |
264fa465bd80a35fada81a2cafc19424
|
|
| BLAKE2b-256 |
de1f682eadb34e7d25e1b9377cf4d2b21f6721a89ad1d0ae8e27788ce0182fdf
|