Files
ayrisdevandClaude Sonnet 5 f00fc73b0b feat: 9:16 crop + dinamik altyazı render motoru (Faz 2, Modül 4)
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>
2026-09-01 15:26:22 +03:00

4.7 KiB
Raw Permalink Blame History

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

cp .env.example .env
# .env içindeki OPENAI_API_KEY / TELEGRAM_* değerlerini doldurun
pnpm install

Yerelde (Docker olmadan)

# 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):

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)

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).