[Pitch] Streamlite: Desafios técnicos
Olá, pessoal!
Gostaria de compartilhar os bastidores, desafios técnicos e decisões de arquitetura que enfrentei criando o StreamLite, um media player nativo para Android focado em reprodução de streams públicos (HLS/M3U8).
Ao final, compartilho também um convite para quem puder me apoiar nos testes fechados exigidos pelo Google.
-
A Motivação: Por que criar outro player?
A maioria dos aplicativos de reprodução de listas M3U na Play Store sofre de problemas crônicos:
Interfaces pesadas, poluídas ou construídas com WebViews lentas.
Alto consumo de memória e travamentos ao carregar listas com mais de 10.000 entradas.
Excesso de anúncios invasivos e código de procedência duvidosa.
Meu objetivo foi criar uma solução 100% nativa, leve, com foco em ergonomia de uso, inicialização rápida de stream e estrita separação entre a ferramenta (o player) e os dados (as playlists do próprio usuário). -
O Stack Tecnológico e Desafios de Engenharia
O projeto foi desenvolvido em Kotlin, utilizando Jetpack Compose para a interface e AndroidX Media3 (ExoPlayer) como motor de reprodução. Alguns desafios interessantes do processo:
a) Parsing assíncrono de playlists massivas
Uma lista M3U pública (como a do repositório aberto iptv-org) pode conter mais de 30 mil canais e dezenas de megabytes de texto.
O problema: Fazer split de strings em memória ou carregar tudo de uma vez causava OutOfMemoryError em aparelhos intermediários.
A solução: Implementei um parser baseado em stream contínuo (buffered reader line-by-line) usando Coroutines e Kotlin Flow. Os itens são processados em lotes e persistidos localmente via Room com suporte a FTS (Full-Text Search), permitindo busca instantânea por categoria/nome sem bloquear a UI thread.
b) Estabilidade de buffers em streams HLS/DASH
Streams ao vivo frequentemente sofrem com instabilidade de rede ou variações de bitrate. Utilizando o Media3, fiz ajustes finos nas configurações do DefaultLoadControl:
Configuração dinâmica de buffer mínimo e máximo para evitar pausas excessivas ao alternar canais (fast channel switching).
Tratamento de falhas de conexão com retry backoff exponencial sem congelar o player.
c) Interface fluida com Jetpack Compose
Renderizar listas longas exige cuidado redobrado no Compose para evitar recomposições desnecessárias. O uso de LazyColumn com chaves estáveis (key = { channel.id }), classes imutáveis anotadas com @Immutable e imagens/logos carregados sob demanda com Coil fizeram a rolagem manter 60/120 fps constantes. -
Sobre a conformidade e legalidade
O StreamLite é exclusivamente um reprodutor de mídia, não hospeda, não fornece e não incentiva o uso de conteúdo protegido por direitos autorais. Para testes, utilizo a lista global e aberta do projeto iptv-org, que agrega apenas transmissões públicas e abertas pelo mundo. -
O Pitch e o desafio dos 14 dias da Play Store
Como desenvolvedor solo, um dos maiores obstáculos recentes da Google Play Store é a política que exige no mínimo 20 testadores mantendo o aplicativo instalado por 14 dias contínuos antes de autorizar o lançamento público em produção.
Se você tiver interesse em testar um player leve e quiser me ajudar a superar essa barreira de homologação:
Acesse o Grupo de Testadores:
👉 Google Groups: Streamlite Testers (requisito da Play Store para dar permissão de download aos testadores) https://groups.google.com/g/streamlite-testers
Aceite o convite no programa de testes:
👉 Participar do teste na Google Play https://play.google.com/apps/testing/dev.vmellos.streamlite
Instale pela Play Store:
👉 Download no Google Play https://play.google.com/store/apps/details?id=dev.vmellos.streamlite
Como forma de agradecimento à comunidade:
O aplicativo já conta com 7 dias de acesso PRO liberados para teste. Para os membros que participarem ativamente e mantiverem o app durante o ciclo de 14 dias, liberarei uma chave de 1 ano de acesso PRO gratuito.
Feedbacks sobre usabilidade, desempenho em diferentes aparelhos, bugs no player ou sugestões de arquitetura são muito bem-vindos nos comentários!