---
name: lucky-director
description: >-
  LuckyDirector — монтажный конвейер Valentin на Mac (Desktop). Python + ffmpeg.
  Input/ → brief.md → python3 video_factory.py или edit_montage_v4.py → Output/
  Для простой склейки: скрипт в ~/Desktop/LuckyDirector/video_factory.py
  Для fade переходов: edit_montage_v4.py (подправив EDL)
  Для произвольной сборки: написать свой скрипт по шаблону edit_montage_v4.
  Также есть папка "~/Desktop/видео путешествие /" с travel-клипами (чистить дубли).
category: media
activation: >-
  Activate when user mentions LuckyDirector, монтаж, склейка видео, или просит
  смонтировать видео на его Mac. Также при упоминании "видео путешествие".
---

# LuckyDirector — Видеомонтажный конвейер

## Расположение

**Основная папка:**
```
~/Desktop/LuckyDirector/
├── Input/          # Исходные видео (mp4)
├── Output/         # Готовые ролики
├── Work/           # Временные файлы (segments, concat)
├── Music/          # MP3 для фоновой музыки
├── Input/brief.md  # Задание для video_factory.py
├── video_factory.py      # Простая склейка (-c copy, без переходов)
├── edit_montage.py       # Ранние версии
├── edit_montage_v2.py
├── edit_montage_v3.py
├── edit_montage_v4.py    # ✅ Склейка с fade на каждом клипе + global fade
├── edit_family.py
├── fix_content_factory.py
└── README.txt            # Инструкция
```

**Папка с travel-клипами:**
```
~/Desktop/видео путешествие /   # (с пробелом в конце!)
```

## 🔴 ВАЖНО: используй существующие скрипты, НЕ пиши свои

В LuckyDirector уже есть все нужные скрипты. **Не пиши новые** — используй готовые.
Пользователь ожидает, что ты будешь работать через `video_factory.py` (с `brief.md`)
или адаптировать `edit_montage_v4.py`.

## 🔴 КРИТИЧЕСКОЕ ПРАВИЛО: НЕ ПИШИ НОВЫЕ СКРИПТЫ

В LuckyDirector **уже есть все скрипты**. Не создавай `quick_edit.py`, `render.py`, `finish.py` и т.д.
Пользователь просит работать **по README** — используй только существующие скрипты:
- `video_factory.py` + `brief.md` — для простой склейки
- `edit_montage_v4.py` — если нужны fade-переходы (подправить EDL)

Если что-то не хватает — адаптируй существующий скрипт, а не пиши новый с нуля.

## Быстрый старт (самый простой — без переходов)

```bash
cd ~/Desktop/LuckyDirector

# 1. Положить видео в Input/ (убрать дубли!)
# 2. Создать brief.md (см. README или шаблон)
# 3. Запустить:
python3 video_factory.py
```

`video_factory.py` делает concat без перекодировки (`-c copy`) — быстро, надёжно, но **без переходов**.

## Склейка с fade-переходами (edit_montage_v4 подход)

Этот подход **проверен и работает** — файлы открываются на любом плеере.
В отличие от `xfade` (см. питфоллы).

### Шаг 1. Рендер каждого клипа с fade in/out

```python
ffmpeg -y -i clip.mp4 \
  -vf "fade=t=in:st=0:d=0.3,fade=t=out:st={dur-0.3}:d=0.3" \
  -af "afade=t=in:st=0:d=0.3,afade=t=out:st={dur-0.3}:d=0.3" \
  -c:v libx264 -preset fast -crf 22 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  -movflags +faststart seg_N.mp4
```

### Шаг 2. Concat через `concat` filter (с перекодировкой)

```python
ffmpeg -i seg_0.mp4 -i seg_1.mp4 -filter_complex \
  "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" \
  -map "[outv]" -map "[outa]" \
  -c:v libx264 -preset fast -crf 20 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  -movflags +faststart _concat.mp4
```

### Шаг 3. Global fade in/out

```python
# dur — длительность concat видео
fi, fo = min(0.5, dur/4), min(1.0, dur/4)
start_out = max(0, dur - fo)  # защита от отрицательного старта
ffmpeg -y -i _concat.mp4 \
  -vf "fade=t=in:st=0:d={fi},fade=t=out:st={start_out}:d={fo}" \
  -af "afade=t=in:st=0:d={fi},afade=t=out:st={start_out}:d={fo}" \
  -c:v libx264 -preset fast -crf 20 \
  -c:a aac -b:a 128k \
  -pix_fmt yuv420p \
  -movflags +faststart Output/montage_final.mp4
```

## ffmpeg на этой Mac

- **Путь**: `~/.local/bin/ffmpeg` (сборка tessus v7.1)
- **В PATH** — можно вызывать как `ffmpeg`
- **Нет ffprobe!** — получай длительность через парсинг stderr:

