Commit Graph
24 Commits
Author SHA1 Message Date
ayrisdevandClaude Sonnet 5 5447a8d269 debug: canlı-tespit için detaylı teşhis bilgisi ekle
Cookie header'ı eklemek beklenen sonucu vermedi — @ertemsener kanalı
gerçekten canlıydı ama sistem hâlâ "değil" diyordu. Kör tahminle
devam etmek yerine, her kontrolde (sonuç ne olursa olsun) final URL,
HTML uzunluğu, cookie gönderilip gönderilmediği, videoDetails bulunup
bulunmadığı ve consent formu varlığı GET /status'ta lastPollDebug
alanında görünür kılındı.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 20:01:58 +03:00
ayrisdevandClaude Sonnet 5 32c09de896 fix: canlı-tespit fetch'ine cookie ekle — AB consent duvarını aş
Coolify sunucusu AB'de; oturumsuz istek YouTube'un interaktif consent
sayfasına düşüyor (o sayfada videoDetails yok), bu da gerçekten canlı
bir kanalı "değil" gibi gösteriyordu (doğrulandı: @ertemsener canlıydı,
sistem "değil" dedi). yt-dlp için zaten sakladığımız oturum açık
cookie'leri aynı fetch'e Cookie header'ı olarak eklendi — giriş yapılmış
hesaplar consent duvarını hiç görmüyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:50:55 +03:00
ayrisdevandClaude Sonnet 5 0547018cc3 fix: canlı-tespitini yt-dlp'siz, doğru kapsamlı fetch'e taşı
Proxy'ye gerek kalmadan bir çözüm: bugün boyunca düz HTTP fetch hiç
engellenmedi, sadece yt-dlp çağrıları bot-check/PO-token duvarına
takıldı. Önceki naive regex sorunuysa "videoId" alanının sayfada
onlarca kez (kanal video listesi, öneriler) geçmesiydi. Çözüm:
YouTube'un videoDetails objesi — sayfa gerçekten canlıysa tek ve
biricik olarak videoId/isLive/channelId'yi birlikte içeriyor (canlı
değilse obje hiç yok, doğrulandı). channelId çapraz kontrolüyle
birlikte hem doğru video hem yt-dlp'ye hiç dokunmadan (dolayısıyla
bot-check'e hiç maruz kalmadan) tespit yapılıyor. yt-dlp + cookie +
pot-provider artık sadece gerçek capture adımında kullanılıyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:40:56 +03:00
ayrisdevandClaude Sonnet 5 5e211096c5 feat: YouTube cookie'lerini panelden yönetilebilir hale getir
Cookie'ler saatler içinde eskiyordu, her seferinde manuel Coolify env
güncellemesi + redeploy gerekiyordu. Artık DB'de (app_settings tablosu)
tutuluyor; /settings sayfasından yeni cookies.txt yapıştırılıp
kaydedilebiliyor, bir sonraki yt-dlp çağrısında redeploy gerekmeden
devreye giriyor. YTDLP_COOKIES_B64 env var mekanizması kaldırıldı.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:13:10 +03:00
ayrisdevandClaude Sonnet 5 d562c05882 fix: yeniden başlatma sonrası açık kalan session'ları temizle
Bir redeploy, devam eden capture'ı temizlik kodu hiç çalışmadan
öldürüyordu — StreamSession.endedAt sonsuza dek null kalıyordu. Bu
sadece panelde yanlış "kayıtta" göstermekle kalmıyor, startSession()
açık bir session gördüğünde o kanal için yeni session başlatmayı
tamamen atlıyor — yani o kanal bir daha asla kayda alınamıyordu.
api-daemon başlarken artık tüm açık session'ları kapatıyor (taze bir
process başlangıcı = gerçekte devam eden capture yok demektir).
BullMQ lockDuration da 24 saatten 10 dakikaya indirildi — worker
canlıyken kilit otomatik yenileniyor, düşük değer sadece ölü bir
worker'ın job'ının ne kadar hızlı kurtarılacağını etkiliyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 18:54:47 +03:00
ayrisdevandClaude Sonnet 5 d05aed72ff fix: canlı-tespitini yt-dlp'ye geri taşı — HTML regex yanlış videoId yakalıyordu
Kullanıcı panelindeki kayıtların kendi yayınıyla alakasız olduğunu
bildirdi. Sebep: channel /live sayfası onlarca alakasız videoId
içeriyor (kanal video listesi, öneriler); düz regex sayfadaki İLK
videoId'yi alıyordu, bu da rastgele başka bir videoydu — isLive:true
kontrolü de aynı bağlamda değildi. yt-dlp'nin extractor'ı kanalın asıl
o anki canlı videosunu doğru çözüyor; -f (format) verilmediği için
PO-token duvarını da tetiklemiyor (format çözümleme sadece gerçek
capture adımında, -f ile, gerekiyor).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 18:46:59 +03:00
ayrisdevandClaude Sonnet 5 8a92b9b019 feat: panelden video izleme/indirme/silme + eşzamanlı yayın kapasitesi düzeltmesi
- streamIngest worker concurrency 3'ten sabit değildi, artık
  MAX_CONCURRENT_CAPTURES (varsayılan 10) ile ayarlanabiliyor. Eskiden
  3'ten fazla kanal aynı anda canlıya geçerse fazlası, ilk 3'ten biri
  bitene kadar (saatlerce) hiç kayda alınmıyordu.
