Skip to content

Repository files navigation

SousVid

Docker Image Version (latest semver) License: MIT

Turn cooking videos from Instagram Reels, TikTok, and YouTube Shorts into structured written recipes by pasting a link.

Runs entirely on your homelab as a lightweight stack alongside your self-hosted Mealie instance.


How It Works

flowchart TD
    A(["User pastes video URL"])
    B["yt-dlp\ndownload video\n + \nextract caption"]
    C{"Caption looks\nlike a recipe?"}
    D["ffmpeg: extract frames\n Whisper: transcribe audio"]
    E["Caption used directly\n Whisper skipped"]
    F["OpenRouter LLM\nextract recipe\n + \nselect dish photo frame"]
    G["Crop & optimize photo\n(crop to square)"]
    H{"Push to\nMealie?"}
    I["POST to Mealie\n& upload recipe photo"]
    J(["Return to UI\nJSON + Markdown + Photo + Mealie link"])

    A --> B
    B --> C
    C -->|"No -- transcribe"| D
    C -->|"Yes -- skip Whisper"| E
    D --> F
    E --> F
    F --> G
    G --> H
    H -->|"Enabled"| I --> J
    H -->|"Disabled"| J

    style E fill:#1a3a1a,stroke:#34d399,color:#34d399
    style I fill:#1a2a3a,stroke:#6c63ff,color:#a78bfa
Loading
  1. Paste: Submit an Instagram Reel, TikTok, or YouTube Shorts URL.
  2. Process: The system downloads the video, transcribes spoken instructions, and extracts visual frames.
  3. Generate: A multimodal LLM structures the recipe and identifies the best plated shot.
  4. Deliver: Export the recipe as Clean Markdown/JSON, or automatically push it directly into Mealie.

Tip

Smart Shortcut: If the creator already pasted the full recipe in the video caption, the pipeline automatically detects it, skips the local transcription (Whisper) phase to save time/CPU resources, and feeds the caption directly to the LLM.


Technology Stack

Component Technology Description
API & Orchestration Python 3.12 (FastAPI) Handles endpoints, job status polling, and auth.
Asynchronous Queue Celery + Redis Manages background extraction jobs concurrently.
Video Downloader yt-dlp Downloads video streams and metadata.
Frame Extractor ffmpeg Extracts visual frames for multimodal analysis.
Transcriber faster-whisper Transcribes audio speech locally on CPU (no API cost).
Recipe Extractor OpenRouter Multi-modal LLM API (supports Gemini, Claude, GPT, etc.).
Recipe Target Mealie Optional self-hosted recipe manager integration.
Frontend Vanilla HTML5 / CSS3 / JS Clean responsive UI with Lucide Icons.

System Architecture

flowchart LR
    subgraph Browser["Browser"]
        UI["index.html"]
    end

    subgraph Docker["Docker Container Space"]
        subgraph FastAPIApp["sousvid container"]
            Main["main.py\nFastAPI"]
            Config["config.py\nSettings"]
        end
        
        subgraph Queue["redis container"]
            Redis[("Redis\nBroker & Backend")]
        end

        subgraph Worker["worker container"]
            Celery["worker.py\nCelery Worker"]
            Pipeline["pipeline.py\nOrchestration"]
            DL["downloader.py"]
            FE["frame_extractor.py"]
            TR["transcriber.py"]
            LLM["llm.py"]
            ME["mealie.py"]
        end
    end

    subgraph External["External Services"]
        Platforms[("TikTok / Instagram\n/ YouTube")]
        OR[("OpenRouter API")]
        Mealie[("Mealie\nself-hosted")]
    end

    UI -->|"POST /extract/submit"| Main
    UI <-->|"GET /jobs/{id}"| Main
    Main -->|"enqueue task"| Redis
    Celery -->|"consume / poll"| Redis
    Celery --> Pipeline
    Pipeline --> DL & FE & TR & LLM & ME

    DL <-->|"download"| Platforms
    LLM <-->|"REST"| OR
    ME <-->|"REST"| Mealie
Loading

For more detailed sequence diagrams and worker configuration details, see Job Queue Architecture.


Setup & Deployment

Prerequisites

  • Docker & Docker Compose installed.
  • An OpenRouter API key (Gemini 1.5 Flash costs roughly $0.001 per recipe).
  • A self-hosted Mealie instance (optional — you can download recipes as Markdown/JSON without it).

1. Configure the Environment (.env)

Create a .env file in your deployment directory:

