Netflix casero: como montar tu propio streaming con NixOS (y por que Stremio no es suficiente)
La historia: solo queriamos ver Paprika
Todo empezo porque Pascual queria ver Paprika (2006, Satoshi Kon, peliculon). Teniamos Stremio montado en Docker, le damos play y… "video not supported". Probamos otro stream. Mismo error. Y otro. Igual.
Resulta que el streaming server dentro del container llevaba dias muerto. El nginx del frontend servia la UI bonita, pero cuando pedias un video real, 502. Connection refused al puerto 11470. Fantastico.
Lo reiniciamos. Ahora arranca, pero transcodea 4K HEVC por software en un AMD FX-8350 sin GPU. A ver, el FX-8350 es un clasico, pero transcodear 4K x265 en tiempo real no es lo suyo. El resultado: buffering infinito, artefactos, y Pascual diciendo "esto va como el culo".
Intentamos descargar el torrent directamente con aria2. Resultado: archivo de 5.3GB que parecia completo pero estaba corrupto. Preallocado pero vacio por dentro. Peerflix? Roto con Node 22. Webtorrent-cli? Eliminado de nixpkgs. El cliente desktop de Stremio? Depende de qtwebengine que nixpkgs marca como inseguro por CVEs.
Sabado por la noche y no pudimos ver la peli.
El domingo dijimos: se acabo el chapuceo. Vamos a montar esto bien.
El problema con Stremio (y servicios similares)
Stremio es genial como concepto: buscas una peli, le das play, y ya. Pero tiene problemas fundamentales cuando lo autoalojas:
- El web player depende del navegador. Si el codec no es compatible (HEVC, 10bit, HDR), no hay video. "Video not supported" es lo unico que ves.
- Transcodeo por software. Sin GPU, un servidor modesto no puede convertir 4K HEVC en tiempo real. Y con GPU, necesitas configurar VAAPI/NVENC que es otro mundo.
- El streaming server se muere. Dentro del container Docker, el proceso del puerto 11470 puede caer sin que nadie se entere. Nginx sigue sirviendo el frontend, tu crees que funciona, pero los streams dan 502.
- No hay gestion de biblioteca. Stremio es efimero: buscas, ves, se borra. No tienes una coleccion organizada.
La solucion no es arreglar Stremio. Es montar un sistema que separe las responsabilidades.
La arquitectura: 4 piezas, cada una hace una cosa
TU (movil/tablet/portatil/smart TV)
|
v
┌─────────────────┐
│ Jellyfin │ <- reproductor (Netflix UI)
│ :8096 │ sin transcodeo, direct play
└────────┬────────┘
|
lee archivos de
|
/storage/media/movies/
^
|
mueve aqui cuando
termina descarga
|
┌─────────────────┐
│ Radarr │ <- gestor de peliculas
│ :7878 │ busca, elige calidad, organiza
└────────┬────────┘
|
busca en descarga via
| |
┌────────v────────┐ ┌──────v──────────┐
│ Prowlarr │ │ Transmission │
│ :9696 │ │ :9091 │
│ (indexador) │ │ (cliente torrent)│
└─────────────────┘ └─────────────────┘
|
busca en sitios
(TPB, 1337x, etc.)
Jellyfin: el reproductor (puerto 8096)
Jellyfin es tu Netflix privado. Interfaz web bonita, apps para movil, smart TV, Fire Stick, Chromecast. Escanea tu carpeta de pelis, descarga caratulas, sinopsis, puntuaciones, y te lo presenta como un catalogo.
La clave: direct play. Jellyfin no transcodea si el dispositivo soporta el codec. Un navegador moderno con un mkv h264 1080p? Direct play. Cero CPU. El FX-8350 descansa.
Por eso descargamos en 1080p x264: compatible con todo sin transcodear.
Radarr: el gestor de peliculas (puerto 7878)
Radarr es el cerebro. Le dices "quiero Paprika" y el:
- Busca en todos los indexadores configurados (via Prowlarr)
- Filtra por calidad (1080p, x264, idioma)
- Elige la mejor release
- Manda el torrent a Transmission
- Cuando termina, renombra el archivo y lo mueve a la carpeta correcta
- Jellyfin detecta el archivo nuevo y lo anade a tu biblioteca
Tu no tocas nada. Buscas, click, y cuando esta listo aparece en Jellyfin.
Prowlarr: el indexador (puerto 9696)
Prowlarr busca en sitios de torrents por ti. Le configuras los indexadores una vez (The Pirate Bay, 1337x, RARBG, etc.) y Radarr busca a traves de el.
Sin Prowlarr tendrias que ir a cada web de torrents, buscar manualmente, copiar el magnet link, pegarlo en el cliente torrent… exactamente lo que Pascual decia que era "un poculoo". Prowlarr elimina todo eso.
Transmission: el cliente torrent (puerto 9091)
Transmission descarga. Punto. Es ligero, estable, y tiene web UI por
si quieres ver el progreso. Radarr le manda los torrents automaticamente
y el los descarga a /storage/media/downloads/. Cuando
termina, Radarr lo mueve a /storage/media/movies/.
Como fluye todo junto
Quieres ver Coco con el crio:
- Abres Radarr (
:7878), buscas "Coco", click en Add Movie - Radarr pregunta a Prowlarr: "oye, tienes Coco 2017 en 1080p?"
- Prowlarr busca en The Pirate Bay, encuentra 8 releases, se las pasa a Radarr
- Radarr elige la mejor (1080p Remux, audio castellano, 7.1), y le dice a Transmission: "descarga esto"
- Transmission descarga el torrent. Tarda lo que tarda tu conexion
- Cuando termina, Radarr mueve el archivo a
/storage/media/movies/Coco (2017)/, bien nombrado - Jellyfin detecta el archivo nuevo, descarga la caratula de TMDB, y lo anade al catalogo
- Abres Jellyfin (
:8096) en el movil/tablet/tele y le das play. Direct play, sin buffering
Total de clicks tuyos: 3 (buscar, anadir, play). El resto es automatico.
Por que esto es mejor que Stremio
| Stremio | Media Stack | |
|---|---|---|
| Buscar peli | En la app | En Radarr |
| Descarga | Streaming en tiempo real | Descarga completa primero |
| Calidad | Lo que pille el torrent | Tu eliges calidad y idioma |
| Codec problems | "video not supported" | Direct play, sin transcodeo |
| Biblioteca | No tiene, efimero | Jellyfin con caratulas y metadatos |
| Offline | No | Si, los archivos son tuyos |
| Multi-dispositivo | Solo web browser | Apps nativas (movil, TV, Fire Stick) |
| Fiabilidad | Streaming server se muere | 4 servicios independientes, cada uno reinicia solo |
La ventaja clave: los archivos son tuyos. Estan en tu disco. No dependes de que haya seeders en el momento que quieras ver la peli. Descargas una vez, ves cuando quieras, desde donde quieras.
La implementacion: un modulo NixOS
Todo el stack esta en un unico modulo NixOS: media-stack.nix. 107 lineas.
# En hosts/vespino/default.nix - esto es TODO lo que necesitas
dotfiles.media-stack = {
enable = true;
mediaPath = "/storage/media";
};Dos lineas. Eso levanta Jellyfin, Radarr, Prowlarr y Transmission,
crea los directorios con permisos correctos, configura el grupo
compartido media para que todos los
servicios se entiendan, y abre los puertos del firewall.
El modulo completo:
{ config, lib, pkgs, ... }:
let
cfg = config.dotfiles.media-stack;
in
{
options.dotfiles.media-stack = {
enable = lib.mkEnableOption "Media stack (Jellyfin + Radarr + Prowlarr + Transmission)";
mediaPath = lib.mkOption {
type = lib.types.str;
default = "/storage/media";
};
};
config = lib.mkIf cfg.enable {
services.jellyfin = { enable = true; openFirewall = true; };
services.radarr = { enable = true; openFirewall = true; };
services.prowlarr = { enable = true; openFirewall = true; };
services.transmission = {
enable = true;
package = pkgs.transmission_4;
openFirewall = true;
settings = {
download-dir = "${cfg.mediaPath}/downloads";
incomplete-dir = "${cfg.mediaPath}/downloads/.incomplete";
incomplete-dir-enabled = true;
rpc-bind-address = "0.0.0.0";
rpc-whitelist-enabled = false;
rpc-host-whitelist-enabled = false;
peer-port = 51413;
};
};
# Radarr sandboxed: necesita acceso explicito al storage
systemd.services.radarr.serviceConfig.ReadWritePaths = [ cfg.mediaPath ];
# Directorios con permisos correctos
systemd.tmpfiles.rules = [
"d ${cfg.mediaPath} 0775 root media -"
"d ${cfg.mediaPath}/movies 0775 radarr media -"
"d ${cfg.mediaPath}/downloads 0775 transmission media -"
"d ${cfg.mediaPath}/downloads/.incomplete 0775 transmission media -"
];
# Grupo compartido: todos los servicios leen/escriben
users.groups.media = {};
users.users.jellyfin.extraGroups = [ "media" ];
users.users.radarr.extraGroups = [ "media" ];
users.users.transmission.extraGroups = [ "media" ];
# Puertos web UI accesibles desde LAN
networking.firewall.allowedTCPPorts = [ 9091 7878 9696 ];
};
}Los bugs que encontramos
Porque nada funciona a la primera:
Transmission 3 eliminado: NixOS ya no tiene
transmission_3. Hay que ponerpackage = pkgs.transmission_4explicito.Radarr no ve /storage: Systemd sandboxea Radarr con
ProtectHomey namespaces. SinReadWritePaths = [ "/storage/media" ]Radarr no puede leer ni escribir fuera de su directorio.Transmission no arranca: El servicio falla si los directorios de descarga no existen.
systemd.tmpfiles.ruleslos crea automaticamente, pero en el primer rebuild los tmpfiles se ejecutan despues del servicio. Solucion: crear los directorios a mano la primera vez o reiniciar.Transmission rechaza conexiones remotas:
rpc-host-whitelist-enabledesta atruepor defecto. Desde otro PC de la LAN el hostname no coincide y devuelve 409. Hay que desactivarlo.openFirewall miente:
services.transmission.openFirewallsolo abre el peer port (51413), NO el puerto RPC (9091). Igual con Radarr y Prowlarr. Hay que abrir 9091, 7878 y 9696 manualmente en el firewall.
Configuracion inicial (una sola vez)
Despues del rebuild, los 4 servicios arrancan pero no se conocen entre si. Hay que presentarlos:
1. Jellyfin (:8096)
- Crear cuenta admin
- Add Media Library → Movies →
/storage/media/movies
2. Prowlarr (:9696)
- Add Indexer → The Pirate Bay (o el que prefieras)
- Settings → Apps → Add → Radarr
- Radarr Server:
http://localhost:7878 - API Key: (la copias de Radarr → Settings → General)
- Radarr Server:
3. Radarr (:7878)
- Settings → Download Clients → Add → Transmission
- Host:
localhost, Port:9091
- Host:
- Settings → Quality Profiles → seleccionar 1080p (evita 4K si no tienes GPU)
4. Buscar tu primera peli
- Radarr → Add New → buscar → Add Movie → Search
- Ver progreso en Transmission (:9091)
- Cuando termina: aparece en Jellyfin
El resultado
175 peliculas que teniamos desperdigadas en ~/Downloads/peliculicas/ ahora estan organizadas
en Jellyfin con caratulas, sinopsis, puntuaciones y busqueda. Paprika y
Coco descargandose automaticamente. El crio puede elegir peli desde la
tablet.
Todo declarativo. Si vespino explota manana, dos lineas en el nuevo servidor y el stack vuelve a estar operativo. Solo hay que reconfigurar los indexadores y reconectar las piezas (5 minutos).
Y lo mejor: cero "video not supported".
Para el futuro
- Sonarr: lo mismo que Radarr pero para series. Mismo patron, anadir al modulo
- Bazarr: descarga subtitulos automaticamente. Para cuando la release no trae castellano
- Jellyseerr: interfaz bonita para que la familia pida pelis sin tocar Radarr
- GPU passthrough: si algun dia vespino tiene una GT 1030, Jellyfin puede transcodear con VAAPI para streams que necesiten conversion
- Acceso externo: Jellyfin via Cloudflare Tunnel para ver pelis fuera de casa
Pero eso ya sera otra tarde de sabado. Hoy toca ver Paprika.
Comentarios (1)
Deja un comentario