```python
def get_dur(path):
    r = subprocess.run(['ffmpeg', '-i', str(path)],
                       capture_output=True, text=True, timeout=30)
    m = re.search(r'Duration: (\d+):(\d+):(\d+\.\d+)', r.stderr)
    if m:
        return int(m.group(1))*3600 + int(m.group(2))*60 + float(m.group(3))
    return 0
```

### Доступные фильтры ffmpeg

| Фильтр | Статус | Назначение |
|--------|--------|------------|
| `fade`, `afade` | ✅ | Fade in/out |
| `concat` (фильтр) | ✅ | Склейка с перекодировкой |
| `xfade` | ✅ | Crossfade видео |
| `acrossfade` | ✅ | Crossfade аудио |
| `crossdae` | ❌ | НЕ доступен (не собран) |
| `drawtext` | ✅ | Текст на видео |
| `zoompan` | ✅ | Ken Burns эффект |

## ⚠️ Питфоллы (из реального опыта)

### 1. xfade делает файлы, которые не открываются локально
Файлы, склеенные через `xfade` + `acrossfade`, могут **не открываться на Mac** 
(QuickTime, IINA и др.), но **YouTube их принимает** (проверено на практике).
→ Если нужно открывать локально — используй fade на каждом клипе + concat (как в edit_montage_v4).
→ Если файл нужен только для YouTube — xfade подойдёт, но плеер его не откроет.

### 2. Duration погрешность для fade out
`st={dur-fo}` может дать стопор, если dur чуть меньше расчётной.
Всегда используй: `start_out = max(0, dur - fo)`

### 3. brief.md — обязателен для video_factory.py
Без него скрипт создаёт шаблон и ждёт заполнения.

### 4. Глобальный fade — отдельным проходом
Не пытайся совместить concat + fade в одном фильтре — проще и надёжнее два прохода.

### 5. Прерывания скриптов
Если скрипт прервался (Ctrl+C, таймаут) — удали `_concat*.mp4` в Work/
перед перезапуском, иначе будет использоваться частичный файл.

## Очистка дублей (папка «видео путешествие»)

В папке `~/Desktop/видео путешествие /` много дублей вида:
```
document_XXXX 21.05.34.mp4  (с таймстемпом)
document_XXXX.mp4           (оригинал)
```

**Алгоритм очистки:**
1. Группировать файлы по base_id (первая часть до пробела)
2. В каждой группе определить "чистые" (без таймстемпов и скобок)
3. Оставить один чистый, остальное в корзину (~/.Trash/)

**ВАЖНО — БАГ наивного определения:**
Не используй проверку `"23." in filename` — она ложно срабатывает на
файлах где ID заканчивается на `23` (например `...4123.mp4` содержит "23.").
Используй проверку через таймстемп-паттерн: `r'\d{2}\.\d{2}\.\d{2}'` 
(ищет именно формат "21.05.34") или проверку с пробелом перед датой.

**Пример рабочего кода:**
```python
import re
# ✅ Правильная проверка на таймстемп-дубль:
has_timestamp = bool(re.search(r' \d{2}\.\d{2}\.\d{2}\.mp4$', f.name))
# или проще — проверяй на наличие пробела перед числом:
has_timestamp = ' 21.' in f.name or ' 22.' in f.name  # пробел перед числом!

# ❌ НЕПРАВИЛЬНО — ложно срабатывает на ID, оканчивающихся на 23-31:
# has_timestamp = '23.' in f.name  # BUG! matches "...4123.mp4"
```

## GitHub инструменты для автомонтажа (исследовано 31.05.2026)

Если пользователь спрашивает про софт для авто-монтажа:

| Проект | ⭐ | Суть |
|--------|---|------|
| **auto-editor** (WyattBlue) | 4.4k | Nim CLI/GUI. Анализирует громкость, вырезает тишину. Самое популярное. |
| **videologkit** (hjjbh1314) | 3 | **Mac-only!** AI-режиссёр на Qwen3-VL: кидаешь папку → LLM пишет сценарий → монтирует под бит → TikTok-ready. ¥0.1/ролик. |
| **autovio** (Auto-Vio) | 18 | AI pipeline текст→сценарий→изображения→клипы→MP4. MCP-ready. |
| **ffmpeg-automated-editor** | 33 | Python. Берёт видео, делает короткие клипы. |
| **stockpile** (sasoder) | 22 | AI b-roll finder на n8n. |

Рекомендация: `auto-editor` для обрезки тишины, `videologkit` — присмотреться (сырой, но концепт под Кэпа).

## Telegram / отправка результата

Готовый файл в Output/ отправляй через MEDIA:
```
MEDIA:/Users/valen/Desktop/LuckyDirector/Output/montage_final.mp4
```
