O teu servidor Jellyfin na TV da sala, com a cara e o jeito da Netflix.
Cliente para Android TV escrito de raiz em Kotlin e Compose for TV.
Projeto pessoal, feito para a TV da sala. Funciona todos os dias — com uma biblioteca de 206 filmes, 71 séries e 2441 episódios —, mas é uma app de uso próprio: não está na Play Store, instala-se pelo APK e foi testada num servidor e num punhado de televisores, não em todos.
As imagens são capturas da própria interface da app, geradas em testes com metadados e capas reais do servidor do autor. As capas pertencem aos respetivos detentores.
Navegar como na Netflix. Menu superior com as secções, destaque que roda sozinho e toca o trailer, cartões 16:9 que abrem com o foco e mostram o preview lá dentro, Top 10 numerado, «Reproduzir algo», A minha lista e grelha por género. Os menus, os teclados no ecrã e o comportamento do Back seguem o que se espera numa TV — nenhum clique se perde e a primeira tecla nunca é gasta só a tirar o foco de um grupo.
Um leitor que aguenta a biblioteca toda. Reprodução direta sempre que a TV consegue, conversão no servidor só quando é mesmo preciso, e o FFmpeg a tratar do áudio que a TV não descodifica (DTS, TrueHD…). Passthrough por HDMI quando o recetor trata do som, com opção para o desligar e ter sempre volume ajustável. A qualidade baixa sozinha quando a ligação não aguenta, em vez de o vídeo ficar aos soluços, e o buffer é dimensionado à memória da TV para um ficheiro de 19 GB não a rebentar.
Saltar introduções, resumos e créditos. Lê os Media Segments do servidor, os endpoints do plugin Intro Skipper, o TheIntroDB e os capítulos do próprio ficheiro — e, sem nada disso, ainda oferece um salto estimado nos primeiros minutos de um episódio. Pode saltar sozinho, e o cartão do próximo episódio aparece nos créditos.
Trailers dentro da app. O trailer do YouTube toca no leitor, com o som original e sem sair da app, em vez de abrir outra aplicação e perder o comando.
TV em Direto. Canais com logótipo numa linha de cartões, destaque do canal focado com o programa a dar agora e a programação do dia ao lado.
Controlo remoto pelos outros clientes. A app móvel ou a web do Jellyfin podem mandar reproduzir, pausar, parar e saltar nesta TV, pelo WebSocket do próprio servidor (nada de Cast nem DLNA).
Ver em grupo e à distância. «Reproduzir aqui» a partir do telemóvel, lista de sessões abertas no servidor e SyncPlay para ver o mesmo título, ao mesmo tempo, com outros ecrãs. Velocidade de reprodução de 0,75× a 2×, áudio e legendas lembrados por série e, opcional, a TV a mudar para a cadência do vídeo (24p/25p).
Perfis com PIN. Um PIN numérico opcional por perfil, guardado só na TV, com teclado só de números, bloqueio depois de tentativas erradas e «Esqueci-me do PIN».
Em português e inglês, conforme a língua da TV.
Mais formas de descobrir. Géneros, estúdios, coleções e a lista «Para ver juntos», tudo no mesmo menu.
E ainda: Quick Connect, pesquisa com géneros, pessoas e voz, legendas embutidas e PGS em reprodução direta, «Ainda estás a ver?», estatísticas para nerds no leitor, proteção de ecrã, descoberta do servidor na rede local, «Continuar a ver» no ecrã inicial da TV, géneros com nomes repetidos juntos num só e atualizações automáticas.
- Servidor Jellyfin 12.0 ou mais recente.
- Android TV 6.0 (API 23) ou mais recente — TVs, caixas e sticks. É uma app de TV (leanback), não serve para telemóveis.
- Descarrega o APK da última release.
- Passa-o para a TV — por exemplo com o Downloader, com o
adb install -r jellyflix-<versão>.apk, ou por uma pen. - Abre a app, escolhe o servidor (a app procura-o na rede) e entra com o teu utilizador.
A partir daí a app avisa-te das versões novas ao arrancar e instala-as sozinha, desde que o APK novo esteja assinado com a mesma chave. Também podes procurar à mão em Definições › Procurar atualizações.
Kotlin · Compose for TV (androidx.tv:tv-material) · Navigation3 · Hilt · Jellyfin SDK Kotlin
1.9 · Media3/ExoPlayer com NextLib (FFmpeg) · Coil 3 · Room e DataStore.
O botão aparece quando se sabe onde estão esses segmentos. A app procura, por esta ordem:
- Media Segments do servidor — instala o plugin Intro Skipper
(repositório
https://raw.githubusercontent.com/intro-skipper/manifest/main/12/manifest.jsonpara o Jellyfin 12) e corre as tarefas agendadas Detect Intros e Media Segment Scan; - endpoints antigos do Intro Skipper;
- TheIntroDB, pelo ID do TMDB (ligado por omissão; desliga-se em Definições › Este televisor);
- capítulos do ficheiro, com nomes como «Intro», «Opening», «Recap» ou «Credits»;
- sem nada disto, um salto estimado nos primeiros minutos do episódio (nunca automático — é um palpite).
Em Estatísticas, dentro do leitor, vê-se o que cada fonte deu («plugin não instalado», «sem ID do TMDB», …).
A app fala sobretudo com o teu servidor Jellyfin. Fora dele: o TheIntroDB recebe o ID do TMDB do que vês, para saber onde está a introdução (desliga-se nas Definições); o YouTube recebe o pedido do trailer; o GitHub recebe a procura de versões novas (também se desliga). Sem publicidade, sem estatísticas de uso e sem contas de terceiros. As licenças dos componentes de código aberto estão em Definições › Licenças de código aberto.
Abre uma issue com a versão (Definições › Sobre), o modelo da TV e o que aconteceu. Se a app fechou sozinha, no arranque seguinte aparece um ecrã com o erro: uma fotografia dele ajuda muito.
Obrigado ao Jellyfin e a quem mantém o SDK, ao Media3, ao NextLib e ao NewPipeExtractor (trailers do YouTube dentro da app).
Projeto pessoal, sem qualquer ligação ao Jellyfin nem à Netflix. «Netflix» é uma marca registada da Netflix, Inc., usada aqui apenas para descrever a inspiração da interface.




