fix(playback): galaxyporn re-resolwuje sie po bledzie zamiast poddawac

Zgloszenie 7f2234eb: "samo wideo dziala, a aplikacja zglasza problem
z hostem". Ekstraktor NIE jest zepsuty:

  - try_extract oddaje dzialajacy manifest w 0,4 s
  - z Refererem ekstraktora (galaxy.4meplayer.pro) link daje 200; bez
    niego 403, wiec naglowek jest ustawiany poprawnie
  - pobranie przez nasze /proxy oddaje 200 i playliste z wariantem 1080p
  - telemetria 14 dni: 1140 udanych, 25 bledow (2,1%)

Padal POJEDYNCZY nod CDN. Kolejne wywolania resolve tej samej sceny
wracaja z ROZNYMI adresami (185.237.107.133, potem 203.188.166.163), a
token ma ~2,8 h TTL i nie jest IP-bound. Czyli ponowny resolve po prostu
laduje na zywym wezle — dokladnie wzorzec, ktory dziala juz dla watchporn.
Stad `tube:galaxyporncom` w BACKEND_RERESOLVE_ORIGINS.

Po drodze skorygowany FALSZYWY komentarz w seekplayer_engine.py: twierdzil,
ze stream_proxy.py ma galaz `verify=False` dla hostow pod golym IP. Nie ma
jej — slowo `verify` nie wystepuje w tym pliku ani razu. `proxy_no_verify`
i `cf_fallback` sa ustawiane przez trzy ekstraktory i przez NIC nieczytane.
cf_fallback jest o tyle bolesny, ze to gotowy zapasowy URL, ktory uratowalby
wlasnie ten przypadek. Osobne zadanie.

Blad diagnostyczny po drodze, dla potomnosci: pierwszy test dal 404, bo
przetestowalem URL uciety wlasnym printem [:70], bez /master.m3u8.
This commit is contained in:
goon-foss 2026-08-14 10:22:08 +02:00
parent e074229bbb
commit 47547fe694
3 changed files with 26 additions and 5 deletions

View file

@ -141,10 +141,17 @@ def extract(page_url: str, *, timeout: float = 30.0) -> list[StreamSource] | Non
source = (data.get("source") or "").strip()
cf = (data.get("cf") or "").strip()
# Source: IP-bound m3u8 URL na CDN edge (np. `185.237.107.146/v4/<sig>/<exp>/ty/<hash>/master.m3u8`).
# Token signed dla VPS IP, proxy poda segmenty z tego samego IP, OK.
# CDN servuje cert na IP, fetch wymaga verify=False (stream_proxy.py ma już
# taką gałąź dla IP-host m3u8).
# Source: m3u8 na CDN edge pod GOŁYM IP (np. `185.237.107.146/v4/<sig>/<exp>/…/master.m3u8`).
# Token ma ~2,8 h TTL i NIE jest związany z IP (sprawdzone 2026-08-14), a węzły
# rotują: dwa kolejne resolve tej samej sceny wracają z różnymi adresami. Dlatego
# padnięcie odtwarzania na tym źródle leczy się ponownym resolve, a nie WebView-em
# (`BACKEND_RERESOLVE_ORIGINS` w PlayerScreen).
#
# UWAGA: `proxy_no_verify` i `cf_fallback` niżej NIE SĄ przez nic czytane. Wcześniejszy
# komentarz twierdził, że `stream_proxy.py` ma gałąź `verify=False` dla hostów-IP —
# nie ma jej, w tym pliku nie występuje słowo `verify` ani razu. W praktyce certyfikaty
# tych węzłów przechodzą weryfikację (fetch przez proxy oddaje 200), więc to flagi
# informacyjne, nie działające przełączniki.
sources: list[StreamSource] = []
if source:
sources.append(

View file

@ -16,6 +16,13 @@ export type ChangelogEntry = {
};
export const CHANGELOG: ChangelogEntry[] = [
{
id: '2026-08-14b',
date: 'August 2026',
items: [
'galaxyporn: if a video fails to start, the app now asks for a fresh link instead of giving up. Their servers rotate, so a second try usually lands on a working one.',
],
},
{
id: '2026-08-14',
date: 'August 2026',

View file

@ -312,7 +312,14 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
// natywny direct stream (0 VPS bandwidth). Dla tych tubów `gone` (404 z CDN) znaczy
// "URL zwietrzał", NIE "scena skasowana" (backend rzuciłby HosterDead→410), więc
// re-resolvujemy też na gone.
const BACKEND_RERESOLVE_ORIGINS = ['tube:watchporn'];
//
// galaxyporn dopisany 2026-08-14 po zgłoszeniu 7f2234eb („samo wideo działa, a apka
// zgłasza problem z hostem"). Ekstraktor jest sprawny: telemetria z 14 dni to 1140
// udanych odtworzeń i 25 błędów (2,1%), a resolve na żądanie oddaje działający
// manifest w 0,4 s. Padał POJEDYNCZY nod CDN — kolejne wywołania resolve wracają
// z RÓŻNYMI adresami (185.237.107.133, potem 203.188.166.163), więc ponowny resolve
// po prostu ląduje na żywym węźle. Token ma ~2,8 h TTL, czyli wygasanie to nie to.
const BACKEND_RERESOLVE_ORIGINS = ['tube:watchporn', 'tube:galaxyporncom'];
const canBackendReresolve =
!!sceneId && !!params.playbackId && BACKEND_RERESOLVE_ORIGINS.includes(playOrigin ?? '');
// Seek/decode recovery (bug f6c86847: doply/playmogo „invalid NAL length” przy