- Python worker'larda (signal-detection, stt-scoring) bullmq varsayılan
  concurrency'si 1'di — WORKER_CONCURRENCY (varsayılan 5) ile
  paralelleştirildi, birden fazla kanal aynı anda segment/transkript
  üretirse sıraya takılmasın diye.
- Frontend artık shared-media volume'üne bağlı: /api/segments/[id]/video
  route'u Range destekli video stream/indirme sağlıyor. Segment ve
  kanal detay sayfalarına <video> oynatıcı, indirme linki ve onaylı
  silme (RawSegment + CandidateSegment, dosya dahil) eklendi.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 18:33:33 +03:00
ayrisdevandClaude Sonnet 5 fd21bbfb14 fix: yt-dlp'ye Node.js JS runtime + EJS solver ekle (n-challenge)
Gerçek capture denemesinde debug endpoint'i asıl nedeni gösterdi:
"n challenge solving failed" — YouTube'un imza çözme JS challenge'ı
için yt-dlp'nin bir JS runtime'ı yoktu, bu da formatların eksik
kalıp "page needs to be reloaded" ile sonuçlanmasına yol açıyordu.
node:22-slim zaten Node 22 içeriyor (minimum gereksinim); yt-dlp'yi
"yt-dlp[default]" (EJS solver dahil) olarak kurup capture çağrısına
--js-runtimes node eklendi. Lokal olarak doğrulandı: aynı video artık
formatları hatasız çözüyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:55:43 +03:00
ayrisdevandClaude Sonnet 5 08569ce4ae debug: yt-dlp/ffmpeg capture stderr'ını GET /debug/capture/:sessionId ile görünür kıl
İlk gerçek capture denemesi 2 saniyede sessionı bitirdi (0 segment) —
Coolify /logs endpoint'i api-daemon'un stdout'unu güvenilir şekilde
izole edemediği için sebebi göremedik. Artık her session'ın son
yt-dlp/ffmpeg stderr satırları bellekte tutulup HTTP'den okunabiliyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:45:36 +03:00
ayrisdevandClaude Sonnet 5 19fe430549 frontend: kanal detay sayfası (canlı durum + poll hatası + yayın geçmişi)
/channels/[id] rotası eklendi: dashboard'daki kanal adı artık oraya
link veriyor. Sayfa api-daemon'un /status'undan canlı durum ve son
poll hatasını (lastPollError, DB'de değil sadece bellekte tutuluyordu)
çekiyor, Prisma'dan da o kanala ait tüm StreamSession/RawSegment/
CandidateSegment geçmişini transkript önizlemesiyle listeliyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:34:15 +03:00
ayrisdevandClaude Sonnet 5 b62d6a7e5f fix: canlı-tespitini yt-dlp'den düz HTTP fetch'e taşı
PO-token duvarı polling'de hiç gerekli değildi — sadece stream byte'ı
indirirken (capture) lazım. yt-dlp --simulate bile format çözümlemeye
çalıştığı için PO-token'a takılıyordu. Artık /channel/<id>/live
sayfasını düz fetch ile çekip ytInitialData içindeki isLive/videoId'yi
regex ile okuyoruz — bot-check/cookie/PO-token'a hiç maruz kalmıyor.
yt-dlp + cookie + pot-provider sadece gerçek capture adımında kalıyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:31:29 +03:00
ayrisdevandClaude Sonnet 5 fc7d1109aa fix: bgutil-ytdlp-pot-provider ile PO-token duvarını aş
Cookie bot-check'i çözdü ama "The page needs to be reloaded" hatası
kalıcıydı — YouTube artık proof-of-origin token da istiyor. Coolify
stack'ine brainicism/bgutil-ytdlp-pot-provider sidecar servisi
(sc_pot_provider, port 4416) eklendi, api-daemon imajına Python
plugin'i kuruldu, her yt-dlp çağrısına
--extractor-args youtubepot-bgutilhttp:base_url=... eklendi.
ytdlpCookieArgs -> ytdlpAntiBotArgs olarak birleştirildi.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:12:39 +03:00
ayrisdevandClaude Sonnet 5 e5a6f67788 fix: android player_client'ı kaldır, sadece cookie + web client kullan
Cookie tek başına bot-check'i çözüyordu ama android client ile
birlikte kullanılınca "No video formats found" hatası sürekli
tekrarladı — android client + cookie kombinasyonu tutarsız bir
manifest döndürüyor gibi. android client'sız, sadece cookie +
varsayılan web client + bestvideo+bestaudio/best format seçiciyle
aynı video id lokal olarak sorunsuz çözüldü.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:02:43 +03:00
ayrisdevandClaude Sonnet 5 ab7b1551cc fix: yt-dlp format seçicisini bestvideo+bestaudio/best'e çevir
Cookie bot-check'i çözdü ama yeni bir hata çıktı: "No video formats
found" / "Requested format is not available". AyrisTech'in canlı
yayını dikey (1080x1920) ve HLS formatları video-only/audio-only
ayrı geliyor — tek parça "best" format hiç yok. Hem live-check hem
capture çağrısını "bestvideo+bestaudio/best" seçicisine çevirdik;
lokal olarak doğrulandı (yt-dlp video id'yi doğru döndürüyor).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 16:24:12 +03:00
ayrisdevandClaude Sonnet 5 09b958ec00 fix: yt-dlp'ye YouTube cookie desteği ekle (bot-check bypass)
android player_client YouTube'un "Sign in to confirm you're not a bot"
duvarını aşmadı — Coolify sunucusunun IP'si datacenter olarak
işaretlenmiş. Kimlik doğrulanmış bir tarayıcı oturumunun cookies.txt'i
YTDLP_COOKIES_B64 env değişkeni (Coolify'da ayarlandı, repo'da yok)
üzerinden container'a taşınıp /tmp'e yazılıyor ve her yt-dlp
çağrısına --cookies olarak veriliyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 16:14:46 +03:00
ayrisdevandClaude Sonnet 5 81d71bd761 fix: yt-dlp android player_client ile bot-tespitini azalt
AyrisTech kanalı gerçekten canlıydı ama Coolify sunucusunun IP'si
YouTube'un "Sign in to confirm you're not a bot" duvarına takıldı
(bu ortamdan aynı komut sorunsuz çalıştı — IP itibarına bağlı).
Hem live-check hem capture çağrısına --extractor-args
"youtube:player_client=android" eklendi; bu client genelde aynı
PO-token doğrulamasına tabi değil.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 16:02:03 +03:00
ayrisdevandClaude Sonnet 5 ad419f38b0 debug: yt-dlp live-check hatalarını /status'ta görünür kıl
yt-dlp hem "kanal canlı değil" hem de gerçek bir hata (ağ engeli,
bot tespiti, extractor kırılması) durumunda non-zero exit code
veriyor; ikisi ayırt edilemiyordu. Son hata mesajı artık kanal
başına saklanıp GET /status içinde lastPollError alanında dönüyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:54:51 +03:00
ayrisdevandClaude Sonnet 5 bae115f497 chore: tsbuildinfo build artifact'ını gitignore'a ekle
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:17:40 +03:00
ayrisdevandClaude Sonnet 5 deefa75926 frontend: kanal ekleme formu
Dashboard'a name/youtubeHandle/channelId alanlarıyla bir server action
formu eklendi. Polling ve /status için channel_id gerçek bir YouTube
UC... kimliği olmalı.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 15:17:26 +03:00
ayrisdevandClaude Sonnet 5 0374846cc1 db: initial migration + container başlangıcında otomatik migrate deploy
Postgres canlıydı ama şema hiç uygulanmamıştı (migrations/ klasörü boştu).
Bu ortamdan Coolify'ın Postgres'ine ağ erişimi yok (5432 filtreli), bu yüzden
`prisma migrate dev` yerine offline schema diff (`migrate diff --from-empty`)
ile ilk migration SQL'i üretildi. api-daemon container'ı artık başlarken
`prisma migrate deploy` çalıştırıyor. Tüm servislere restart: unless-stopped
eklendi ki Postgres henüz hazır değilken başlayan container kendini toparlasın.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 14:58:34 +03:00
ayrisdevandClaude Sonnet 5 8ae34c18ef fix: Node imajlarını 22-slim'e yükselt (pnpm 11, Node >=22.13 istiyor)
node:20-slim üzerinde corepack pnpm@11.22.0'ı indirmeye çalışınca
"No such built-in module: node:sqlite" hatasıyla patlıyordu — pnpm 11
Node 22.13+ gerektiriyor. api-daemon ve frontend Dockerfile'larını
node:22-slim'e çektik, engines alanını güncelledik.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 14:51:38 +03:00
ayrisdevandClaude Sonnet 5 8419fbd963 infra: docker-compose.yml'i repo köküne taşı
Coolify build sırasında --project-directory olarak repo kökünü
kullanıyor; compose dosyası infra/ altındayken build context: ".."
/artifacts/apps yerine /artifacts/../apps'e (repo dışına) çözümleniyor
ve "lstat /artifacts/apps: no such file or directory" hatasıyla
patlıyordu. Dosyayı köke taşıyıp context: "." yaparak hem Coolify hem
de lokal `docker compose up` çağrısı için tutarlı hale getirdik.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 14:49:28 +03:00
ayrisdevandClaude Sonnet 5 8ff0d1d7ef infra: Coolify env var injection için env_file yerine ${VAR} substitution kullan
env_file: ../.env git repo'ya girmiyor (.gitignore), Coolify repo'yu clone
ettiğinde bu dosya bulunamayacaktı. Sırlar artık Coolify'ın application-level
environment variable deposundan ${VAR} substitution ile geliyor; local
dev'de docker compose kendi çalışma dizinindeki .env'i otomatik okuyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 14:42:47 +03:00
ayrisdevandClaude Sonnet 5 eccc74166a StreamClipper AI Faz 1: ingestion + sinyal analizi + STT + altyapı iskeleti
yt-dlp headless capture (15dk segmentleme), ses peak + chat velocity sinyal
tespiti, OpenAI Whisper STT (kelime zaman damgalı), BullMQ/Redis/Postgres
altyapısı ve kanal durumu + transkript kütüphanesi gösteren Next.js panel.
LLM virality skorlama, render/crop/altyazı ve multi-platform dağıtım bu
fazın kapsamı dışında.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 14:36:50 +03:00