Files

5.5 KiB

Recipe: descarga automática castellano gnula → Jellyfin

Flujo completo validado 2026-05-30. Para promover a pipeline del registry (download_gnula_movie_py_pipelines o similar). Humano solo hace captcha si sale.

0. Infra previa (una vez)

  • Bridge NordVPN: start_nordvpn_socks_bridge_bash_infra --port 8889 (creds env NORDVPN_SOCKS_USER/PASS de pass datardos-vps/nordvpn). gost SOCKS5→HTTP local.
  • Jellyfin realtime monitor ON en libs media/movies,media/tv (ya).
  • systemd-user timer popelis-import.timer (3min) → popelis_import_media_drop (manual→media+metadata).
  • Extensiones unpacked en Windows: C:\Users\lucas\hls-dl-ext (HLS+AES decrypt), C:\Users\lucas\ubol (uBlock Origin Lite MV3, mata ads/popunders).

1. Lanzar Chrome (Windows, visible) por NordVPN + CDP + extensiones

chrome.exe --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 \
  --remote-allow-origins='*' \
  --user-data-dir='C:\Users\lucas\AppData\Local\fn-chrome-cdp-profile' \
  --proxy-server=http://127.0.0.1:8889 \
  --disable-extensions-except='C:\Users\lucas\hls-dl-ext,C:\Users\lucas\ubol' \
  --load-extension='C:\Users\lucas\hls-dl-ext,C:\Users\lucas\ubol' \
  --no-first-run --no-default-browser-check --new-window "https://www.gnularetro.cc/release/2025/"

NOTA Chrome 148: --load-extension SOLO no carga las extensiones; hay que añadir --disable-extensions-except con los mismos paths. Verificar con browser-ws Target.getTargets (SW chrome-extension://) o chrome://extensions. gnula está ISP-bloqueado (Allot) + Cloudflare → NordVPN salta ISP, navegador real pasa CF.

2. Listado: detectar pelis con bandera España + dedup

CDP eval en la página release: por cada a[href*="/ver-pelicula/"], mirar imgs /flags/.

  • es.png = España (Español/castellano) — la que queremos. (En el LISTADO el alt-text está invertido: es.png alt="Latino". IGNORAR alt, usar el nombre de imagen es.png. Confirmado en la página de peli: el grupo es.png se etiqueta literalmente "Español".)
  • mx.png = México/Latino. jp.png = Subtitulado/VOSE.
  • Dedup: cruzar título vs GET /api/v3/movie de Radarr (key 63fb51c8...) — saltar los ya presentes.

3. Página de la peli: elegir server Español

CDP: navegar al href. Las opciones de player son li[data-nume] (DooPlay):

  • Grupo "Español" (es.png) = dnume bajos; "Subtitulado" (jp.png) = dnume altos.
  • Servers: streamplay, luluvid(=luluvdo), bigwarp, filemoon, dsvplay, powvideo, streamtape, vidmoly, voe.
  • PREFERIR luluvid/luluvdo (sabemos descifrar su HLS AES-128). Clic: li[data-nume="2"].click() (luluvid Español).
  • Carga iframe lulustream.com/e/<id> → resuelve a luluvdo.com/e/<id>.

4. Play (CDP) — método que FUNCIONA (sin depender de uBlock)

luluvdo pone un overlay ad click-catcher div con z-index>=1000 encima del player: el .click() JS no es gesto válido y un clic normal abre popunder. Solución validada (en el target del iframe luluvdo):

  1. Quitar overlays: document.querySelectorAll('div,iframe') con zIndex>=1000.remove() (quita ~4).
  2. Trusted click en .jw-icon-display/video via Input.dispatchMouseEvent (coords del rect).
  3. jwplayer().play(true). → video.paused=false + master.m3u8 pedido. Captcha real (si sale) = humano.
  • Cerrar popunders: GET /json/list → cerrar targets que no sean gnula/luluvdo (/json/close/<id>).
  • uBlock: --load-extension SOLO falló en Chrome 148 (ver gotcha); NO es necesario para play (el overlay se quita in-page). Útil solo para reducir popunders generales.

5. Descarga streaming + descifrado (NO blob → no peta Chrome)

temp/grab_stream.py <basename>:

  • Conecta CDP al iframe player.
  • Lee master.m3u8 (de performance entries) → variante → media playlist.
  • AES-128: #EXT-X-KEY (key url + IV; sin IV → IV=media-sequence en 16B BE).
  • Por segmento: in-page fetch(seg)→arrayBuffer→base64 (sesión browser=pasa 522 CF) → CDP → LOCAL: base64decode + AES.new(key,CBC,iv).decrypt + unpad PKCS7 + append a /tmp/grab/<n>.ts. (1 segmento en RAM a la vez → aguanta pelis grandes.)
  • Remux ffmpeg -c copy .ts→.mkv directo a F:\POPELIS\manual\movies\<basename>.mkv. Borra .ts.

6. Import + Jellyfin (automático)

  • systemd timer (3min) corre popelis_import_media_drop → identifica (Radarr/TMDb) + mueve manual/movies → media/movies con ficha → Jellyfin realtime monitor → aparece.
  • (o lanzar import on-demand: RADARR_KEY=.. SONARR_KEY=.. python popelis_import_media_drop.py --apply)

Gotchas

  • blob-en-memoria petaba Chrome con peli 3.4GB → usar grab_stream.py (streaming).
  • Token master.m3u8 caduca ~8h + ligado a IP de salida → descargar por el MISMO proxy/sesión.
  • 522 CF sólo afecta clientes externos (curl/ffmpeg/yt-dlp); la sesión viva del navegador = 200.
  • Multi-audio urlset: el variant elegido trae 1 audio (el del grupo Español = castellano).
  • chrome.downloads / a.click() blob cae en Downloads, NO respeta setDownloadBehavior → por eso grab_stream.py escribe directo a disco vía CDP+local, evitando el download del navegador.
  • --load-extension falla en Chrome 148: las extensiones unpacked (hls-dl-ext, ubol) NO cargaron (Target.getTargets no lista sus SW + overlay ad seguía). Fix a probar: añadir --disable-extensions-except='<mismos paths>' junto a --load-extension. Pero NO es necesario para el flujo: el overlay se neutraliza in-page (paso 4). uBOL Lite (MV3 DNR) además NO mata bien el click-catcher inyectado por JS (limitado vs uBO full, que es MV2 y Chrome 148 ya no admite). Conclusión: depender del paso-4 in-page, no de uBlock.