# Required Configuration
OPENROUTER_API_KEY=sk-or-your-api-key-here
OPENROUTER_MODEL=google/gemini-flash-1.5

# Optional — Leave blank to disable automatic Mealie pushes
MEALIE_URL=http://your-mealie-ip:9925
MEALIE_API_TOKEN=your-mealie-api-token-here

# Transcription Settings (Whisper)
WHISPER_MODEL=small        # options: tiny | base | small | medium | large-v3
WHISPER_DEVICE=cpu         # options: cpu | cuda
WHISPER_COMPUTE_TYPE=int8  # options: int8 (CPU) | float16 (GPU)

# Extraction Settings
MAX_FRAMES=6

2. Export Instagram Cookies (Required for Reels)

Instagram blocks unauthenticated video downloads. You must export session cookies from your browser:

  1. Install an extension like Get cookies.txt LOCALLY (Chrome/Edge) or Firefox equivalent.
  2. Log into Instagram in your web browser.
  3. Open the extension, click Export, and save the file.
  4. Create a folder named cookies in your deployment directory and save the file as cookies/cookies.txt.

Note

TikTok and YouTube Shorts links do not require cookies to download.

3. Deploy

Choose one of the two options below to run the stack.

Option A: Pull Pre-built Images from Docker Hub (Recommended)

This is the easiest path for self-hosters. Use the following docker-compose.yml:

services:
  sousvid:
    image: leshicodes/sousvid:v1.0.0
    container_name: sousvid
    restart: unless-stopped
    ports:
      - "8000:8000"
    env_file:
      - .env
    volumes:
      - ./cookies:/app/cookies
      - ./data:/app/data
    depends_on:
      - redis

  worker:
    image: leshicodes/sousvid:v1.0.0
    container_name: sousvid-worker
    command: celery -A app.worker.celery_app worker --loglevel=info
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - whisper-cache:/root/.cache/huggingface
      - ./cookies:/app/cookies
      - ./data:/app/data
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    container_name: sousvid-redis
    restart: unless-stopped
    volumes:
      - redis-data:/data

volumes:
  whisper-cache:
    driver: local
  redis-data:
    driver: local

Run:

docker compose up -d

Option B: Build from Source

If you are developing or want to compile the image locally, clone the repository and run:

docker compose up -d --build

(Uses the local Dockerfile build targets specified in the repository's docker-compose.yml).

Once started, navigate to http://localhost:8000 to access the web interface.


Detailed Environment Reference

Variable Default Description
OPENROUTER_API_KEY (Required) Your OpenRouter API Key.
OPENROUTER_MODEL google/gemini-flash-1.5 Model used for recipe processing (Gemini Flash recommended for cost/speed).
DB_PATH /app/data/sousvid.db Local path inside container for user, service, and history database.
WHISPER_MODEL small Size of local model. Larger models are more accurate but consume more RAM.
WHISPER_DEVICE cpu Execution hardware: cpu or cuda.
WHISPER_COMPUTE_TYPE int8 Model precision (int8 for CPU, float16 for GPU).
MAX_FRAMES 6 Maximum number of keyframes extracted and sent to LLM.
COOKIES_FILE /app/cookies/cookies.txt Path inside container where Instagram cookies are mapped.
REDIS_URL redis://redis:6379/0 Celery broker URL.
JWT_SECRET (Auto-generated) Key used to sign user auth tokens. Auto-generated on first run.
JWT_EXPIRE_HOURS 168 Expiration duration for user sessions (7 days).
ALLOW_REGISTRATION true Set to false to disable new registrations (still allows the first user to bootstrap as admin).

Whisper Model Guide

Model Size RAM Usage Speed Accuracy
tiny ~1 GB Fastest Low
base ~1.5 GB Fast OK
small ~2.5 GB Good Recommended (Default)
medium ~5 GB Slower Great
large-v3 ~10 GB Slow (needs GPU) Best

Cost Estimates

Component Cost Notes
yt-dlp, ffmpeg, Whisper Free Runs entirely on your local machine.
OpenRouter (Gemini Flash) ~$0.001 / recipe Recommended default.
OpenRouter (Claude Sonnet) ~$0.02 / recipe High accuracy, higher price.

Development

See CONTRIBUTING.md for development setup, testing, and contribution instructions. Changes are tracked in CHANGELOG.md.

pip install -r requirements-dev.txt
pytest tests/ -v
ruff check app/ tests/

Roadmap

See ROADMAP.md for planned features and ideas under consideration.

About

Convert Instagram Reels, TikTok, and YouTube Shorts cooking videos into structured written recipes with one click

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages