mirror of https://github.com/iptv-org/iptv
commit
ac5a955d19
@ -1,53 +1,61 @@
|
|||||||
import { Generator } from './generator'
|
import { Generator } from './generator'
|
||||||
import { Collection, Storage, Logger } from '@freearhey/core'
|
import { Collection, Storage, Logger } from '@freearhey/core'
|
||||||
import { Playlist, Subdivision, Region } from '../models'
|
import { Playlist, Region, Stream } from '../models'
|
||||||
import { PUBLIC_DIR } from '../constants'
|
import { PUBLIC_DIR } from '../constants'
|
||||||
|
|
||||||
type RegionsGeneratorProps = {
|
type RegionsGeneratorProps = {
|
||||||
streams: Collection
|
streams: Collection
|
||||||
regions: Collection
|
regions: Collection
|
||||||
subdivisions: Collection
|
|
||||||
logger: Logger
|
logger: Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RegionsGenerator implements Generator {
|
export class RegionsGenerator implements Generator {
|
||||||
streams: Collection
|
streams: Collection
|
||||||
regions: Collection
|
regions: Collection
|
||||||
subdivisions: Collection
|
|
||||||
storage: Storage
|
storage: Storage
|
||||||
logger: Logger
|
logger: Logger
|
||||||
|
|
||||||
constructor({ streams, regions, subdivisions, logger }: RegionsGeneratorProps) {
|
constructor({ streams, regions, logger }: RegionsGeneratorProps) {
|
||||||
this.streams = streams
|
this.streams = streams
|
||||||
this.regions = regions
|
this.regions = regions
|
||||||
this.subdivisions = subdivisions
|
|
||||||
this.storage = new Storage(PUBLIC_DIR)
|
this.storage = new Storage(PUBLIC_DIR)
|
||||||
this.logger = logger
|
this.logger = logger
|
||||||
}
|
}
|
||||||
|
|
||||||
async generate(): Promise<void> {
|
async generate(): Promise<void> {
|
||||||
const streams = this.streams
|
const streams = this.streams
|
||||||
.orderBy(stream => stream.getTitle())
|
.orderBy((stream: Stream) => stream.getTitle())
|
||||||
.filter(stream => stream.isSFW())
|
.filter((stream: Stream) => stream.isSFW())
|
||||||
|
|
||||||
this.regions.forEach(async (region: Region) => {
|
this.regions.forEach(async (region: Region) => {
|
||||||
if (region.code === 'INT') return
|
if (region.isWorldwide()) return
|
||||||
|
|
||||||
const regionSubdivisionsCodes = this.subdivisions
|
const regionStreams = streams.filter((stream: Stream) => stream.isBroadcastInRegion(region))
|
||||||
.filter((subdivision: Subdivision) => region.countries.indexOf(subdivision.country) > -1)
|
|
||||||
.map((subdivision: Subdivision) => `s/${subdivision.code}`)
|
|
||||||
|
|
||||||
const regionCodes = region.countries
|
|
||||||
.map((code: string) => `c/${code}`)
|
|
||||||
.concat(regionSubdivisionsCodes)
|
|
||||||
.add(`r/${region.code}`)
|
|
||||||
|
|
||||||
const regionStreams = streams.filter(stream => stream.broadcastArea.intersects(regionCodes))
|
|
||||||
|
|
||||||
const playlist = new Playlist(regionStreams, { public: true })
|
const playlist = new Playlist(regionStreams, { public: true })
|
||||||
const filepath = `regions/${region.code.toLowerCase()}.m3u`
|
const filepath = `regions/${region.code.toLowerCase()}.m3u`
|
||||||
await this.storage.save(filepath, playlist.toString())
|
await this.storage.save(filepath, playlist.toString())
|
||||||
this.logger.info(JSON.stringify({ filepath, count: playlist.streams.count() }))
|
this.logger.info(
|
||||||
|
JSON.stringify({ type: 'region', filepath, count: playlist.streams.count() })
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const internationalStreams = streams.filter((stream: Stream) => stream.isInternational())
|
||||||
|
const internationalPlaylist = new Playlist(internationalStreams, { public: true })
|
||||||
|
const internationalFilepath = 'regions/int.m3u'
|
||||||
|
await this.storage.save(internationalFilepath, internationalPlaylist.toString())
|
||||||
|
this.logger.info(
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'region',
|
||||||
|
filepath: internationalFilepath,
|
||||||
|
count: internationalPlaylist.streams.count()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const undefinedStreams = streams.filter((stream: Stream) => !stream.hasBroadcastArea())
|
||||||
|
const playlist = new Playlist(undefinedStreams, { public: true })
|
||||||
|
const filepath = 'regions/undefined.m3u'
|
||||||
|
await this.storage.save(filepath, playlist.toString())
|
||||||
|
this.logger.info(JSON.stringify({ type: 'region', filepath, count: playlist.streams.count() }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
type BroadcastAreaProps = {
|
||||||
|
code: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BroadcastArea {
|
||||||
|
code: string
|
||||||
|
|
||||||
|
constructor(data: BroadcastAreaProps) {
|
||||||
|
this.code = data.code
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,58 @@
|
|||||||
type CountryProps = {
|
import { Collection, Dictionary } from '@freearhey/core'
|
||||||
|
import { Region, Language } from '.'
|
||||||
|
|
||||||
|
type CountryData = {
|
||||||
code: string
|
code: string
|
||||||
name: string
|
name: string
|
||||||
languages: string[]
|
lang: string
|
||||||
flag: string
|
flag: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Country {
|
export class Country {
|
||||||
code: string
|
code: string
|
||||||
name: string
|
name: string
|
||||||
languages: string[]
|
|
||||||
flag: string
|
flag: string
|
||||||
|
languageCode: string
|
||||||
|
language?: Language
|
||||||
|
subdivisions?: Collection
|
||||||
|
regions?: Collection
|
||||||
|
|
||||||
|
constructor(data: CountryData) {
|
||||||
|
this.code = data.code
|
||||||
|
this.name = data.name
|
||||||
|
this.flag = data.flag
|
||||||
|
this.languageCode = data.lang
|
||||||
|
}
|
||||||
|
|
||||||
|
withSubdivisions(subdivisionsGroupedByCountryCode: Dictionary): this {
|
||||||
|
this.subdivisions = subdivisionsGroupedByCountryCode.get(this.code) || new Collection()
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withRegions(regions: Collection): this {
|
||||||
|
this.regions = regions.filter(
|
||||||
|
(region: Region) => region.code !== 'INT' && region.includesCountryCode(this.code)
|
||||||
|
)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withLanguage(languagesGroupedByCode: Dictionary): this {
|
||||||
|
this.language = languagesGroupedByCode.get(this.languageCode)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
getLanguage(): Language | undefined {
|
||||||
|
return this.language
|
||||||
|
}
|
||||||
|
|
||||||
|
getRegions(): Collection {
|
||||||
|
return this.regions || new Collection()
|
||||||
|
}
|
||||||
|
|
||||||
constructor({ code, name, languages, flag }: CountryProps) {
|
getSubdivisions(): Collection {
|
||||||
this.code = code
|
return this.subdivisions || new Collection()
|
||||||
this.name = name
|
|
||||||
this.languages = languages
|
|
||||||
this.flag = flag
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,200 @@
|
|||||||
|
import { Collection, Dictionary } from '@freearhey/core'
|
||||||
|
import { Country, Language, Region, Channel, Subdivision } from './index'
|
||||||
|
|
||||||
|
type FeedData = {
|
||||||
|
channel: string
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
is_main: boolean
|
||||||
|
broadcast_area: Collection
|
||||||
|
languages: Collection
|
||||||
|
timezones: Collection
|
||||||
|
video_format: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Feed {
|
||||||
|
channelId: string
|
||||||
|
channel?: Channel
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
isMain: boolean
|
||||||
|
broadcastAreaCodes: Collection
|
||||||
|
broadcastCountryCodes: Collection
|
||||||
|
broadcastCountries?: Collection
|
||||||
|
broadcastRegionCodes: Collection
|
||||||
|
broadcastRegions?: Collection
|
||||||
|
broadcastSubdivisionCodes: Collection
|
||||||
|
broadcastSubdivisions?: Collection
|
||||||
|
languageCodes: Collection
|
||||||
|
languages?: Collection
|
||||||
|
timezoneIds: Collection
|
||||||
|
timezones?: Collection
|
||||||
|
videoFormat: string
|
||||||
|
|
||||||
|
constructor(data: FeedData) {
|
||||||
|
this.channelId = data.channel
|
||||||
|
this.id = data.id
|
||||||
|
this.name = data.name
|
||||||
|
this.isMain = data.is_main
|
||||||
|
this.broadcastAreaCodes = new Collection(data.broadcast_area)
|
||||||
|
this.languageCodes = new Collection(data.languages)
|
||||||
|
this.timezoneIds = new Collection(data.timezones)
|
||||||
|
this.videoFormat = data.video_format
|
||||||
|
this.broadcastCountryCodes = new Collection()
|
||||||
|
this.broadcastRegionCodes = new Collection()
|
||||||
|
this.broadcastSubdivisionCodes = new Collection()
|
||||||
|
|
||||||
|
this.broadcastAreaCodes.forEach((areaCode: string) => {
|
||||||
|
const [type, code] = areaCode.split('/')
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'c':
|
||||||
|
this.broadcastCountryCodes.add(code)
|
||||||
|
break
|
||||||
|
case 'r':
|
||||||
|
this.broadcastRegionCodes.add(code)
|
||||||
|
break
|
||||||
|
case 's':
|
||||||
|
this.broadcastSubdivisionCodes.add(code)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
withChannel(channelsGroupedById: Dictionary): this {
|
||||||
|
this.channel = channelsGroupedById.get(this.channelId)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withLanguages(languagesGroupedByCode: Dictionary): this {
|
||||||
|
this.languages = this.languageCodes
|
||||||
|
.map((code: string) => languagesGroupedByCode.get(code))
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withTimezones(timezonesGroupedById: Dictionary): this {
|
||||||
|
this.timezones = this.timezoneIds
|
||||||
|
.map((id: string) => timezonesGroupedById.get(id))
|
||||||
|
.filter(Boolean)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withBroadcastSubdivisions(subdivisionsGroupedByCode: Dictionary): this {
|
||||||
|
this.broadcastSubdivisions = this.broadcastSubdivisionCodes.map((code: string) =>
|
||||||
|
subdivisionsGroupedByCode.get(code)
|
||||||
|
)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withBroadcastCountries(
|
||||||
|
countriesGroupedByCode: Dictionary,
|
||||||
|
regionsGroupedByCode: Dictionary,
|
||||||
|
subdivisionsGroupedByCode: Dictionary
|
||||||
|
): this {
|
||||||
|
let broadcastCountries = new Collection()
|
||||||
|
|
||||||
|
if (this.isInternational()) {
|
||||||
|
this.broadcastCountries = broadcastCountries
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
this.broadcastCountryCodes.forEach((code: string) => {
|
||||||
|
broadcastCountries.add(countriesGroupedByCode.get(code))
|
||||||
|
})
|
||||||
|
|
||||||
|
this.broadcastRegionCodes.forEach((code: string) => {
|
||||||
|
const region: Region = regionsGroupedByCode.get(code)
|
||||||
|
if (region) {
|
||||||
|
region.countryCodes.forEach((countryCode: string) => {
|
||||||
|
broadcastCountries.add(countriesGroupedByCode.get(countryCode))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.broadcastSubdivisionCodes.forEach((code: string) => {
|
||||||
|
const subdivision: Subdivision = subdivisionsGroupedByCode.get(code)
|
||||||
|
if (subdivision) {
|
||||||
|
broadcastCountries.add(countriesGroupedByCode.get(subdivision.countryCode))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.broadcastCountries = broadcastCountries.uniq().filter(Boolean)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
withBroadcastRegions(regions: Collection): this {
|
||||||
|
if (!this.broadcastCountries) return this
|
||||||
|
const countriesCodes = this.broadcastCountries.map((country: Country) => country.code)
|
||||||
|
|
||||||
|
this.broadcastRegions = regions.filter((region: Region) => {
|
||||||
|
if (region.code === 'INT') return false
|
||||||
|
|
||||||
|
return region.countryCodes.intersects(countriesCodes)
|
||||||
|
})
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
hasBroadcastArea(): boolean {
|
||||||
|
return (
|
||||||
|
this.isInternational() || (!!this.broadcastCountries && this.broadcastCountries.notEmpty())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getBroadcastCountries(): Collection {
|
||||||
|
return this.broadcastCountries || new Collection()
|
||||||
|
}
|
||||||
|
|
||||||
|
getBroadcastRegions(): Collection {
|
||||||
|
return this.broadcastRegions || new Collection()
|
||||||
|
}
|
||||||
|
|
||||||
|
getTimezones(): Collection {
|
||||||
|
return this.timezones || new Collection()
|
||||||
|
}
|
||||||
|
|
||||||
|
getLanguages(): Collection {
|
||||||
|
return this.languages || new Collection()
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLanguages(): boolean {
|
||||||
|
return !!this.languages && this.languages.notEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLanguage(language: Language): boolean {
|
||||||
|
return (
|
||||||
|
!!this.languages &&
|
||||||
|
this.languages.includes((_language: Language) => _language.code === language.code)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
isInternational(): boolean {
|
||||||
|
return this.broadcastAreaCodes.includes('r/INT')
|
||||||
|
}
|
||||||
|
|
||||||
|
isBroadcastInSubdivision(subdivision: Subdivision): boolean {
|
||||||
|
if (this.isInternational()) return false
|
||||||
|
|
||||||
|
return this.broadcastSubdivisionCodes.includes(subdivision.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
isBroadcastInCountry(country: Country): boolean {
|
||||||
|
if (this.isInternational()) return false
|
||||||
|
|
||||||
|
return this.getBroadcastCountries().includes(
|
||||||
|
(_country: Country) => _country.code === country.code
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
isBroadcastInRegion(region: Region): boolean {
|
||||||
|
if (this.isInternational()) return false
|
||||||
|
|
||||||
|
return this.getBroadcastRegions().includes((_region: Region) => _region.code === region.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import { Collection, Dictionary } from '@freearhey/core'
|
||||||
|
|
||||||
|
type TimezoneData = {
|
||||||
|
id: string
|
||||||
|
utc_offset: string
|
||||||
|
countries: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Timezone {
|
||||||
|
id: string
|
||||||
|
utcOffset: string
|
||||||
|
countryCodes: Collection
|
||||||
|
countries?: Collection
|
||||||
|
|
||||||
|
constructor(data: TimezoneData) {
|
||||||
|
this.id = data.id
|
||||||
|
this.utcOffset = data.utc_offset
|
||||||
|
this.countryCodes = new Collection(data.countries)
|
||||||
|
}
|
||||||
|
|
||||||
|
withCountries(countriesGroupedByCode: Dictionary): this {
|
||||||
|
this.countries = this.countryCodes.map((code: string) => countriesGroupedByCode.get(code))
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
getCountries(): Collection {
|
||||||
|
return this.countries || new Collection()
|
||||||
|
}
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
[{"channel":null,"url":"http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8","referrer":null,"user_agent":null},{"channel":null,"url":"http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8","referrer":"http://imn.iq","user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"},{"channel":"AndorraTV.ad","url":"https://iptv-all.lanesh4d0w.repl.co/andorra/atv","referrer":null,"user_agent":null},{"channel":"BBCNews.uk","url":"http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8","referrer":null,"user_agent":null},{"channel":"LDPRTV.ru","url":"http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8","referrer":null,"user_agent":null},{"channel":"MeteoMedia.ca","url":"http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8","referrer":null,"user_agent":null},{"channel":"VisitXTV.nl","url":"https://stream.visit-x.tv/vxtv/ngrp:live_all/30fps.m3u8","referrer":null,"user_agent":null},{"channel":"Zoo.ad","url":"https://iptv-all.lanesh4d0w.repl.co/andorra/zoo","referrer":null,"user_agent":null}]
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-logo="https://raw.githubusercontent.com/Tapiosinn/tv-logos/master/countries/united-kingdom/bbc-news-uk.png" group-title="General;News",BBC News HD
|
|
||||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
|
|
@ -1,11 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
|
||||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
|
||||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
|
||||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8
|
|
||||||
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-logo="" group-title="Undefined",ATV
|
|
||||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Daawah TV
|
|
||||||
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
|
|
||||||
#EXTINF:-1 tvg-id="Zoo.ad" tvg-logo="" group-title="Undefined",Zoo (720p)
|
|
||||||
https://iptv-all.lanesh4d0w.repl.co/andorra/zoo
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="VisitXTV.nl" tvg-logo="https://i.imgur.com/RJ9wbNF.jpg" group-title="XXX",Visit-X TV
|
|
||||||
https://stream.visit-x.tv/vxtv/ngrp:live_all/30fps.m3u8
|
|
@ -1,5 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="AndorraTV.ad" tvg-logo="" group-title="Undefined",ATV
|
|
||||||
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
|
|
||||||
#EXTINF:-1 tvg-id="Zoo.ad" tvg-logo="" group-title="Undefined",Zoo (720p)
|
|
||||||
https://iptv-all.lanesh4d0w.repl.co/andorra/zoo
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Daawah TV
|
|
||||||
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="BBCNews.uk" tvg-logo="https://raw.githubusercontent.com/Tapiosinn/tv-logos/master/countries/united-kingdom/bbc-news-uk.png" group-title="General;News",BBC News HD
|
|
||||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
|
|
@ -1,11 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined" http-referrer="http://imn.iq" http-user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",Andorra TV (720p) [Not 24/7]
|
|
||||||
#EXTVLCOPT:http-referrer=http://imn.iq
|
|
||||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
|
|
||||||
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Daawah TV
|
|
||||||
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
||||||
#EXTINF:-1 tvg-id="Zoo.ad" tvg-logo="" group-title="Undefined",Zoo (720p)
|
|
||||||
https://iptv-all.lanesh4d0w.repl.co/andorra/zoo
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Daawah TV
|
|
||||||
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="" tvg-logo="" group-title="Undefined",Daawah TV
|
|
||||||
http://51.15.246.58:8081/daawahtv/daawahtv2/playlist.m3u8
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1 +0,0 @@
|
|||||||
#EXTM3U
|
|
@ -1,3 +0,0 @@
|
|||||||
#EXTM3U
|
|
||||||
#EXTINF:-1 tvg-id="MeteoMedia.ca" tvg-logo="https://s1.twnmm.com/images/en_ca/mobile/logos/twn-mobile-logo.png" group-title="Weather",Meteomedia
|
|
||||||
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
|
|
@ -1,70 +0,0 @@
|
|||||||
{"filepath":"categories/auto.m3u","count":0}
|
|
||||||
{"filepath":"categories/animation.m3u","count":0}
|
|
||||||
{"filepath":"categories/business.m3u","count":0}
|
|
||||||
{"filepath":"categories/classic.m3u","count":0}
|
|
||||||
{"filepath":"categories/comedy.m3u","count":0}
|
|
||||||
{"filepath":"categories/cooking.m3u","count":0}
|
|
||||||
{"filepath":"categories/culture.m3u","count":0}
|
|
||||||
{"filepath":"categories/documentary.m3u","count":0}
|
|
||||||
{"filepath":"categories/education.m3u","count":0}
|
|
||||||
{"filepath":"categories/entertainment.m3u","count":0}
|
|
||||||
{"filepath":"categories/family.m3u","count":0}
|
|
||||||
{"filepath":"categories/general.m3u","count":2}
|
|
||||||
{"filepath":"categories/kids.m3u","count":0}
|
|
||||||
{"filepath":"categories/legislative.m3u","count":0}
|
|
||||||
{"filepath":"categories/lifestyle.m3u","count":0}
|
|
||||||
{"filepath":"categories/movies.m3u","count":0}
|
|
||||||
{"filepath":"categories/music.m3u","count":0}
|
|
||||||
{"filepath":"categories/news.m3u","count":1}
|
|
||||||
{"filepath":"categories/outdoor.m3u","count":0}
|
|
||||||
{"filepath":"categories/relax.m3u","count":0}
|
|
||||||
{"filepath":"categories/religious.m3u","count":0}
|
|
||||||
{"filepath":"categories/series.m3u","count":0}
|
|
||||||
{"filepath":"categories/science.m3u","count":0}
|
|
||||||
{"filepath":"categories/shop.m3u","count":0}
|
|
||||||
{"filepath":"categories/sports.m3u","count":0}
|
|
||||||
{"filepath":"categories/travel.m3u","count":0}
|
|
||||||
{"filepath":"categories/weather.m3u","count":1}
|
|
||||||
{"filepath":"categories/xxx.m3u","count":1}
|
|
||||||
{"filepath":"categories/undefined.m3u","count":4}
|
|
||||||
{"filepath":"countries/ad.m3u","count":2}
|
|
||||||
{"filepath":"countries/ca.m3u","count":1}
|
|
||||||
{"filepath":"subdivisions/ca-on.m3u","count":1}
|
|
||||||
{"filepath":"countries/in.m3u","count":1}
|
|
||||||
{"filepath":"countries/ru.m3u","count":1}
|
|
||||||
{"filepath":"countries/int.m3u","count":1}
|
|
||||||
{"filepath":"index.category.m3u","count":8}
|
|
||||||
{"filepath":"index.country.m3u","count":7}
|
|
||||||
{"filepath":"index.language.m3u","count":7}
|
|
||||||
{"filepath":"index.m3u","count":7}
|
|
||||||
{"filepath":"index.region.m3u","count":21}
|
|
||||||
{"filepath":"languages/eng.m3u","count":1}
|
|
||||||
{"filepath":"languages/rus.m3u","count":1}
|
|
||||||
{"filepath":"languages/cat.m3u","count":1}
|
|
||||||
{"filepath":"languages/undefined.m3u","count":4}
|
|
||||||
{"filepath":"regions/afr.m3u","count":0}
|
|
||||||
{"filepath":"regions/amer.m3u","count":1}
|
|
||||||
{"filepath":"regions/apac.m3u","count":1}
|
|
||||||
{"filepath":"regions/arab.m3u","count":0}
|
|
||||||
{"filepath":"regions/asean.m3u","count":0}
|
|
||||||
{"filepath":"regions/asia.m3u","count":2}
|
|
||||||
{"filepath":"regions/carib.m3u","count":0}
|
|
||||||
{"filepath":"regions/cas.m3u","count":0}
|
|
||||||
{"filepath":"regions/cenamer.m3u","count":0}
|
|
||||||
{"filepath":"regions/cis.m3u","count":1}
|
|
||||||
{"filepath":"regions/emea.m3u","count":3}
|
|
||||||
{"filepath":"regions/eur.m3u","count":3}
|
|
||||||
{"filepath":"regions/hispam.m3u","count":0}
|
|
||||||
{"filepath":"regions/lac.m3u","count":0}
|
|
||||||
{"filepath":"regions/latam.m3u","count":0}
|
|
||||||
{"filepath":"regions/maghreb.m3u","count":0}
|
|
||||||
{"filepath":"regions/mena.m3u","count":0}
|
|
||||||
{"filepath":"regions/mideast.m3u","count":0}
|
|
||||||
{"filepath":"regions/nam.m3u","count":1}
|
|
||||||
{"filepath":"regions/noram.m3u","count":1}
|
|
||||||
{"filepath":"regions/nord.m3u","count":0}
|
|
||||||
{"filepath":"regions/oce.m3u","count":0}
|
|
||||||
{"filepath":"regions/sas.m3u","count":1}
|
|
||||||
{"filepath":"regions/southam.m3u","count":0}
|
|
||||||
{"filepath":"regions/ssa.m3u","count":0}
|
|
||||||
{"filepath":"regions/wafr.m3u","count":0}
|
|
@ -0,0 +1,76 @@
|
|||||||
|
{"type":"category","filepath":"categories/auto.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/cooking.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/comedy.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/documentary.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/business.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/classic.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/entertainment.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/education.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/animation.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/family.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/kids.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/culture.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/lifestyle.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/general.m3u","count":3}
|
||||||
|
{"type":"category","filepath":"categories/outdoor.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/music.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/legislative.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/series.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/news.m3u","count":1}
|
||||||
|
{"type":"category","filepath":"categories/movies.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/relax.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/religious.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/weather.m3u","count":1}
|
||||||
|
{"type":"category","filepath":"categories/science.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/shop.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/xxx.m3u","count":1}
|
||||||
|
{"type":"category","filepath":"categories/sports.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/travel.m3u","count":0}
|
||||||
|
{"type":"category","filepath":"categories/undefined.m3u","count":6}
|
||||||
|
{"type":"country","filepath":"countries/ad.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/ca.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/kg.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/kz.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/tj.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/ru.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/tm.m3u","count":1}
|
||||||
|
{"type":"country","filepath":"countries/undefined.m3u","count":4}
|
||||||
|
{"type":"country","filepath":"countries/uz.m3u","count":1}
|
||||||
|
{"type":"language","filepath":"languages/cat.m3u","count":1}
|
||||||
|
{"type":"language","filepath":"languages/rus.m3u","count":1}
|
||||||
|
{"type":"subdivision","filepath":"subdivisions/ca-on.m3u","count":1}
|
||||||
|
{"type":"language","filepath":"languages/undefined.m3u","count":7}
|
||||||
|
{"type":"language","filepath":"languages/eng.m3u","count":1}
|
||||||
|
{"type":"region","filepath":"regions/afr.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/apac.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/amer.m3u","count":1}
|
||||||
|
{"type":"region","filepath":"regions/arab.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/asean.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/cenamer.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/asia.m3u","count":2}
|
||||||
|
{"type":"region","filepath":"regions/carib.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/cis.m3u","count":2}
|
||||||
|
{"type":"region","filepath":"regions/hispam.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/emea.m3u","count":3}
|
||||||
|
{"type":"region","filepath":"regions/lac.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/cas.m3u","count":1}
|
||||||
|
{"type":"region","filepath":"regions/latam.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/eur.m3u","count":3}
|
||||||
|
{"type":"region","filepath":"regions/nam.m3u","count":1}
|
||||||
|
{"type":"region","filepath":"regions/mena.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/noram.m3u","count":1}
|
||||||
|
{"type":"region","filepath":"regions/mideast.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/maghreb.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/ssa.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/nord.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/oce.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/southam.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/wafr.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/int.m3u","count":2}
|
||||||
|
{"type":"region","filepath":"regions/sas.m3u","count":0}
|
||||||
|
{"type":"region","filepath":"regions/undefined.m3u","count":4}
|
||||||
|
{"type":"index","filepath":"index.m3u","count":10}
|
||||||
|
{"type":"index","filepath":"index.category.m3u","count":11}
|
||||||
|
{"type":"index","filepath":"index.country.m3u","count":14}
|
||||||
|
{"type":"index","filepath":"index.language.m3u","count":10}
|
||||||
|
{"type":"index","filepath":"index.region.m3u","count":20}
|
@ -0,0 +1,3 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXTINF:-1 tvg-id="AdaTV.cy",AdaTV
|
||||||
|
https://ythls.onrender.com/channel/UC40TUSUx490U5uR1lZt3Ajg.m3u8
|
@ -1,5 +1,5 @@
|
|||||||
#EXTM3U
|
#EXTM3U
|
||||||
#EXTINF:-1 tvg-id="BBCAmericaEast.us" http-user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246",BBC America East (720p)
|
#EXTINF:-1 tvg-id="BBCAmerica.us@East" http-user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246",BBC America East (720p)
|
||||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246
|
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 Edge/12.246
|
||||||
https://servilive.com:3126/live/tele2000live.m3u8
|
https://servilive.com:3126/live/tele2000live.m3u8
|
||||||
#EXTINF:-1 tvg-id="FastTV.us",Fast TV
|
#EXTINF:-1 tvg-id="FastTV.us",Fast TV
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue