83 lines
5.5 KiB
Markdown
83 lines
5.5 KiB
Markdown
# 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.
|