Her aday klip transkribe olduktan hemen sonra otomatik olarak video-render kuyruğuna giriyor. Yeni Python worker (video_render.py): - Klibi ffmpeg ile keser - OpenCV + MediaPipe Face Detector (Tasks API — yeni mediapipe sürümlerinde eski solutions API'si kalktı, .tflite model dosyası Docker build'de indiriliyor) ile örneklenmiş karelerde yüz merkezi tespit eder, yumuşatır (moving average); hiç yüz bulunamazsa sabit merkez crop'a düşer, hata saymaz - Kırpılmış kareleri OpenCV'den ffmpeg'e pipe'layıp tek geçişte orijinal sesi map'ler ve transcript_json'dan ürettiği .ass altyazıyı yakar - Sonucu /shared-media/shorts/<candidate_id>.mp4'e yazar Yeni ShortVideo modeli (PENDING/RENDERING/READY/FAILED). Panelde (segments + kanal detay sayfaları) render durumu + READY olunca video önizleme/indirme. VIDEO_RENDER_CONCURRENCY ayrı ve düşük (varsayılan 2) — bu iş diğerlerinden çok daha ağır. Kapsam: sadece tekil konuşmacı şablonu (çoklu konuşmacı/split-screen sonraki bir iterasyona bırakıldı — aktif-konuşmacı tespiti gerektiriyor). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
120 lines
4.7 KiB
Markdown
120 lines
4.7 KiB
Markdown
# StreamClipper AI — Faz 1 + Faz 2 (render)
|
||
|
||
`prd.md` içindeki tam kapsamlı otonom pipeline'ın Faz 1+2'si: ingestion
|
||
(yt-dlp headless capture + 15dk segmentleme), sinyal analizi (ses peak +
|
||
chat velocity), Whisper STT (OpenAI API, kelime zaman damgalı), BullMQ/
|
||
Redis/Postgres altyapısı, auth korumalı bir Next.js panel — ve Faz 2 olarak
|
||
transkribe edilen her aday klibi otomatik yüz-takipli 9:16'ya crop'layıp
|
||
dinamik altyazı basan bir render motoru (`apps/worker/worker/video_render.py`).
|
||
LLM virality skorlama, çoklu-konuşmacı/split-screen şablonu ve
|
||
multi-platform dağıtım hâlâ **yok** — bkz. `prd.md` Modül 3 (skorlama
|
||
kısmı) ve Modül 5.
|
||
|
||
## Klasör Yapısı
|
||
|
||
```
|
||
apps/
|
||
frontend/ Next.js panel (kanal durumu, segment/transkript kütüphanesi)
|
||
api-daemon/ Node/TS — YouTube polling, BullMQ producer, yt-dlp/ffmpeg capture
|
||
worker/ Python — chat-downloader, sinyal analizi, Whisper STT
|
||
packages/
|
||
db/ Prisma schema + client (Node tarafı)
|
||
docker-compose.yml
|
||
```
|
||
|
||
## Ön Koşullar
|
||
|
||
- Node.js 22.13+ (pnpm 11'in gereksinimi), pnpm, Python 3.12+, `ffmpeg`, `yt-dlp` (host'ta çalıştırırken)
|
||
- Docker + Docker Compose (container'larla çalıştırırken)
|
||
- **OpenAI API key** — Whisper STT için
|
||
- **Telegram bot token + chat id** — bildirimler için (`@BotFather`)
|
||
|
||
Canlı yayın tespiti YouTube Data API yerine `yt-dlp`'nin kendisiyle yapılıyor
|
||
(`/channel/<id>/live` kontrolü) — API key veya kota gerekmiyor.
|
||
|
||
## Kurulum
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# .env içindeki OPENAI_API_KEY / TELEGRAM_* değerlerini doldurun
|
||
pnpm install
|
||
```
|
||
|
||
### Yerelde (Docker olmadan)
|
||
|
||
```bash
|
||
# Redis + Postgres'i ayağa kaldır
|
||
docker compose up sc_redis sc_postgres
|
||
|
||
# Şemayı uygula
|
||
pnpm db:migrate
|
||
pnpm db:generate
|
||
|
||
# Test kanalı ekle (gerçek bir YouTube channel_id ile)
|
||
SEED_CHANNEL_ID=UCxxxxxxxx SEED_CHANNEL_NAME="Test Kanal" pnpm db:seed
|
||
|
||
# Servisleri ayrı terminallerde çalıştır
|
||
pnpm dev:daemon
|
||
pnpm dev:frontend
|
||
```
|
||
|
||
Python worker ayrı bir sanal ortamda çalışır (pnpm workspace'in parçası değil):
|
||
|
||
```bash
|
||
cd apps/worker
|
||
python3 -m venv .venv && source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
python -m worker.main
|
||
```
|
||
|
||
### Docker Compose ile (tüm servisler)
|
||
|
||
```bash
|
||
docker compose up --build
|
||
```
|
||
|
||
Panel: http://localhost:3000 · API daemon health: http://localhost:4001/health
|
||
|
||
## Panel Girişi
|
||
|
||
Panelin tüm sayfaları giriş gerektirir (middleware ile korunuyor). İlk açılışta
|
||
henüz hiç kullanıcı yoksa `/login` otomatik olarak "İlk Yönetici Hesabını
|
||
Oluştur" formunu gösterir — kullanıcı adı/şifre girip ilk admin hesabını
|
||
oradan oluşturursun. `/users` sayfasından ek kullanıcı ekleyip silebilirsin
|
||
(kendi hesabını veya son kalan tek kullanıcıyı silmek engellenir).
|
||
|
||
`SESSION_SECRET` production'da zorunlu (`openssl rand -base64 32` ile
|
||
üretilebilir) — local dev'de boş bırakılırsa güvensiz bir varsayılan
|
||
kullanılır, sadece test için.
|
||
|
||
## Test / Doğrulama Akışı
|
||
|
||
1. `FORCE_LIVE_URL=<gerçek veya kısa test yayını URL'si>` ile `apps/api-daemon`'ı
|
||
çalıştırırsan polling'i atlayıp doğrudan capture'ı tetikler.
|
||
2. `shared-media/raw/<sessionId>/` altında 15dk'lık segment dosyaları ve
|
||
`segments.csv` oluştuğunu doğrula; DB'de `raw_segments` satırları düşer.
|
||
3. `sc_heavy_worker` (Python) her tamamlanan segmenti `signal-detection`
|
||
kuyruğundan alıp ses peak + (varsa) chat velocity analiziyle
|
||
`candidate_segments` üretir.
|
||
4. Her aday, `stt-scoring` kuyruğunda OpenAI Whisper API ile transkribe edilir;
|
||
sonuç `candidate_segments.transcript_json` alanına yazılır, Telegram'a
|
||
bildirim gider ve `video-render` kuyruğuna otomatik iş eklenir.
|
||
5. `video-render` (Python, `video_render.py`) yüz tespiti + yumuşatılmış
|
||
dinamik crop ile 9:16'ya çevirir, transkriptten `.ass` altyazı üretip
|
||
yakar, `/shared-media/shorts/<candidate_id>.mp4`'e yazar;
|
||
`short_videos.status` `READY`/`FAILED` olur, Telegram'a bildirim gider.
|
||
6. Panelde (`/`, `/segments`, kanal detay sayfaları) kanal durumu, ham
|
||
segment/transkript ve render edilen 9:16 kısa videoları izle/indir.
|
||
|
||
## Bilinen Sınırlamalar (bu faz kapsamı dışı)
|
||
|
||
- LLM virality skorlama, metadata üretimi, telif/görüntü filtresi yok —
|
||
transkribe edilen her aday otomatik render edilir, eşik/filtre yok.
|
||
- Çoklu konuşmacı / split-screen şablonu yok — sadece tekil konuşmacı
|
||
(yüz-merkezli dinamik crop).
|
||
- YouTube/Instagram/TikTok'a otomatik yayınlama yok (bu API'ler ayrı onay
|
||
süreçleri gerektiriyor — `prd.md` tartışmasına bkz.).
|
||
- Aday pencere çıkarımı her zaman tek bir 15dk'lık segment dosyasıyla sınırlı;
|
||
segment sınırına yakın bir an kırpılabilir (segment'ler arası dikiş, gelecek
|
||
bir iyileştirme).
|