# movmaker

Flat-folder Python + ffmpeg movie maker, plus optional MVLog worker.

## What it does

- Input: one directory with mixed images/videos/audio + optional `data.txt`
- Output: one rendered MP4 with transitions, captions, intro/logo, stamps, and embedded metadata
- Optional worker (`mvlog_worker.py`) renders/publishes MVLog jobs either locally on the webserver or via the older SSH/SCP remote mode

## Requirements

- Python 3
- `ffmpeg`, `ffprobe`

Install (Debian/Ubuntu):

```bash
sudo apt install ffmpeg
```

## Basic usage

```bash
python3 movmaker.py /path/to/input
```

Preview render:

```bash
python3 movmaker.py /path/to/input --preview
```

Custom output dir:

```bash
python3 movmaker.py /path/to/input --out-dir /path/to/output
```

## Input model (flat folder)

Supported media:

- Images: `.jpg .jpeg .png .webp .bmp .tif .tiff`
- Videos: `.mp4 .mov .mkv .avi .webm .m4v`
- Audio: `.mp3 .wav .m4a .aac .flac .ogg`
- Data file: `data.txt` (also accepts `info.txt`, `title.txt`)

No required subfolders.

## Ordering

If `order.json` exists in the input folder, it is used first for visual media order.
Then fallback order is handled by movmaker logic (metadata/filename/file-time based sorting path).

`order.json` should contain only visual files (images/videos).

## `data.txt` format

Use `key: value` lines.

General keys used by movmaker:

- `Title` / `Name`
- `Teaser`
- `Quote_da`
- `Location` / `Place` / `Where`
- `Date` / `Dates` / `When`
- `Description` / `Desc` / `Synopsis`

Per-file captions:

```text
IMG_0001.jpg: caption text
clip01.mp4: caption text
```

Per-video source audio toggle (optional):

```text
clip01.mp4 audio: yes
```

## Current render behavior (important)

- Default still duration: 6s
- Default crossfade: 3s
- First still is extended (`FIRST_IMAGE_DURATION_MULTIPLIER`)
- Intro/logo mode supported (`--intro-logo`)
- Teaser is metadata-only (not burned into intro text)
- `quote_da` and `teaser` are embedded in output metadata
- Long video caption rule:
  - if clip duration > 10s, caption starts at +2s and shows for 6s
- Output filename is normalized/safe ASCII (`YYYYMMDD_slug.mp4`)
- Detailed ffmpeg logs are written under `<input>/.logs/`

## MVLog worker (`mvlog_worker.py`)

Worker is for MVLog web integration. Preferred deployment is webserver-local: `/var/www/html/in-dir` -> render on the webserver -> `/var/www/html/out-dir`. Older SSH/SCP remote mode is still available for rollback/manual use.

Key points:

- Uses per-job state `.movmaker-state.json`
- Honors job toggles (`.movmaker-enabled`, `.movmaker-preview`, `.mvlog-hidden`)
- Includes article IDs from `.mvlog-id` in state
- Ignores `.mvlog-id` and `.mvlog-hide-map` in fingerprinting
- Publishes output atomically and clears remote cache file
- Supports remote mode (SSH/SCP) and `--local` mode

Run once on the webserver:

```bash
./mvlog_worker.py --local --remote-root /var/www/html --work-dir /srv/mvlog/work
```

Single job on the webserver:

```bash
./mvlog_worker.py --local --remote-root /var/www/html --work-dir /srv/mvlog/work --job 20260525_mohnesee
```

Older SSH/SCP remote mode from another machine:

```bash
./mvlog_worker.py
```

Force rerender:

```bash
./mvlog_worker.py --job 20260525_mohnesee --force
```

Pass extra movmaker args:

```bash
./mvlog_worker.py --movmaker-arg=--preview
```

## Webserver deployment

Recommended deployment keeps this repo checked out on the webserver at:

```text
/srv/mvlog/app
```

The worker writes temporary render data outside git at `/srv/mvlog/work` and publishes public files to `/var/www/html/out-dir`.

Systemd templates are in `deploy/systemd/`:

```bash
sudo cp deploy/systemd/mvlog-worker.service /etc/systemd/system/
sudo cp deploy/systemd/mvlog-worker.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now mvlog-worker.timer
```

## Notes

- This repo does **not** send web push itself; push is handled by MVLog web app server-side.
- Keep secrets out of git (API keys, push keys, auth files).