|
| 1 | +# SAM Cloud M3U Crawler |
| 2 | + |
| 3 | +Crawler asíncrono en Python para consultar enlaces de escucha de SAM Broadcaster Cloud, seguir redirecciones, detectar `icy-name` y generar una lista M3U con la **URL final redirigida**. |
| 4 | + |
| 5 | +> [!IMPORTANT] |
| 6 | +> Utiliza este proyecto únicamente sobre rangos y servicios para los que tengas autorización. La enumeración masiva de SID o una concurrencia extrema puede incumplir condiciones del proveedor o degradar el servicio. El proyecto usa valores prudentes por defecto y bloquea configuraciones agresivas sin una confirmación explícita. |
| 7 | +
|
| 8 | +## Funciones |
| 9 | + |
| 10 | +- Rango SID configurable, incluido `0-999999`. |
| 11 | +- Hasta 2048 tareas/conexiones configurables como techo técnico. |
| 12 | +- Límites separados de concurrencia total, por host y peticiones por segundo. |
| 13 | +- Seguimiento de redirecciones HTTP 301, 302, 303, 307 y 308. |
| 14 | +- La M3U contiene la URL final, no el enlace intermedio de la API. |
| 15 | +- Detección de `icy-name`, `ice-name`, `x-audiocast-name` y descripción ICY. |
| 16 | +- Detección básica de M3U/PLS devueltos como cuerpo y extracción del primer stream. |
| 17 | +- Reintentos, timeout, checkpoint, reanudación y base SQLite. |
| 18 | +- Exportación M3U y JSONL. |
| 19 | +- CI y ejecución manual/programada mediante GitHub Actions. |
| 20 | + |
| 21 | +## Instalación |
| 22 | + |
| 23 | +```bash |
| 24 | +python -m venv .venv |
| 25 | +source .venv/bin/activate # Windows: .venv\\Scripts\\activate |
| 26 | +python -m pip install -e ".[dev]" |
| 27 | +``` |
| 28 | + |
| 29 | +## Ejemplo prudente |
| 30 | + |
| 31 | +```bash |
| 32 | +samcloud-m3u \ |
| 33 | + --start 0 \ |
| 34 | + --end 9999 \ |
| 35 | + --concurrency 32 \ |
| 36 | + --per-host 16 \ |
| 37 | + --max-rps 8 |
| 38 | +``` |
| 39 | + |
| 40 | +Archivos generados: |
| 41 | + |
| 42 | +- `output/samcloud.m3u` |
| 43 | +- `output/stations.jsonl` |
| 44 | +- `data/stations.sqlite3` |
| 45 | +- `data/next_sid.txt` |
| 46 | + |
| 47 | +## Rango completo |
| 48 | + |
| 49 | +El rango completo se expresa así, pero debería dividirse en lotes y ejecutarse solo con permiso del proveedor: |
| 50 | + |
| 51 | +```bash |
| 52 | +samcloud-m3u --start 0 --end 999999 --resume |
| 53 | +``` |
| 54 | + |
| 55 | +## Techo de 2048 conexiones |
| 56 | + |
| 57 | +El programa admite `--concurrency 2048`, pero las configuraciones de alta carga están bloqueadas salvo confirmación expresa. Incluso con autorización, empieza con cifras bajas y mide la respuesta del servidor. |
| 58 | + |
| 59 | +```bash |
| 60 | +samcloud-m3u \ |
| 61 | + --start 0 \ |
| 62 | + --end 999999 \ |
| 63 | + --concurrency 2048 \ |
| 64 | + --per-host 2048 \ |
| 65 | + --max-rps 2048 \ |
| 66 | + --acknowledge-load I_HAVE_PERMISSION |
| 67 | +``` |
| 68 | + |
| 69 | +No se recomienda esta configuración en un runner compartido ni contra un único host público. El límite `max-rps` suele ser más importante que el número de tareas. |
| 70 | + |
| 71 | +## Reanudación |
| 72 | + |
| 73 | +```bash |
| 74 | +samcloud-m3u --start 0 --end 999999 --resume |
| 75 | +``` |
| 76 | + |
| 77 | +El checkpoint contiene el siguiente SID pendiente. SQLite conserva y actualiza resultados anteriores; la M3U se regenera ordenada y sin duplicados por SID. |
| 78 | + |
| 79 | +## Formato M3U |
| 80 | + |
| 81 | +```m3u |
| 82 | +#EXTM3U |
| 83 | +#EXTINF:-1 sid="123" group-title="SAM Cloud" content-type="audio/mpeg",Nombre detectado |
| 84 | +https://servidor-final.example/live.mp3 |
| 85 | +``` |
| 86 | + |
| 87 | +## GitHub Actions |
| 88 | + |
| 89 | +- `CI`: instala, ejecuta Ruff y las pruebas. |
| 90 | +- `Crawl and build M3U`: ejecución manual con rango y límites configurables. |
| 91 | +- Programación semanal: usa por defecto `0-9999`, 32 tareas, 16 conexiones por host y 8 peticiones/s. |
| 92 | +- Para cambiar el rango programado, crea las variables de repositorio `SAMCLOUD_START` y `SAMCLOUD_END`. |
| 93 | +- Los resultados se suben como artifact durante 30 días. |
| 94 | +- En una ejecución manual, `publish=true` publica `output/` y el checkpoint en la rama predeterminada. |
| 95 | + |
| 96 | +GitHub advierte que los workflows programados pueden retrasarse en periodos de carga y que los runners alojados tienen un máximo de seis horas por job. Por eso conviene usar lotes pequeños y programar fuera del minuto 0. |
| 97 | + |
| 98 | +## Limitaciones |
| 99 | + |
| 100 | +- Algunos servidores antiguos responden con una línea de estado no estándar `ICY 200 OK`; `aiohttp` puede rechazar esos endpoints. Los servidores modernos suelen devolver HTTP normal con cabeceras `icy-*`. |
| 101 | +- Cerrar una respuesta de audio tras leer sus cabeceras minimiza ancho de banda, pero sigue contando como una conexión al servicio. |
| 102 | +- Una URL que responde correctamente no garantiza que la emisora esté permanentemente activa. |
| 103 | +- El proyecto no intenta saltarse autenticación, CAPTCHA, bloqueos, cuotas ni controles de acceso. |
| 104 | + |
| 105 | +## Referencias |
| 106 | + |
| 107 | +- Documentación de clientes y conectores aiohttp: https://docs.aiohttp.org/en/stable/client.html |
| 108 | +- Límites de GitHub Actions: https://docs.github.com/actions/reference/limits |
| 109 | +- Eventos programados de Actions: https://docs.github.com/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule |
| 110 | +- Guías SAM Broadcaster Cloud: https://support.spacial.com/hc/en-us/sections/206508527-User-Guides |
| 111 | + |
| 112 | +## Licencia |
| 113 | + |
| 114 | +MIT. El proyecto no está afiliado a Spacial, Triton Digital ni GitHub. |
| 115 | + |
| 116 | +## Publicar como repositorio nuevo |
| 117 | + |
| 118 | +Con GitHub CLI autenticado: |
| 119 | + |
| 120 | +```bash |
| 121 | +./scripts/publish.sh samcloud-m3u-crawler public |
| 122 | +``` |
| 123 | + |
| 124 | +En PowerShell: |
| 125 | + |
| 126 | +```powershell |
| 127 | +.\scripts\publish.ps1 -RepositoryName samcloud-m3u-crawler -Visibility public |
| 128 | +``` |
0 commit comments