fix: canlı-tespitini tekrar yt-dlp'ye taşı, temiz ISP proxy ekle

Regex tabanlı HTML çıkarımı IP'den bağımsız olarak tutarsız çıktı:
YouTube bazen player verisini (videoDetails) sunucu tarafında hiç
göndermiyor. yt-dlp'nin kendi extractor'ı engellenmediği sürece her
zaman doğru çözüyor, o yüzden kontrol tekrar yt-dlp'ye taşındı — bu
sefer üç katmanı birlikte kullanarak: cookie (oturum), pot-provider
(PO-token) ve PROXY_URL (temiz residential/ISP IP — Coolify
sunucusunun kendi IP'si bir günlük yoğun testten sonra işaretlendi).
Oxylabs ISP Proxies ile doğrulandı (gerçek ISP: CenturyLink), datacenter
proxy'lerin aksine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 21:17:00 +03:00
co-authored by Claude Sonnet 5
parent f18692dd82
commit f139d6002f
6 changed files with 48 additions and 91 deletions
+12 -27
View File
@@ -6,11 +6,14 @@ const COOKIES_PATH = "/tmp/yt-cookies.txt";
const COOKIES_SETTING_KEY = "ytdlp_cookies";
/**
* YouTube's anti-bot layer against datacenter IPs has two parts, both
* needed together: a "Sign in to confirm you're not a bot" wall (avoided
* with an authenticated session's cookies) and a "The page needs to be
* reloaded" proof-of-origin token check (avoided by querying the
* bgutil-ytdlp-pot-provider sidecar — see docker-compose.yml sc_pot_provider).
* YouTube's anti-bot layer against yt-dlp has three parts, all needed
* together: a "Sign in to confirm you're not a bot" wall (avoided with an
* authenticated session's cookies), a "The page needs to be reloaded"
* proof-of-origin token check (avoided by querying the bgutil-ytdlp-pot-
* provider sidecar — see docker-compose.yml sc_pot_provider), and — once the
* Coolify server's own IP had a day of heavy testing behind it — outright
* blocking tied to that IP's reputation specifically (avoided by routing
* through a clean residential/ISP proxy, PROXY_URL).
*
* Cookies rotate/expire over hours, so they're stored in the DB (updated
* from the panel's Settings page — see apps/frontend/app/settings) rather
@@ -31,27 +34,9 @@ export async function ytdlpAntiBotArgs(): Promise<string[]> {
args.push("--extractor-args", `youtubepot-bgutilhttp:base_url=${env.ytdlpPotProviderUrl}`);
}
if (env.proxyUrl) {
args.push("--proxy", env.proxyUrl);
}
return args;
}
/**
* Same cookies, formatted as a `Cookie:` header for plain fetch() calls
* (youtubePolling.ts's live-check). Logged-in cookies also skip YouTube's
* interactive EU consent wall, which an unauthenticated fetch from an
* EU-geolocated server IP otherwise hits — that page has no `videoDetails`,
* so the check would misreport a genuinely live channel as offline.
*/
export async function getCookieHeader(): Promise<string | null> {
const setting = await prisma.appSetting.findUnique({ where: { key: COOKIES_SETTING_KEY } });
if (!setting?.value) return null;
const pairs = setting.value
.split("\n")
.map((line) => line.trim())
.filter((line) => line && !line.startsWith("#"))
.map((line) => line.split("\t"))
.filter((fields) => fields.length >= 7)
.map(([, , , , , name, value]) => `${name}=${value}`);
return pairs.length > 0 ? pairs.join("; ") : null;
}