Fase 5: IPTV/M3U Extended Info - Análise de Viabilidade
📋 Resumo Executivo
Data do Teste: 24 de dezembro de 2025
Fonte: iptv-org/iptv + iptv-org/epg
Status: ⚠️ VIABILIDADE MÉDIA - Útil como fonte complementar, mas não primária para rádios
Decisão: Implementar como fonte secundária para descoberta de streams + logos
🎯 Objetivo da Fase 5
Avaliar a viabilidade de usar playlists M3U públicas (IPTV) como fonte de:
- Streams de rádio adicionais (descoberta automática)
- Metadata (logos, nomes, categorias)
- EPG (guias de programação via XMLTV)
📊 Resultados dos Testes
Estatísticas Gerais
| Métrica | Valor | Percentagem |
|---|---|---|
| Total de Streams | 877 | 100% |
| Streams de Rádio | 134 | 15.3% |
| Com tvg-id | 877 | 100% ✅ |
| Com Logo | 868 | 98.9% ✅ |
| Playlists com EPG | 0/3 | 0% ❌ |
Breakdown por Playlist
1. IPTV-ORG Music/Radio Global
- URL:
https://iptv-org.github.io/iptv/categories/music.m3u - Total: 629 streams
- Rádios: 122 (19.4%)
- tvg-id: 100%
- Logos: 98.6%
2. IPTV-ORG Portugal
- URL:
https://iptv-org.github.io/iptv/countries/pt.m3u - Total: 42 streams
- Rádios: 5 (11.9%)
- tvg-id: 100%
- Logos: 100%
- Exemplos:
- NPC Radio e TV
- ON FM
- Rádio Sines
- ARTV Canal Parlamento
- Famatv
3. IPTV-ORG Brasil
- URL:
https://iptv-org.github.io/iptv/countries/br.m3u - Total: 206 streams
- Rádios: 7 (3.4%)
- tvg-id: 100%
- Logos: 100%
- Exemplos:
- Amazon Sat
- Catve FM
- CWB TV
✅ Pontos Fortes
1. Metadata Excelente
- 100% dos streams têm tvg-id (identificador único)
- ~99% têm logo em alta qualidade
- Categorização via
group-title(país, idioma) - Nomes padronizados e limpos
2. Cobertura Global
- 122 rádios internacionais na categoria Music
- Cobertura de múltiplos países (PT, BR, IT, UK, US, etc)
- Playlists organizadas por:
- País (
/countries/pt.m3u) - Categoria (
/categories/music.m3u) - Idioma
- País (
3. Formato Padronizado (M3U Extended)
#EXTM3U
#EXTINF:-1 tvg-id="ONFM.pt@SD" tvg-logo="https://..." group-title="Portugal",ON FM (720p)
https://5ce9406b73c33.streamlock.net/ONFM/livestream/playlist.m3u8
4. Manutenção Ativa
- Repositório com 107k stars
- Atualizado continuamente (bot iptv-bot)
- Comunidade ativa (372 contributors)
❌ Limitações Críticas
1. **Foco em TV, não Rádio**
- Apenas 15.3% são rádios (maioria é TV)
- Cobertura de rádio inconsistente entre países
- Prioridade do projeto é IPTV/TV
2. **Nenhum EPG Disponível para Rádios**
- ❌ 0 playlists com EPG nos testes
- Repositório iptv-org/epg existe, mas:
- Foco em TV channels
- EPG/XMLTV não inclui rádios na maioria dos casos
- Sites scraped são de TV guides (não rádio)
3. **Streams Podem Estar Offline**
- Muitos streams marcados
[Not 24/7] - Alguns
[Geo-blocked] - Sem garantia de estabilidade dos links
- Necessário validação regular
4. **Duplicação com Fontes Existentes**
- Rádios já presentes no MyTuner/TuneIn
- Pouca adição de valor em termos de EPG
- Sobreposição com fontes já implementadas
🔬 Comparação com Outras Fontes
| Fonte | Rádios PT/BR | EPG Disponível | Metadata | Estabilidade |
|---|---|---|---|---|
| MyTuner (Fase atual) | ✅ Alta | ⚠️ Parcial | ✅ Bom | ✅ Alta |
| ICY Patterns (Fases 1-4) | ✅ Todas | ✅ Gerado | ⚠️ Capturado | ✅ Alta |
| User-Submitted (Fase 3) | ✅ Todas | ✅ Completo | ✅ Completo | ✅ Alta |
| IPTV/M3U (Fase 5) | ⚠️ Baixa (12 rádios PT/BR) | ❌ Inexistente | ✅ Excelente | ⚠️ Variável |
💡 Recomendações
✅ Implementar (Prioridade Baixa)
Para quê?
- Descoberta de streams novos/alternativos
- Enriquecimento de logos (URLs de alta qualidade)
- Fallback URLs para rádios existentes
- Identificação de rádios por tvg-id
Como?
- Ingestão semanal (não diária)
- Apenas categoria Music + países PT/BR
- Matching inteligente com rádios existentes (nome + país)
- Validação de streams antes de adicionar
- Atualização de logos quando melhor qualidade
❌ NÃO Implementar
EPG via XMLTV
- Inexistente para rádios nos testes
- Foco do iptv-org/epg é TV
- Melhor usar ICY Patterns (Fases 1-4)
Como fonte primária de rádios
- Cobertura de rádio muito baixa (<15%)
- Melhor usar MyTuner como primária
🏗️ Arquitetura de Implementação (Sugerida)
1. Parser M3U Extended
interface M3UStream {
name: string; // "ON FM (720p)"
url: string; // "https://..."
tvgId: string; // "ONFM.pt@SD"
tvgLogo: string; // "https://..."
groupTitle: string; // "Portugal"
country?: string; // "PT"
language?: string; // "pt"
}
function parseM3U(content: string): M3UStream[] {
// Implementação no teste
}
2. Serviço de Ingestão
@Injectable()
export class IptvIngestService {
@Cron(CronExpression.EVERY_WEEK)
async ingestPlaylists() {
const playlists = [
'https://iptv-org.github.io/iptv/categories/music.m3u',
'https://iptv-org.github.io/iptv/countries/pt.m3u',
'https://iptv-org.github.io/iptv/countries/br.m3u',
];
for (const url of playlists) {
const streams = await this.fetchAndParse(url);
const radioStreams = this.filterRadioStreams(streams);
for (const stream of radioStreams) {
await this.processStream(stream);
}
}
}
private async processStream(stream: M3UStream) {
// 1. Validar stream (HTTP HEAD request)
const isValid = await this.validateStream(stream.url);
if (!isValid) return;
// 2. Tentar match com rádio existente
const existingRadio = await this.findMatchingRadio(stream);
if (existingRadio) {
// 3a. Atualizar logo se melhor qualidade
await this.updateLogoIfBetter(existingRadio, stream.tvgLogo);
// 3b. Adicionar URL alternativa
await this.addFallbackUrl(existingRadio, stream.url);
} else {
// 4. Criar nova rádio
await this.createRadioFromStream(stream);
}
}
private async findMatchingRadio(stream: M3UStream): Promise<Radio | null> {
// Match por nome + país usando Levenshtein
const country = this.extractCountry(stream.groupTitle);
const cleanName = this.cleanRadioName(stream.name);
return await this.radioModel.findOne({
country,
$or: [
{ name: { $regex: cleanName, $options: 'i' } },
{ iptv_tvg_id: stream.tvgId },
],
});
}
}
3. Extensão do Schema Radio
@Schema()
export class Radio {
// ... campos existentes
@Prop()
iptv_tvg_id?: string; // Mapeamento para tvg-id
@Prop()
iptv_logo_url?: string; // Logo de alta qualidade
@Prop([String])
fallback_urls?: string[]; // URLs alternativas
@Prop()
iptv_last_validated?: Date; // Última validação do stream
}
📈 Roadmap de Implementação
Fase 5.1: Parser M3U (1 dia)
- Script de teste (já criado)
- Parser reutilizável
- Testes unitários
Fase 5.2: Ingestão Básica (2 dias)
- Serviço de ingestão semanal
- Validação de streams
- Deduplicação
Fase 5.3: Matching Inteligente (2 dias)
- Algoritmo de match por nome + país
- Mapeamento tvg-id ↔ Radio
- Atualização de logos
Fase 5.4: Fallback URLs (1 dia)
- Array de URLs alternativas
- Rotação automática em caso de falha
- Health check periódico
Total Estimado: 6 dias de desenvolvimento
📊 Priorização vs Outras Fases
| Fase | Prioridade | Valor para EPG | Esforço |
|---|---|---|---|
| Fase 1-4: ICY Patterns | 🔴 ALTA | ✅ Alto (EPG gerado) | Médio (6 dias) ✅ COMPLETO |
| Fase 3: User-Submitted | 🔴 ALTA | ✅ Máximo (dados reais) | Baixo (2 dias) |
| Fase 2: Scraping RTP/etc | 🟡 MÉDIA | ✅ Alto (oficial) | Alto (10 dias) |
| Fase 5: IPTV/M3U | 🟢 BAIXA | ❌ Nulo (sem EPG) | Médio (6 dias) |
Recomendação: Implementar Fase 3 (User-Submitted) antes da Fase 5.
🎓 Recursos Técnicos
Formato M3U Extended
Parsers Existentes (NPM)
m3u-parser- Simple M3U parseriptv-playlist-parser- Extended M3U parserxmltv- XMLTV/EPG parser
Validação de Streams
axios- HTTP requests (HEAD)ffprobe- Stream inspectionhls-parser- HLS playlist validation
🔍 Exemplos de Streams Encontrados
Portugal (5 rádios)
#EXTINF:-1 tvg-id="ONFM.pt@SD" tvg-logo="https://onfmwordpressfiles.ams3.digitaloceanspaces.com/2019/11/LOGO-ON-FM-2.png",ON FM (720p)
https://5ce9406b73c33.streamlock.net/ONFM/livestream/playlist.m3u8
#EXTINF:-1 tvg-id="NPCRadioeTV.pt@SD" tvg-logo="https://i.imgur.com/mw1lYWE.png",NPC Radio e TV (720p)
https://stmv1.srvif.com/npc/npc/playlist.m3u8
#EXTINF:-1 tvg-id="RadioSines.pt@SD" tvg-logo="https://i.imgur.com/Oe6F1nL.png",Rádio Sines (720p) [Geo-blocked]
https://load-balancer.azotosolutions.com/cdnedge19/smil:live-stream-name-20180.smil/playlist.m3u8
Brasil (7 rádios)
#EXTINF:-1 tvg-id="AmazonSat.br@SD" tvg-logo="https://i.imgur.com/7rjCS5i.png",Amazon Sat (1080p)
https://amazonsat.brasilstream.com.br/hls/amazonsat/index.m3u8
#EXTINF:-1 tvg-id="CatveFM.br@SD" tvg-logo="https://i.imgur.com/w89yw36.png",Catve FM (720p) [Not 24/7]
https://5b33b873179a2.streamlock.net:1443/radiocamera/livestream/playlist.m3u8
#EXTINF:-1 tvg-id="CWBTV.br@SD" tvg-logo="https://i.imgur.com/S0ISpmU.png",CWB TV (720p)
https://59d39900ebfb8.streamlock.net/cwbtv/cwbtv/playlist.m3u8
⚖️ Conclusão
✅ Viabilidade: MÉDIA
- Útil como fonte complementar para:
- Descoberta de streams alternativos
- Enriquecimento de metadata (logos)
- Fallback URLs
- NÃO útil para:
- EPG/guias de programação (inexistente para rádios)
- Fonte primária de rádios (cobertura baixa)
🎯 Próximos Passos
- Priorizar Fase 3 (User-Submitted EPG) - alto valor, baixo esforço
- Considerar Fase 2 (Scraping sites oficiais) - alto valor, alto esforço
- Implementar Fase 5 depois - complementar, valor marginal
💬 Feedback do Teste
- Script de teste funcionou perfeitamente ✅
- Descobrimos 12 novas rádios PT/BR (5+7)
- Todos os streams têm metadata de qualidade
- Nenhum EPG/XMLTV disponível ❌
Última Atualização: 24 de dezembro de 2025
Autor: Audissey Development Team
Script de Teste: /apps/api/src/scripts/test-iptv-m3u.ts