📡

Validação EPG IPTV/M3U Extended

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:

  1. Streams de rádio adicionais (descoberta automática)
  2. Metadata (logos, nomes, categorias)
  3. 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

2. IPTV-ORG Portugal

3. IPTV-ORG Brasil


✅ Pontos Fortes

1. Metadata Excelente

2. Cobertura Global

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


❌ Limitações Críticas

1. **Foco em TV, não Rádio**

2. **Nenhum EPG Disponível para Rádios**

3. **Streams Podem Estar Offline**

4. **Duplicação com Fontes Existentes**


🔬 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ê?

  1. Descoberta de streams novos/alternativos
  2. Enriquecimento de logos (URLs de alta qualidade)
  3. Fallback URLs para rádios existentes
  4. Identificação de rádios por tvg-id

Como?

❌ NÃO Implementar

EPG via XMLTV

Como fonte primária de rádios


🏗️ 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)

Fase 5.2: Ingestão Básica (2 dias)

Fase 5.3: Matching Inteligente (2 dias)

Fase 5.4: Fallback URLs (1 dia)

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)

Validação de Streams


🔍 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

🎯 Próximos Passos

  1. Priorizar Fase 3 (User-Submitted EPG) - alto valor, baixo esforço
  2. Considerar Fase 2 (Scraping sites oficiais) - alto valor, alto esforço
  3. Implementar Fase 5 depois - complementar, valor marginal

💬 Feedback do Teste


Última Atualização: 24 de dezembro de 2025
Autor: Audissey Development Team
Script de Teste: /apps/api/src/scripts/test-iptv-m3u.ts