Merge branch 'master' into master

This commit is contained in:
Jxpl9
2025-09-01 15:46:46 +02:00
committed by GitHub
117 changed files with 2381 additions and 8382 deletions

3
.readme/.gitignore vendored
View File

@@ -1,5 +1,4 @@
_categories.md
_countries.md
_languages.md
_regions.md
_subdivisions.md
_regions.md

View File

@@ -1,4 +0,0 @@
{
"build" : "PLAYLISTS.md",
"files" : ["./.readme/template.md"]
}

View File

@@ -40,13 +40,14 @@ Same thing, but split up into separate files:
</details>
### Grouped by country
### Grouped by broadcast area
Playlists in which channels are grouped by country for which they are broadcasted.
Playlists in which channels are grouped by broadcast area.
<details>
<summary>Expand</summary>
<br>
#### Countries
```
https://iptv-org.github.io/iptv/index.country.m3u
@@ -57,34 +58,7 @@ Same thing, but split up into separate files:
<!-- prettier-ignore -->
#include "./.readme/_countries.md"
</details>
### Grouped by subdivision
Playlists in which channels are grouped by subdivision for which they are broadcasted.
<details>
<summary>Expand</summary>
<br>
<!-- prettier-ignore -->
#include "./.readme/_subdivisions.md"
</details>
### Grouped by region
Playlists in which channels are grouped by the region for which they are broadcasted.
<details>
<summary>Expand</summary>
<br>
```
https://iptv-org.github.io/iptv/index.region.m3u
```
Same thing, but split up into separate files:
#### Regions
<!-- prettier-ignore -->
#include "./.readme/_regions.md"

File diff suppressed because it is too large Load Diff

91
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.32.0",
"@freearhey/core": "^0.10.2",
@@ -45,6 +46,11 @@
"tsx": "^4.20.3"
}
},
"node_modules/@alex_neo/jest-expect-message": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@alex_neo/jest-expect-message/-/jest-expect-message-1.0.5.tgz",
"integrity": "sha512-1eBykZCd0pPGl5qKtV6Z5ARA6yuhXzHsVN2h5GH5/H6svYa37Jr7vMio5OFpiw1LBHtscrZs7amSkZkcwm0cvQ=="
},
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -1254,14 +1260,13 @@
}
},
"node_modules/@inquirer/editor": {
"version": "4.2.15",
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.15.tgz",
"integrity": "sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==",
"license": "MIT",
"version": "4.2.17",
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.17.tgz",
"integrity": "sha512-r6bQLsyPSzbWrZZ9ufoWL+CztkSatnJ6uSxqd6N+o41EZC51sQeWOzI6s5jLb+xxTWxl7PlUppqm8/sow241gg==",
"dependencies": {
"@inquirer/core": "^10.1.15",
"@inquirer/type": "^3.0.8",
"external-editor": "^3.1.0"
"@inquirer/external-editor": "^1.0.1",
"@inquirer/type": "^3.0.8"
},
"engines": {
"node": ">=18"
@@ -1297,6 +1302,26 @@
}
}
},
"node_modules/@inquirer/external-editor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz",
"integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==",
"dependencies": {
"chardet": "^2.1.0",
"iconv-lite": "^0.6.3"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@types/node": ">=18"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
}
}
},
"node_modules/@inquirer/figures": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz",
@@ -3853,10 +3878,9 @@
}
},
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"license": "MIT"
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz",
"integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA=="
},
"node_modules/ci-info": {
"version": "4.3.0",
@@ -4547,20 +4571,6 @@
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
"node_modules/external-editor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"license": "MIT",
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
"tmp": "^0.0.33"
},
"engines": {
"node": ">=4"
}
},
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
@@ -5033,12 +5043,11 @@
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"license": "MIT",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
@@ -6848,15 +6857,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/outvariant": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
@@ -7280,8 +7280,7 @@
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/semver": {
"version": "7.7.2",
@@ -7667,18 +7666,6 @@
"resolved": "https://registry.npmjs.org/timer-node/-/timer-node-5.0.9.tgz",
"integrity": "sha512-zXxCE/5/YDi0hY9pygqgRqjRbrFRzigYxOudG0I3syaqAAmX9/w9sxex1bNFCN6c1S66RwPtEIJv65dN+1psew=="
},
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"license": "MIT",
"dependencies": {
"os-tmpdir": "~1.0.2"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",

View File

@@ -38,6 +38,7 @@
"private": true,
"license": "MIT",
"dependencies": {
"@alex_neo/jest-expect-message": "^1.0.5",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.32.0",
"@freearhey/core": "^0.10.2",

View File

@@ -18,7 +18,8 @@ async function main() {
loader.download('logos.json'),
loader.download('timezones.json'),
loader.download('guides.json'),
loader.download('streams.json')
loader.download('streams.json'),
loader.download('cities.json')
])
}

View File

@@ -10,12 +10,12 @@ import {
IndexLanguageGenerator,
IndexCountryGenerator,
SubdivisionsGenerator,
IndexRegionGenerator,
CategoriesGenerator,
CountriesGenerator,
LanguagesGenerator,
RegionsGenerator,
SourcesGenerator,
CitiesGenerator,
IndexGenerator,
RawGenerator
} from '../../generators'
@@ -36,7 +36,8 @@ async function main() {
subdivisions,
categories,
countries,
regions
regions,
cities
}: DataProcessorData = processor.process(data)
logger.info('loading streams...')
@@ -90,6 +91,13 @@ async function main() {
logFile
}).generate()
logger.info('generating cities/...')
await new CitiesGenerator({
cities,
streams,
logFile
}).generate()
logger.info('generating regions/...')
await new RegionsGenerator({
streams,
@@ -115,9 +123,6 @@ async function main() {
logger.info('generating index.language.m3u...')
await new IndexLanguageGenerator({ streams, logFile }).generate()
logger.info('generating index.region.m3u...')
await new IndexRegionGenerator({ streams, regions, logFile }).generate()
logger.info('saving generators.log...')
const logStorage = new Storage(LOGS_DIR)
logStorage.saveFile(logFile)

View File

@@ -1,32 +1,47 @@
import { Logger } from '@freearhey/core'
import {
CategoryTable,
CountryTable,
LanguageTable,
RegionTable,
SubdivisionTable
} from '../../tables'
import { Markdown } from '../../core'
import { README_DIR } from '../../constants'
import path from 'path'
import { CategoriesTable, CountriesTable, LanguagesTable, RegionsTable } from '../../tables'
import { DataLoader, DataProcessor, Markdown } from '../../core'
import { DataProcessorData } from '../../types/dataProcessor'
import { DataLoaderData } from '../../types/dataLoader'
import { README_DIR, DATA_DIR, ROOT_DIR } from '../../constants'
import { Logger, Storage } from '@freearhey/core'
async function main() {
const logger = new Logger()
const dataStorage = new Storage(DATA_DIR)
const processor = new DataProcessor()
const loader = new DataLoader({ storage: dataStorage })
const data: DataLoaderData = await loader.load()
const {
subdivisionsKeyByCode,
languagesKeyByCode,
countriesKeyByCode,
categoriesKeyById,
subdivisions,
countries,
regions,
cities
}: DataProcessorData = processor.process(data)
logger.info('creating category table...')
await new CategoryTable().make()
await new CategoriesTable({ categoriesKeyById }).make()
logger.info('creating language table...')
await new LanguageTable().make()
logger.info('creating country table...')
await new CountryTable().make()
logger.info('creating subdivision table...')
await new SubdivisionTable().make()
await new LanguagesTable({ languagesKeyByCode }).make()
logger.info('creating countires table...')
await new CountriesTable({
countriesKeyByCode,
subdivisionsKeyByCode,
subdivisions,
countries,
cities
}).make()
logger.info('creating region table...')
await new RegionTable().make()
await new RegionsTable({ regions }).make()
logger.info('updating playlists.md...')
const configPath = path.join(README_DIR, 'config.json')
const playlists = new Markdown(configPath)
const playlists = new Markdown({
build: `${ROOT_DIR}/PLAYLISTS.md`,
template: `${README_DIR}/template.md`
})
playlists.compile()
}

View File

@@ -57,7 +57,8 @@ export class DataLoader {
logos,
timezones,
guides,
streams
streams,
cities
] = await Promise.all([
this.storage.json('countries.json'),
this.storage.json('regions.json'),
@@ -70,7 +71,8 @@ export class DataLoader {
this.storage.json('logos.json'),
this.storage.json('timezones.json'),
this.storage.json('guides.json'),
this.storage.json('streams.json')
this.storage.json('streams.json'),
this.storage.json('cities.json')
])
return {
@@ -85,7 +87,8 @@ export class DataLoader {
logos,
timezones,
guides,
streams
streams,
cities
}
}

View File

@@ -1,3 +1,4 @@
import { DataProcessorData } from '../types/dataProcessor'
import { DataLoaderData } from '../types/dataLoader'
import { Collection } from '@freearhey/core'
import {
@@ -11,14 +12,16 @@ import {
Region,
Stream,
Guide,
City,
Feed,
Logo
} from '../models'
export class DataProcessor {
constructor() {}
process(data: DataLoaderData): DataProcessorData {
let regions = new Collection(data.regions).map(data => new Region(data))
let regionsKeyByCode = regions.keyBy((region: Region) => region.code)
process(data: DataLoaderData) {
const categories = new Collection(data.categories).map(data => new Category(data))
const categoriesKeyById = categories.keyBy((category: Category) => category.id)
@@ -26,25 +29,23 @@ export class DataProcessor {
const languagesKeyByCode = languages.keyBy((language: Language) => language.code)
let subdivisions = new Collection(data.subdivisions).map(data => new Subdivision(data))
const subdivisionsKeyByCode = subdivisions.keyBy((subdivision: Subdivision) => subdivision.code)
const subdivisionsGroupedByCountryCode = subdivisions.groupBy(
let subdivisionsKeyByCode = subdivisions.keyBy((subdivision: Subdivision) => subdivision.code)
let subdivisionsGroupedByCountryCode = subdivisions.groupBy(
(subdivision: Subdivision) => subdivision.countryCode
)
let regions = new Collection(data.regions).map(data => new Region(data))
const regionsKeyByCode = regions.keyBy((region: Region) => region.code)
let countries = new Collection(data.countries).map(data => new Country(data))
let countriesKeyByCode = countries.keyBy((country: Country) => country.code)
const countries = new Collection(data.countries).map(data =>
new Country(data)
const cities = new Collection(data.cities).map(data =>
new City(data)
.withRegions(regions)
.withLanguage(languagesKeyByCode)
.withSubdivisions(subdivisionsGroupedByCountryCode)
)
const countriesKeyByCode = countries.keyBy((country: Country) => country.code)
subdivisions = subdivisions.map((subdivision: Subdivision) =>
subdivision.withCountry(countriesKeyByCode)
.withCountry(countriesKeyByCode)
.withSubdivision(subdivisionsKeyByCode)
)
const citiesKeyByCode = cities.keyBy((city: City) => city.code)
const citiesGroupedByCountryCode = cities.groupBy((city: City) => city.countryCode)
const citiesGroupedBySubdivisionCode = cities.groupBy((city: City) => city.subdivisionCode)
const timezones = new Collection(data.timezones).map(data =>
new Timezone(data).withCountries(countriesKeyByCode)
@@ -56,27 +57,12 @@ export class DataProcessor {
(blocklistRecord: BlocklistRecord) => blocklistRecord.channelId
)
let channels = new Collection(data.channels).map(data =>
new Channel(data)
.withCategories(categoriesKeyById)
.withCountry(countriesKeyByCode)
.withSubdivision(subdivisionsKeyByCode)
.withCategories(categoriesKeyById)
)
let channels = new Collection(data.channels).map(data => new Channel(data))
let channelsKeyById = channels.keyBy((channel: Channel) => channel.id)
const channelsKeyById = channels.keyBy((channel: Channel) => channel.id)
const feeds = new Collection(data.feeds).map(data =>
new Feed(data)
.withChannel(channelsKeyById)
.withLanguages(languagesKeyByCode)
.withTimezones(timezonesKeyById)
.withBroadcastCountries(countriesKeyByCode, regionsKeyByCode, subdivisionsKeyByCode)
.withBroadcastRegions(regions)
.withBroadcastSubdivisions(subdivisionsKeyByCode)
)
const feedsGroupedByChannelId = feeds.groupBy((feed: Feed) => feed.channelId)
const feedsGroupedById = feeds.groupBy((feed: Feed) => feed.id)
let feeds = new Collection(data.feeds).map(data => new Feed(data))
let feedsGroupedByChannelId = feeds.groupBy((feed: Feed) => feed.channelId)
let feedsGroupedById = feeds.groupBy((feed: Feed) => feed.id)
const logos = new Collection(data.logos).map(data => new Logo(data).withFeed(feedsGroupedById))
const logosGroupedByChannelId = logos.groupBy((logo: Logo) => logo.channelId)
@@ -90,11 +76,60 @@ export class DataProcessor {
const guides = new Collection(data.guides).map(data => new Guide(data))
const guidesGroupedByStreamId = guides.groupBy((guide: Guide) => guide.getStreamId())
regions = regions.map((region: Region) => region.withCountries(countriesKeyByCode))
regions = regions.map((region: Region) =>
region
.withCountries(countriesKeyByCode)
.withRegions(regions)
.withSubdivisions(subdivisions)
.withCities(cities)
)
regionsKeyByCode = regions.keyBy((region: Region) => region.code)
countries = countries.map((country: Country) =>
country
.withCities(citiesGroupedByCountryCode)
.withSubdivisions(subdivisionsGroupedByCountryCode)
.withRegions(regions)
.withLanguage(languagesKeyByCode)
)
countriesKeyByCode = countries.keyBy((country: Country) => country.code)
subdivisions = subdivisions.map((subdivision: Subdivision) =>
subdivision
.withCities(citiesGroupedBySubdivisionCode)
.withCountry(countriesKeyByCode)
.withRegions(regions)
)
subdivisionsKeyByCode = subdivisions.keyBy((subdivision: Subdivision) => subdivision.code)
subdivisionsGroupedByCountryCode = subdivisions.groupBy(
(subdivision: Subdivision) => subdivision.countryCode
)
channels = channels.map((channel: Channel) =>
channel.withFeeds(feedsGroupedByChannelId).withLogos(logosGroupedByChannelId)
channel
.withFeeds(feedsGroupedByChannelId)
.withLogos(logosGroupedByChannelId)
.withCategories(categoriesKeyById)
.withCountry(countriesKeyByCode)
.withSubdivision(subdivisionsKeyByCode)
.withCategories(categoriesKeyById)
)
channelsKeyById = channels.keyBy((channel: Channel) => channel.id)
feeds = feeds.map((feed: Feed) =>
feed
.withChannel(channelsKeyById)
.withLanguages(languagesKeyByCode)
.withTimezones(timezonesKeyById)
.withBroadcastArea(
citiesKeyByCode,
subdivisionsKeyByCode,
countriesKeyByCode,
regionsKeyByCode
)
)
feedsGroupedByChannelId = feeds.groupBy((feed: Feed) => feed.channelId)
feedsGroupedById = feeds.groupBy((feed: Feed) => feed.id)
return {
blocklistRecordsGroupedByChannelId,
@@ -111,6 +146,7 @@ export class DataProcessor {
regionsKeyByCode,
blocklistRecords,
channelsKeyById,
citiesKeyByCode,
subdivisions,
categories,
countries,
@@ -119,6 +155,7 @@ export class DataProcessor {
channels,
regions,
streams,
cities,
guides,
feeds,
logos

View File

@@ -1,33 +1,37 @@
import fs from 'fs'
import path from 'path'
export class Markdown {
filepath: string
type MarkdownConfig = {
build: string
template: string
}
constructor(filepath: string) {
this.filepath = filepath
export class Markdown {
build: string
template: string
constructor(config: MarkdownConfig) {
this.build = config.build
this.template = config.template
}
compile() {
const config = JSON.parse(fs.readFileSync(this.filepath, 'utf8'))
const workingDir = process.cwd()
config.files.forEach((templateFile: string) => {
const templatePath = path.resolve(workingDir, templateFile)
const content = fs.readFileSync(templatePath, 'utf8')
const processedContent = this.processIncludes(content, workingDir)
if (config.build) {
const outputPath = path.resolve(workingDir, config.build)
fs.writeFileSync(outputPath, processedContent, 'utf8')
}
})
const workingDir = process.cwd()
const templatePath = path.resolve(workingDir, this.template)
const template = fs.readFileSync(templatePath, 'utf8')
const processedContent = this.processIncludes(template, workingDir)
if (this.build) {
const outputPath = path.resolve(workingDir, this.build)
fs.writeFileSync(outputPath, processedContent, 'utf8')
}
}
private processIncludes(content: string, baseDir: string): string {
private processIncludes(template: string, baseDir: string): string {
const includeRegex = /#include\s+"([^"]+)"/g
return content.replace(includeRegex, (match, includePath) => {
return template.replace(includeRegex, (match, includePath) => {
try {
const fullPath = path.resolve(baseDir, includePath)
const includeContent = fs.readFileSync(fullPath, 'utf8')

View File

@@ -0,0 +1,43 @@
import { City, Stream, Playlist } from '../models'
import { Collection, Storage, File } from '@freearhey/core'
import { PUBLIC_DIR, EOL } from '../constants'
import { Generator } from './generator'
type CitiesGeneratorProps = {
streams: Collection
cities: Collection
logFile: File
}
export class CitiesGenerator implements Generator {
streams: Collection
cities: Collection
storage: Storage
logFile: File
constructor({ streams, cities, logFile }: CitiesGeneratorProps) {
this.streams = streams.clone()
this.cities = cities
this.storage = new Storage(PUBLIC_DIR)
this.logFile = logFile
}
async generate(): Promise<void> {
const streams = this.streams
.orderBy((stream: Stream) => stream.getTitle())
.filter((stream: Stream) => stream.isSFW())
this.cities.forEach(async (city: City) => {
const cityStreams = streams.filter((stream: Stream) => stream.isBroadcastInCity(city))
if (cityStreams.isEmpty()) return
const playlist = new Playlist(cityStreams, { public: true })
const filepath = `cities/${city.code.toLowerCase()}.m3u`
await this.storage.save(filepath, playlist.toString())
this.logFile.append(
JSON.stringify({ type: 'city', filepath, count: playlist.streams.count() }) + EOL
)
})
}
}

View File

@@ -41,6 +41,18 @@ export class CountriesGenerator implements Generator {
)
})
const internationalStreams = streams.filter((stream: Stream) => stream.isInternational())
const internationalPlaylist = new Playlist(internationalStreams, { public: true })
const internationalFilepath = 'countries/int.m3u'
await this.storage.save(internationalFilepath, internationalPlaylist.toString())
this.logFile.append(
JSON.stringify({
type: 'country',
filepath: internationalFilepath,
count: internationalPlaylist.streams.count()
}) + EOL
)
const undefinedStreams = streams.filter((stream: Stream) => !stream.hasBroadcastArea())
const undefinedPlaylist = new Playlist(undefinedStreams, { public: true })
const undefinedFilepath = 'countries/undefined.m3u'

View File

@@ -1,11 +1,11 @@
export * from './categoriesGenerator'
export * from './citiesGenerator'
export * from './countriesGenerator'
export * from './indexCategoryGenerator'
export * from './indexCountryGenerator'
export * from './indexGenerator'
export * from './indexLanguageGenerator'
export * from './indexNsfwGenerator'
export * from './indexRegionGenerator'
export * from './languagesGenerator'
export * from './rawGenerator'
export * from './regionsGenerator'

View File

@@ -33,17 +33,17 @@ export class IndexCountryGenerator implements Generator {
return
}
if (stream.isInternational()) {
const streamClone = stream.clone()
streamClone.groupTitle = 'International'
groupedStreams.add(streamClone)
}
stream.getBroadcastCountries().forEach((country: Country) => {
const streamClone = stream.clone()
streamClone.groupTitle = country.name
groupedStreams.add(streamClone)
})
if (stream.isInternational()) {
const streamClone = stream.clone()
streamClone.groupTitle = 'International'
groupedStreams.add(streamClone)
}
})
groupedStreams = groupedStreams.orderBy((stream: Stream) => {

View File

@@ -1,65 +0,0 @@
import { Collection, Storage, File } from '@freearhey/core'
import { Stream, Playlist, Region } from '../models'
import { PUBLIC_DIR, EOL } from '../constants'
import { Generator } from './generator'
type IndexRegionGeneratorProps = {
streams: Collection
regions: Collection
logFile: File
}
export class IndexRegionGenerator implements Generator {
streams: Collection
regions: Collection
storage: Storage
logFile: File
constructor({ streams, regions, logFile }: IndexRegionGeneratorProps) {
this.streams = streams.clone()
this.regions = regions
this.storage = new Storage(PUBLIC_DIR)
this.logFile = logFile
}
async generate(): Promise<void> {
let groupedStreams = new Collection()
this.streams
.orderBy((stream: Stream) => stream.getTitle())
.filter((stream: Stream) => stream.isSFW())
.forEach((stream: Stream) => {
if (stream.isInternational()) {
const streamClone = stream.clone()
streamClone.groupTitle = 'International'
groupedStreams.push(streamClone)
return
}
if (!stream.hasBroadcastArea()) {
const streamClone = stream.clone()
streamClone.groupTitle = 'Undefined'
groupedStreams.push(streamClone)
return
}
stream.getBroadcastRegions().forEach((region: Region) => {
const streamClone = stream.clone()
streamClone.groupTitle = region.name
groupedStreams.push(streamClone)
})
})
groupedStreams = groupedStreams.orderBy((stream: Stream) => {
if (stream.groupTitle === 'International') return 'ZZ'
if (stream.groupTitle === 'Undefined') return 'ZZZ'
return stream.groupTitle
})
const playlist = new Playlist(groupedStreams, { public: true })
const filepath = 'index.region.m3u'
await this.storage.save(filepath, playlist.toString())
this.logFile.append(
JSON.stringify({ type: 'index', filepath, count: playlist.streams.count() }) + EOL
)
}
}

View File

@@ -28,8 +28,6 @@ export class RegionsGenerator implements Generator {
.filter((stream: Stream) => stream.isSFW())
this.regions.forEach(async (region: Region) => {
if (region.isWorldwide()) return
const regionStreams = streams.filter((stream: Stream) => stream.isBroadcastInRegion(region))
const playlist = new Playlist(regionStreams, { public: true })
@@ -39,25 +37,5 @@ export class RegionsGenerator implements Generator {
JSON.stringify({ type: 'region', filepath, count: playlist.streams.count() }) + EOL
)
})
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.logFile.append(
JSON.stringify({
type: 'region',
filepath: internationalFilepath,
count: internationalPlaylist.streams.count()
}) + EOL
)
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.logFile.append(
JSON.stringify({ type: 'region', filepath, count: playlist.streams.count() }) + EOL
)
}
}

View File

@@ -1,11 +1,103 @@
type BroadcastAreaProps = {
code: string
}
import { Collection, Dictionary } from '@freearhey/core'
import { City, Subdivision, Region, Country } from './'
export class BroadcastArea {
code: string
codes: Collection
citiesIncluded: Collection
subdivisionsIncluded: Collection
countriesIncluded: Collection
regionsIncluded: Collection
constructor(data: BroadcastAreaProps) {
this.code = data.code
constructor(codes: Collection) {
this.codes = codes
}
withLocations(
citiesKeyByCode: Dictionary,
subdivisionsKeyByCode: Dictionary,
countriesKeyByCode: Dictionary,
regionsKeyByCode: Dictionary
): this {
let citiesIncluded = new Collection()
let subdivisionsIncluded = new Collection()
let countriesIncluded = new Collection()
let regionsIncluded = new Collection()
this.codes.forEach((value: string) => {
const [type, code] = value.split('/')
switch (type) {
case 'ct': {
const city: City = citiesKeyByCode.get(code)
if (!city) return
citiesIncluded.add(city)
regionsIncluded = regionsIncluded.concat(city.getRegions())
break
}
case 's': {
const subdivision: Subdivision = subdivisionsKeyByCode.get(code)
if (!subdivision) return
subdivisionsIncluded.add(subdivision)
regionsIncluded = regionsIncluded.concat(subdivision.getRegions())
break
}
case 'c': {
const country: Country = countriesKeyByCode.get(code)
if (!country) return
countriesIncluded.add(country)
regionsIncluded = regionsIncluded.concat(country.getRegions())
break
}
case 'r': {
const region: Region = regionsKeyByCode.get(code)
if (!region) return
regionsIncluded = regionsIncluded.concat(region.getRegions())
break
}
}
})
this.citiesIncluded = citiesIncluded.uniqBy((city: City) => city.code)
this.subdivisionsIncluded = subdivisionsIncluded.uniqBy(
(subdivision: Subdivision) => subdivision.code
)
this.countriesIncluded = countriesIncluded.uniqBy((country: Country) => country.code)
this.regionsIncluded = regionsIncluded.uniqBy((region: Region) => region.code)
return this
}
getCountries(): Collection {
return this.countriesIncluded || new Collection()
}
getSubdivisions(): Collection {
return this.subdivisionsIncluded || new Collection()
}
getCities(): Collection {
return this.citiesIncluded || new Collection()
}
getRegions(): Collection {
return this.regionsIncluded || new Collection()
}
includesCountry(country: Country): boolean {
return this.getCountries().includes((_country: Country) => _country.code === country.code)
}
includesSubdivision(subdivision: Subdivision): boolean {
return this.getSubdivisions().includes(
(_subdivision: Subdivision) => _subdivision.code === subdivision.code
)
}
includesRegion(region: Region): boolean {
return this.getRegions().includes((_region: Region) => _region.code === region.code)
}
includesCity(city: City): boolean {
return this.getCities().includes((_city: City) => _city.code === city.code)
}
}

78
scripts/models/city.ts Normal file
View File

@@ -0,0 +1,78 @@
import { Collection, Dictionary } from '@freearhey/core'
import { Country, Region, Subdivision } from '.'
import type { CityData, CitySerializedData } from '../types/city'
export class City {
code: string
name: string
countryCode: string
country?: Country
subdivisionCode?: string
subdivision?: Subdivision
wikidataId: string
regions?: Collection
constructor(data?: CityData) {
if (!data) return
this.code = data.code
this.name = data.name
this.countryCode = data.country
this.subdivisionCode = data.subdivision || undefined
this.wikidataId = data.wikidata_id
}
withCountry(countriesKeyByCode: Dictionary): this {
this.country = countriesKeyByCode.get(this.countryCode)
return this
}
withSubdivision(subdivisionsKeyByCode: Dictionary): this {
if (!this.subdivisionCode) return this
this.subdivision = subdivisionsKeyByCode.get(this.subdivisionCode)
return this
}
withRegions(regions: Collection): this {
this.regions = regions.filter((region: Region) =>
region.countryCodes.includes(this.countryCode)
)
return this
}
getRegions(): Collection {
if (!this.regions) return new Collection()
return this.regions
}
serialize(): CitySerializedData {
return {
code: this.code,
name: this.name,
countryCode: this.countryCode,
country: this.country ? this.country.serialize() : undefined,
subdivisionCode: this.subdivisionCode || null,
subdivision: this.subdivision ? this.subdivision.serialize() : undefined,
wikidataId: this.wikidataId
}
}
deserialize(data: CitySerializedData): this {
this.code = data.code
this.name = data.name
this.countryCode = data.countryCode
this.country = data.country ? new Country().deserialize(data.country) : undefined
this.subdivisionCode = data.subdivisionCode || undefined
this.subdivision = data.subdivision
? new Subdivision().deserialize(data.subdivision)
: undefined
this.wikidataId = data.wikidataId
return this
}
}

View File

@@ -12,6 +12,7 @@ export class Country {
language?: Language
subdivisions?: Collection
regions?: Collection
cities?: Collection
constructor(data?: CountryData) {
if (!data) return
@@ -23,15 +24,19 @@ export class Country {
}
withSubdivisions(subdivisionsGroupedByCountryCode: Dictionary): this {
this.subdivisions = subdivisionsGroupedByCountryCode.get(this.code) || new Collection()
this.subdivisions = new Collection(subdivisionsGroupedByCountryCode.get(this.code))
return this
}
withRegions(regions: Collection): this {
this.regions = regions.filter(
(region: Region) => region.code !== 'INT' && region.includesCountryCode(this.code)
)
this.regions = regions.filter((region: Region) => region.includesCountryCode(this.code))
return this
}
withCities(citiesGroupedByCountryCode: Dictionary): this {
this.cities = new Collection(citiesGroupedByCountryCode.get(this.code))
return this
}
@@ -54,6 +59,10 @@ export class Country {
return this.subdivisions || new Collection()
}
getCities(): Collection {
return this.cities || new Collection()
}
serialize(): CountrySerializedData {
return {
code: this.code,

View File

@@ -1,4 +1,4 @@
import { Country, Language, Region, Channel, Subdivision } from './index'
import { Country, Language, Region, Channel, Subdivision, BroadcastArea, City } from './index'
import { Collection, Dictionary } from '@freearhey/core'
import type { FeedData } from '../types/feed'
@@ -9,12 +9,7 @@ export class Feed {
name: string
isMain: boolean
broadcastAreaCodes: Collection
broadcastCountryCodes: Collection
broadcastCountries?: Collection
broadcastRegionCodes: Collection
broadcastRegions?: Collection
broadcastSubdivisionCodes: Collection
broadcastSubdivisions?: Collection
broadcastArea?: BroadcastArea
languageCodes: Collection
languages?: Collection
timezoneIds: Collection
@@ -32,25 +27,6 @@ export class Feed {
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(channelsKeyById: Dictionary): this {
@@ -93,76 +69,36 @@ export class Feed {
return this
}
withBroadcastSubdivisions(subdivisionsKeyByCode: Dictionary): this {
this.broadcastSubdivisions = this.broadcastSubdivisionCodes.map((code: string) =>
subdivisionsKeyByCode.get(code)
)
return this
}
withBroadcastCountries(
withBroadcastArea(
citiesKeyByCode: Dictionary,
subdivisionsKeyByCode: Dictionary,
countriesKeyByCode: Dictionary,
regionsKeyByCode: Dictionary,
subdivisionsKeyByCode: Dictionary
regionsKeyByCode: Dictionary
): this {
const broadcastCountries = new Collection()
if (this.isInternational()) {
this.broadcastCountries = broadcastCountries
return this
}
this.broadcastCountryCodes.forEach((code: string) => {
broadcastCountries.add(countriesKeyByCode.get(code))
})
this.broadcastRegionCodes.forEach((code: string) => {
const region: Region = regionsKeyByCode.get(code)
if (region) {
region.countryCodes.forEach((countryCode: string) => {
broadcastCountries.add(countriesKeyByCode.get(countryCode))
})
}
})
this.broadcastSubdivisionCodes.forEach((code: string) => {
const subdivision: Subdivision = subdivisionsKeyByCode.get(code)
if (subdivision) {
broadcastCountries.add(countriesKeyByCode.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
const intersected = region.countryCodes.intersects(countriesCodes)
return intersected.notEmpty()
})
this.broadcastArea = new BroadcastArea(this.broadcastAreaCodes).withLocations(
citiesKeyByCode,
subdivisionsKeyByCode,
countriesKeyByCode,
regionsKeyByCode
)
return this
}
hasBroadcastArea(): boolean {
return (
this.isInternational() || (!!this.broadcastCountries && this.broadcastCountries.notEmpty())
)
return !!this.broadcastArea
}
getBroadcastCountries(): Collection {
return this.broadcastCountries || new Collection()
if (!this.broadcastArea) return new Collection()
return this.broadcastArea.getCountries()
}
getBroadcastRegions(): Collection {
return this.broadcastRegions || new Collection()
if (!this.broadcastArea) return new Collection()
return this.broadcastArea.getRegions()
}
getTimezones(): Collection {
@@ -184,35 +120,34 @@ export class Feed {
)
}
isInternational(): boolean {
return this.broadcastAreaCodes.includes('r/INT')
isBroadcastInCity(city: City): boolean {
if (!this.broadcastArea) return false
return this.broadcastArea.includesCity(city)
}
isBroadcastInSubdivision(subdivision: Subdivision): boolean {
if (this.isInternational()) return false
if (this.broadcastSubdivisionCodes.includes(subdivision.code)) return true
if (
this.broadcastSubdivisionCodes.isEmpty() &&
subdivision.country &&
this.isBroadcastInCountry(subdivision.country)
)
return true
if (!this.broadcastArea) return false
return false
return this.broadcastArea.includesSubdivision(subdivision)
}
isBroadcastInCountry(country: Country): boolean {
if (this.isInternational()) return false
if (!this.broadcastArea) return false
return this.getBroadcastCountries().includes(
(_country: Country) => _country.code === country.code
)
return this.broadcastArea.includesCountry(country)
}
isBroadcastInRegion(region: Region): boolean {
if (this.isInternational()) return false
if (!this.broadcastArea) return false
return this.getBroadcastRegions().includes((_region: Region) => _region.code === region.code)
return this.broadcastArea.includesRegion(region)
}
isInternational(): boolean {
if (!this.broadcastArea) return false
return this.broadcastArea.codes.join(',').includes('r/')
}
getGuides(): Collection {

View File

@@ -2,6 +2,7 @@ export * from './blocklistRecord'
export * from './broadcastArea'
export * from './category'
export * from './channel'
export * from './city'
export * from './country'
export * from './feed'
export * from './guide'

View File

@@ -1,15 +1,18 @@
import { Collection, Dictionary } from '@freearhey/core'
import { Country, Subdivision } from '.'
import { City, Country, Subdivision } from '.'
import type { RegionData, RegionSerializedData } from '../types/region'
import { CountrySerializedData } from '../types/country'
import { SubdivisionSerializedData } from '../types/subdivision'
import { CitySerializedData } from '../types/city'
export class Region {
code: string
name: string
countryCodes: Collection
countries: Collection = new Collection()
subdivisions: Collection = new Collection()
countries?: Collection
subdivisions?: Collection
cities?: Collection
regions?: Collection
constructor(data?: RegionData) {
if (!data) return
@@ -33,20 +36,50 @@ export class Region {
return this
}
withCities(cities: Collection): this {
this.cities = cities.filter((city: City) => this.countryCodes.indexOf(city.countryCode) > -1)
return this
}
withRegions(regions: Collection): this {
this.regions = regions.filter(
(region: Region) => !region.countryCodes.intersects(this.countryCodes).isEmpty()
)
return this
}
getSubdivisions(): Collection {
if (!this.subdivisions) return new Collection()
return this.subdivisions
}
getCountries(): Collection {
if (!this.countries) return new Collection()
return this.countries
}
getCities(): Collection {
if (!this.cities) return new Collection()
return this.cities
}
getRegions(): Collection {
if (!this.regions) return new Collection()
return this.regions
}
includesCountryCode(code: string): boolean {
return this.countryCodes.includes((countryCode: string) => countryCode === code)
}
isWorldwide(): boolean {
return this.code === 'INT'
return ['INT', 'WW'].includes(this.code)
}
serialize(): RegionSerializedData {
@@ -54,9 +87,14 @@ export class Region {
code: this.code,
name: this.name,
countryCodes: this.countryCodes.all(),
countries: this.countries.map((country: Country) => country.serialize()).all(),
subdivisions: this.subdivisions
countries: this.getCountries()
.map((country: Country) => country.serialize())
.all(),
subdivisions: this.getSubdivisions()
.map((subdivision: Subdivision) => subdivision.serialize())
.all(),
cities: this.getCities()
.map((city: City) => city.serialize())
.all()
}
}
@@ -71,6 +109,9 @@ export class Region {
this.subdivisions = new Collection(data.subdivisions).map((data: SubdivisionSerializedData) =>
new Subdivision().deserialize(data)
)
this.cities = new Collection(data.cities).map((data: CitySerializedData) =>
new City().deserialize(data)
)
return this
}

View File

@@ -1,4 +1,14 @@
import { Feed, Channel, Category, Region, Subdivision, Country, Language, Logo } from './index'
import {
Feed,
Channel,
Category,
Region,
Subdivision,
Country,
Language,
Logo,
City
} from './index'
import { URL, Collection, Dictionary } from '@freearhey/core'
import type { StreamData } from '../types/stream'
import parser from 'iptv-playlist-parser'
@@ -330,6 +340,10 @@ export class Stream {
return this.feed ? this.feed.broadcastAreaCodes : new Collection()
}
isBroadcastInCity(city: City): boolean {
return this.feed ? this.feed.isBroadcastInCity(city) : false
}
isBroadcastInSubdivision(subdivision: Subdivision): boolean {
return this.feed ? this.feed.isBroadcastInSubdivision(subdivision) : false
}

View File

@@ -1,12 +1,15 @@
import { SubdivisionData, SubdivisionSerializedData } from '../types/subdivision'
import { Dictionary } from '@freearhey/core'
import { Country } from '.'
import { Dictionary, Collection } from '@freearhey/core'
import { Country, Region } from '.'
export class Subdivision {
code: string
name: string
countryCode: string
country?: Country
parentCode?: string
regions?: Collection
cities?: Collection
constructor(data?: SubdivisionData) {
if (!data) return
@@ -14,6 +17,7 @@ export class Subdivision {
this.code = data.code
this.name = data.name
this.countryCode = data.country
this.parentCode = data.parent || undefined
}
withCountry(countriesKeyByCode: Dictionary): this {
@@ -22,12 +26,39 @@ export class Subdivision {
return this
}
withRegions(regions: Collection): this {
this.regions = regions.filter((region: Region) =>
region.countryCodes.includes(this.countryCode)
)
return this
}
withCities(citiesGroupedBySubdivisionCode: Dictionary): this {
this.cities = new Collection(citiesGroupedBySubdivisionCode.get(this.code))
return this
}
getRegions(): Collection {
if (!this.regions) return new Collection()
return this.regions
}
getCities(): Collection {
if (!this.cities) return new Collection()
return this.cities
}
serialize(): SubdivisionSerializedData {
return {
code: this.code,
name: this.name,
countryCode: this.code,
country: this.country ? this.country.serialize() : undefined
countryCode: this.countryCode,
country: this.country ? this.country.serialize() : undefined,
parentCode: this.parentCode || null
}
}
@@ -36,6 +67,7 @@ export class Subdivision {
this.name = data.name
this.countryCode = data.countryCode
this.country = data.country ? new Country().deserialize(data.country) : undefined
this.parentCode = data.parentCode || undefined
return this
}

View File

@@ -1,32 +1,35 @@
import { Storage, Collection, File } from '@freearhey/core'
import { Storage, Collection, File, Dictionary } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { LOGS_DIR, README_DIR } from '../constants'
import { Category } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class CategoryTable implements Table {
constructor() {}
type CategoriesTableProps = {
categoriesKeyById: Dictionary
}
export class CategoriesTable implements Table {
categoriesKeyById: Dictionary
constructor({ categoriesKeyById }: CategoriesTableProps) {
this.categoriesKeyById = categoriesKeyById
}
async make() {
const dataStorage = new Storage(DATA_DIR)
const categoriesContent = await dataStorage.json('categories.json')
const categories = new Collection(categoriesContent).map(data => new Category(data))
const categoriesGroupedById = categories.keyBy((category: Category) => category.id)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
let data = new Collection()
let items = new Collection()
parser
.parse(generatorsLog)
.filter((logItem: LogItem) => logItem.type === 'category')
.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const categoryId = file.name()
const category: Category = categoriesGroupedById.get(categoryId)
const category: Category = this.categoriesKeyById.get(categoryId)
data.add([
items.add([
category ? category.name : 'ZZ',
category ? category.name : 'Undefined',
logItem.count,
@@ -34,14 +37,14 @@ export class CategoryTable implements Table {
])
})
data = data
items = items
.orderBy(item => item[0])
.map(item => {
item.shift()
return item
})
const table = new HTMLTable(data.all(), [
const table = new HTMLTable(items.all(), [
{ name: 'Category' },
{ name: 'Channels', align: 'right' },
{ name: 'Playlist', nowrap: true }

View File

@@ -0,0 +1,189 @@
import { Storage, Collection, Dictionary } from '@freearhey/core'
import { City, Country, Subdivision } from '../models'
import { LOGS_DIR, README_DIR } from '../constants'
import { LogParser, LogItem } from '../core'
import { Table } from './table'
type CountriesTableProps = {
countriesKeyByCode: Dictionary
subdivisionsKeyByCode: Dictionary
countries: Collection
subdivisions: Collection
cities: Collection
}
export class CountriesTable implements Table {
countriesKeyByCode: Dictionary
subdivisionsKeyByCode: Dictionary
countries: Collection
subdivisions: Collection
cities: Collection
constructor({
countriesKeyByCode,
subdivisionsKeyByCode,
countries,
subdivisions,
cities
}: CountriesTableProps) {
this.countriesKeyByCode = countriesKeyByCode
this.subdivisionsKeyByCode = subdivisionsKeyByCode
this.countries = countries
this.subdivisions = subdivisions
this.cities = cities
}
async make() {
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
const parsed = parser.parse(generatorsLog)
const logCountries = parsed.filter((logItem: LogItem) => logItem.type === 'country')
const logSubdivisions = parsed.filter((logItem: LogItem) => logItem.type === 'subdivision')
const logCities = parsed.filter((logItem: LogItem) => logItem.type === 'city')
let items = new Collection()
this.countries.forEach((country: Country) => {
const countriesLogItem = logCountries.find(
(logItem: LogItem) => logItem.filepath === `countries/${country.code.toLowerCase()}.m3u`
)
let countryItem = {
index: country.name,
count: 0,
link: `https://iptv-org.github.io/iptv/countries/${country.code.toLowerCase()}.m3u`,
name: `${country.flag} ${country.name}`,
children: new Collection()
}
if (countriesLogItem) {
countryItem.count = countriesLogItem.count
}
const countrySubdivisions = this.subdivisions.filter(
(subdivision: Subdivision) => subdivision.countryCode === country.code
)
const countryCities = this.cities.filter((city: City) => city.countryCode === country.code)
if (countrySubdivisions.notEmpty()) {
this.subdivisions.forEach((subdivision: Subdivision) => {
if (subdivision.countryCode !== country.code) return
const subdivisionCities = countryCities.filter(
(city: City) =>
(city.subdivisionCode && city.subdivisionCode === subdivision.code) ||
city.countryCode === subdivision.countryCode
)
const subdivisionsLogItem = logSubdivisions.find(
(logItem: LogItem) =>
logItem.filepath === `subdivisions/${subdivision.code.toLowerCase()}.m3u`
)
let subdivisionItem = {
index: subdivision.name,
name: subdivision.name,
count: 0,
link: `https://iptv-org.github.io/iptv/subdivisions/${subdivision.code.toLowerCase()}.m3u`,
children: new Collection()
}
if (subdivisionsLogItem) {
subdivisionItem.count = subdivisionsLogItem.count
}
subdivisionCities.forEach((city: City) => {
if (city.countryCode !== country.code || city.subdivisionCode !== subdivision.code)
return
const citiesLogItem = logCities.find(
(logItem: LogItem) => logItem.filepath === `cities/${city.code.toLowerCase()}.m3u`
)
if (!citiesLogItem) return
subdivisionItem.children.add({
index: city.name,
name: city.name,
count: citiesLogItem.count,
link: `https://iptv-org.github.io/iptv/${citiesLogItem.filepath}`
})
})
if (subdivisionItem.count > 0 || subdivisionItem.children.notEmpty()) {
countryItem.children.add(subdivisionItem)
}
})
} else if (countryCities.notEmpty()) {
countryCities.forEach((city: City) => {
const citiesLogItem = logCities.find(
(logItem: LogItem) => logItem.filepath === `cities/${city.code.toLowerCase()}.m3u`
)
if (!citiesLogItem) return
countryItem.children.add({
index: city.name,
name: city.name,
count: citiesLogItem.count,
link: `https://iptv-org.github.io/iptv/${citiesLogItem.filepath}`,
children: new Collection()
})
})
}
if (countryItem.count > 0 || countryItem.children.notEmpty()) {
items.add(countryItem)
}
})
const internationalLogItem = logCountries.find(
(logItem: LogItem) => logItem.filepath === 'countries/int.m3u'
)
if (internationalLogItem) {
items.push({
index: 'ZZ',
name: '🌐 International',
count: internationalLogItem.count,
link: `https://iptv-org.github.io/iptv/${internationalLogItem.filepath}`,
children: new Collection()
})
}
const undefinedLogItem = logCountries.find(
(logItem: LogItem) => logItem.filepath === `countries/undefined.m3u`
)
if (undefinedLogItem) {
items.push({
index: 'ZZZ',
name: 'Undefined',
count: undefinedLogItem.count,
link: `https://iptv-org.github.io/iptv/${undefinedLogItem.filepath}`,
children: new Collection()
})
}
items = items.orderBy(item => item.index)
const output = items
.map(item => {
let row = `- ${item.name} <code>${item.link}</code>`
item.children
.orderBy(item => item.index)
.forEach(item => {
row += `\r\n\ - ${item.name} <code>${item.link}</code>`
item.children
.orderBy(item => item.index)
.forEach(item => {
row += `\r\n\ - ${item.name} <code>${item.link}</code>`
})
})
return row
})
.join('\r\n')
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_countries.md', output)
}
}

View File

@@ -1,65 +0,0 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { Country } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class CountryTable implements Table {
constructor() {}
async make() {
const dataStorage = new Storage(DATA_DIR)
const countriesContent = await dataStorage.json('countries.json')
const countries = new Collection(countriesContent).map(data => new Country(data))
const countriesGroupedByCode = countries.keyBy((country: Country) => country.code)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
const parsed = parser.parse(generatorsLog)
let data = new Collection()
parsed
.filter((logItem: LogItem) => logItem.type === 'country')
.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const code = file.name().toUpperCase()
const [countryCode] = code.split('-') || ['', '']
const country = countriesGroupedByCode.get(countryCode)
if (country) {
data.add([
country.name,
`${country.flag} ${country.name}`,
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
} else {
data.add([
'ZZ',
'Undefined',
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
}
})
data = data
.orderBy(item => item[0])
.map(item => {
item.shift()
return item
})
const table = new HTMLTable(data.all(), [
{ name: 'Country' },
{ name: 'Channels', align: 'right' },
{ name: 'Playlist', nowrap: true }
])
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_countries.md', table.toString())
}
}

View File

@@ -1,5 +1,4 @@
export * from './categoryTable'
export * from './countryTable'
export * from './languageTable'
export * from './regionTable'
export * from './subdivisionTable'
export * from './categoriesTable'
export * from './countriesTable'
export * from './languagesTable'
export * from './regionsTable'

View File

@@ -1,18 +1,21 @@
import { Storage, Collection, File } from '@freearhey/core'
import { Storage, Collection, File, Dictionary } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { LOGS_DIR, README_DIR } from '../constants'
import { Language } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class LanguageTable implements Table {
constructor() {}
type LanguagesTableProps = {
languagesKeyByCode: Dictionary
}
export class LanguagesTable implements Table {
languagesKeyByCode: Dictionary
constructor({ languagesKeyByCode }: LanguagesTableProps) {
this.languagesKeyByCode = languagesKeyByCode
}
async make() {
const dataStorage = new Storage(DATA_DIR)
const languagesContent = await dataStorage.json('languages.json')
const languages = new Collection(languagesContent).map(data => new Language(data))
const languagesGroupedByCode = languages.keyBy((language: Language) => language.code)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
@@ -24,7 +27,7 @@ export class LanguageTable implements Table {
.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const languageCode = file.name()
const language: Language = languagesGroupedByCode.get(languageCode)
const language: Language = this.languagesKeyByCode.get(languageCode)
data.add([
language ? language.name : 'ZZ',

View File

@@ -1,62 +0,0 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { Region } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class RegionTable implements Table {
constructor() {}
async make() {
const dataStorage = new Storage(DATA_DIR)
const regionsContent = await dataStorage.json('regions.json')
const regions = new Collection(regionsContent).map(data => new Region(data))
const regionsGroupedByCode = regions.keyBy((region: Region) => region.code)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
let data = new Collection()
parser
.parse(generatorsLog)
.filter((logItem: LogItem) => logItem.type === 'region')
.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const regionCode = file.name().toUpperCase()
const region: Region = regionsGroupedByCode.get(regionCode)
if (region) {
data.add([
region.name,
region.name,
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
} else {
data.add([
'ZZZ',
'Undefined',
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
}
})
data = data
.orderBy(item => item[0])
.map(item => {
item.shift()
return item
})
const table = new HTMLTable(data.all(), [
{ name: 'Region', align: 'left' },
{ name: 'Channels', align: 'right' },
{ name: 'Playlist', align: 'left', nowrap: true }
])
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_regions.md', table.toString())
}
}

View File

@@ -0,0 +1,52 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { LOGS_DIR, README_DIR } from '../constants'
import { Region } from '../models'
import { Table } from './table'
type RegionsTableProps = {
regions: Collection
}
export class RegionsTable implements Table {
regions: Collection
constructor({ regions }: RegionsTableProps) {
this.regions = regions
}
async make() {
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
const parsed = parser.parse(generatorsLog)
const logRegions = parsed.filter((logItem: LogItem) => logItem.type === 'region')
let items = new Collection()
this.regions.forEach((region: Region) => {
const logItem = logRegions.find(
(logItem: LogItem) => logItem.filepath === `regions/${region.code.toLowerCase()}.m3u`
)
if (!logItem) return
items.add({
index: region.name,
name: region.name,
count: logItem.count,
link: `https://iptv-org.github.io/iptv/${logItem.filepath}`
})
})
items = items.orderBy(item => item.index)
const output = items
.map(item => {
return `- ${item.name} <code>${item.link}</code>`
})
.join('\r\n')
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_regions.md', output)
}
}

View File

@@ -1,72 +0,0 @@
import { Storage, Collection, File } from '@freearhey/core'
import { HTMLTable, LogParser, LogItem } from '../core'
import { Country, Subdivision } from '../models'
import { DATA_DIR, LOGS_DIR, README_DIR } from '../constants'
import { Table } from './table'
export class SubdivisionTable implements Table {
constructor() {}
async make() {
const dataStorage = new Storage(DATA_DIR)
const countriesContent = await dataStorage.json('countries.json')
const countries = new Collection(countriesContent).map(data => new Country(data))
const countriesGroupedByCode = countries.keyBy((country: Country) => country.code)
const subdivisionsContent = await dataStorage.json('subdivisions.json')
const subdivisions = new Collection(subdivisionsContent).map(data => new Subdivision(data))
const subdivisionsGroupedByCode = subdivisions.keyBy(
(subdivision: Subdivision) => subdivision.code
)
const parser = new LogParser()
const logsStorage = new Storage(LOGS_DIR)
const generatorsLog = await logsStorage.load('generators.log')
const parsed = parser.parse(generatorsLog)
const parsedSubdivisions = parsed.filter((logItem: LogItem) => logItem.type === 'subdivision')
let output = ''
countries.forEach((country: Country) => {
const parsedCountrySubdivisions = parsedSubdivisions.filter((logItem: LogItem) =>
logItem.filepath.includes(`subdivisions/${country.code.toLowerCase()}`)
)
if (!parsedCountrySubdivisions.length) return
output += `\r\n<details>\r\n<summary>${country.name}</summary>\r\n`
const data = new Collection()
parsedCountrySubdivisions.forEach((logItem: LogItem) => {
const file = new File(logItem.filepath)
const code = file.name().toUpperCase()
const [countryCode, subdivisionCode] = code.split('-') || ['', '']
const country = countriesGroupedByCode.get(countryCode)
if (country && subdivisionCode) {
const subdivision = subdivisionsGroupedByCode.get(code)
if (subdivision) {
data.add([
subdivision.name,
logItem.count,
`<code>https://iptv-org.github.io/iptv/${logItem.filepath}</code>`
])
}
}
})
const table = new HTMLTable(data.all(), [
{ name: 'Subdivision' },
{ name: 'Channels', align: 'right' },
{ name: 'Playlist', nowrap: true }
])
output += table.toString()
output += '\r\n</details>'
})
const readmeStorage = new Storage(README_DIR)
await readmeStorage.save('_subdivisions.md', output.trim())
}
}

20
scripts/types/city.d.ts vendored Normal file
View File

@@ -0,0 +1,20 @@
import { CountrySerializedData } from './country'
import { SubdivisionSerializedData } from './subdivision'
export type CitySerializedData = {
code: string
name: string
countryCode: string
country?: CountrySerializedData
subdivisionCode: string | null
subdivision?: SubdivisionSerializedData
wikidataId: string
}
export type CityData = {
code: string
name: string
country: string
subdivision: string | null
wikidata_id: string
}

View File

@@ -17,4 +17,5 @@ export type DataLoaderData = {
timezones: object | object[]
guides: object | object[]
streams: object | object[]
cities: object | object[]
}

View File

@@ -15,6 +15,7 @@ export type DataProcessorData = {
regionsKeyByCode: Dictionary
blocklistRecords: Collection
channelsKeyById: Dictionary
citiesKeyByCode: Dictionary
subdivisions: Collection
categories: Collection
countries: Collection
@@ -23,6 +24,8 @@ export type DataProcessorData = {
channels: Collection
regions: Collection
streams: Collection
cities: Collection
guides: Collection
feeds: Collection
logos: Collection
}

View File

@@ -1,12 +1,10 @@
import { Collection } from '@freearhey/core'
export type FeedData = {
channel: string
id: string
name: string
is_main: boolean
broadcast_area: Collection
languages: Collection
timezones: Collection
broadcast_area: string[]
languages: string[]
timezones: string[]
video_format: string
}

View File

@@ -1,9 +1,14 @@
import { CitySerializedData } from './city'
import { CountrySerializedData } from './country'
import { SubdivisionSerializedData } from './subdivision'
export type RegionSerializedData = {
code: string
name: string
countryCodes: string[]
countries?: CountrySerializedData[]
subdivisions?: SubdivisionSerializedData[]
cities?: CitySerializedData[]
}
export type RegionData = {

View File

@@ -1,12 +1,16 @@
import { CountrySerializedData } from './country'
export type SubdivisionSerializedData = {
code: string
name: string
countryCode: string
country?: CountrySerializedData
parentCode: string | null
}
export type SubdivisionData = {
code: string
name: string
country: string
parent: string | null
}

View File

@@ -67,8 +67,8 @@ https://mbc1-enc.edgenextcdn.net/out/v1/0965e4d7deae49179172426cbfb3bc5e/index.m
https://shd-gcp-live.edgenextcdn.net/live/bitmovin-mbc-1-na/eec141533c90dd34722c503a296dd0d8/index.m3u8
#EXTINF:-1 tvg-id="MBC1.ae",MBC 1 (1080p)
https://shls-live-enc.edgenextcdn.net/out/v1/0965e4d7deae49179172426cbfb3bc5e/index.m3u8
#EXTINF:-1 tvg-id="MBC2.ae",MBC 2 (480p)
https://edge66.magictvbox.com/liveApple/MBC_2/index.m3u8
#EXTINF:-1 tvg-id="MBC2.ae",MBC 2 (576p)
http://213.57.91.138:8000/play/a05k
#EXTINF:-1 tvg-id="MBC4.ae@SD",MBC 4 (1080p)
https://shd-gcp-live.edgenextcdn.net/live/bitmovin-mbc-4/24f134f1cd63db9346439e96b86ca6ed/index.m3u8
#EXTINF:-1 tvg-id="MBC5.ae@SD",MBC 5 (1080p)
@@ -139,3 +139,5 @@ http://213.57.91.138:8000/play/a05a
https://viamotionhsi.netplus.ch/live/eds/alarabiya/browser-HLS8/alarabiya.m3u8
#EXTINF:-1 tvg-id="Alarabiya.ae@SD",Alarabiya
https://viamotionhsi.netplus.ch/live/eds/alarabiya/browser-dash/alarabiya.mpd
#EXTINF:-1 tvg-id="MBCAction.ae@SD",MBC Action (576p)
http://213.57.91.138:8000/play/a05l

View File

@@ -77,3 +77,5 @@ https://live-radio-cf-vrt.akamaized.net/groupb/live/0f394a26-c87d-475e-8590-e9c6
https://live-radio-cf-vrt.akamaized.net/groupb/live/0f394a26-c87d-475e-8590-e9c6e79b28d9/live.isml/.mpd
#EXTINF:-1 tvg-id="VTM.be",VTM (720p)
https://dpp-live-events.medialaancdn.be/events/hls/aes/webstream1.m3u8
#EXTINF:-1 tvg-id="AB3.be@HD",AB3 HD
https://viamotionhsi.netplus.ch/live/eds/ab3/browser-HLS8/ab3.m3u8

View File

@@ -1,12 +1,8 @@
#EXTM3U
#EXTINF:-1 tvg-id="78TV.bg",7/8 TV (1080p)
https://ms4.sedemosmi.tv/live/M3E5ajhtdjJkaXBscmZubmUxMmh1cjN1bjZrbm5wZW8/index.m3u8
#EXTINF:-1 tvg-id="100AutoMotoTV.bg",100% Auto Moto TV (406p) [Not 24/7]
http://100automoto.tv:1935/bgtv1/autotv/playlist.m3u8
#EXTINF:-1 tvg-id="AgroTV.bg",Agro TV (480p)
https://restr2.bgtv.bg/agro/hls/agro.m3u8
#EXTINF:-1 tvg-id="BalkanikaTV.bg",Balkanika TV (270p)
rtsp://stream.teracomm.bg/balkanika
#EXTINF:-1 tvg-id="CityTV.bg",City TV (576p) [Not 24/7]
https://tv.city.bg/play/tshls/citytv/index.m3u8
#EXTINF:-1 tvg-id="DSTV.bg",DSTV (614p) [Not 24/7]
@@ -22,8 +18,6 @@ https://old2.rn-tv.com/k0/stream.m3u8
https://streamer1.streamhost.org/salive/GMIlcbgM/playlist.m3u8
#EXTINF:-1 tvg-id="MagicTV.bg",Magic TV (720p)
https://bss1.neterra.tv/magictv/magictv.m3u8
#EXTINF:-1 tvg-id="PIKTV.bg",PIK TV (720p)
https://s.piktv.bg/l/live/index.m3u8
#EXTINF:-1 tvg-id="PlovdivOrthodoxTV.bg",Plovdivska Pravoslavna TV (1080p)
http://78.130.149.196:1935/live/pptv.stream/playlist.m3u8
#EXTINF:-1 tvg-id="RMTV.bg",RMTV (288p)
@@ -38,9 +32,9 @@ https://streamer103.neterra.tv/tiankov-folk/live.m3u8
https://streamer103.neterra.tv/tiankov-orient/live.m3u8
#EXTINF:-1 tvg-id="TravelTV.bg",Travel TV (576p)
https://streamer103.neterra.tv/travel/live.m3u8
#EXTINF:-1 tvg-id="TV1.bg",TV 1 (720p)
https://tv1.cloudcdn.bg:8081/stream.m3u8
#EXTINF:-1 tvg-id="TVZagora.bg",TV Zagora (576p)
http://zagoratv.ddns.net:8080/tvzagora.m3u8
#EXTINF:-1 tvg-id="TVNBulgaria.bg",TVN-Bulgaria (1080p)
https://obs.friendshipchurch.eu/tvn/mystream.m3u8
#EXTINF:-1 tvg-id="BNT4.bg@SD",BNT 4
https://viamotionhsi.netplus.ch/live/eds/bntworld/browser-HLS8/bntworld.m3u8

View File

@@ -19,7 +19,7 @@ https://alba-bo-bolivision-bolivision.stream.mediatiquestream.com/index.m3u8
https://5fe2654d6127d.streamlock.net/cadenaa/videocadenaa/playlist.m3u8
#EXTINF:-1 tvg-id="Canal29TVA.bo@SD",Canal 29 TVA
https://play.agenciastreaming.com:19360/8160/8160.m3u8
#EXTINF:-1 tvg-id="Ceacom.bo",Ceacom [Not 24/7]
#EXTINF:-1 tvg-id="CEACOMTV.bo@SD",CEACOM TV [Not 24/7]
https://eu1.servers10.com:8081/ceacom/index.m3u8
#EXTINF:-1 tvg-id="CoralTV.bo",Coral TV (480p)
https://tv.mediacp.eu:8081/coraltv/index.m3u8

View File

@@ -137,3 +137,7 @@ https://viamotionhsi.netplus.ch/live/eds/onetv/browser-dash/onetv.mpd
https://viamotionhsi.netplus.ch/live/eds/rougetv/browser-dash/rougetv.mpd
#EXTINF:-1 tvg-id="Carac5.ch@SD",Carac 5 SD
https://viamotionhsi.netplus.ch/live/eds/teleswizz/browser-dash/teleswizz.mpd
#EXTINF:-1 tvg-id="NRTV.ch@SD",NRTV
https://viamotionhsi.netplus.ch/live/eds/nrtv/browser-HLS8/nrtv.m3u8
#EXTINF:-1 tvg-id="StarTV.ch@SD",Star TV
https://viamotionhsi.netplus.ch/live/eds/startv/browser-HLS8/startv.m3u8

View File

@@ -143,6 +143,8 @@ http://49.113.179.174:4022/udp/238.125.7.93:5140
http://110.19.156.172:9901/tsfile/live/1003_1.m3u8
#EXTINF:-1 tvg-id="NeiMonggolTV.cn",Nei Monggol TV
http://play1-qk.nmtv.cn/live/1686560387346365.m3u8
#EXTINF:-1 tvg-id="NeiMonggolTV.cn",Nei Monggol TV
https://cdn4.skygo.mn/live/disk1/NeigMGL/HLSv3-FTA/NeigMGL.m3u8
#EXTINF:-1 tvg-id="NeiMonggolTV2MongolianCultureChannel.cn",Nei Monggol TV 2 Mongolian Culture Channel
http://1.24.190.98:10080/hls/40/index.m3u8
#EXTINF:-1 tvg-id="NeiMonggolTV2MongolianCultureChannel.cn",Nei Monggol TV 2 Mongolian Culture Channel

View File

@@ -123,7 +123,7 @@ https://mist01.homestream.fun/hls/tlmas904/0_1/index.m3u8
https://k20.usastreams.com:8081/telered/index.m3u8
#EXTINF:-1 tvg-id="TeleSURCostaRica.cr",TeleSUR Costa Rica (720p) [Not 24/7]
https://s1.tvdatta.com:3582/live/telesurlive.m3u8
#EXTINF:-1 tvg-id="Teletica7.cr" http-referrer="https://bradmax.com/client/embed-player/c7c83ebb46fa89529a7383d933e2038729f8e4c9_13428?id=tv7&mediaUrl=https://cdn01.teletica.com/TeleticaLiveStream/Stream/playlist_dvr.m3u8&mediaUrl2=https://6zklxk9bdw9b-hls-live.5centscdn.com/TeleticaLiveStream/d072c3a8dde8622c607ecd258fd628e8.sdp/playlist_dvr.m3u8",Teletica 7 (720p) [Geo-blocked]
#EXTINF:-1 tvg-id="Teletica7.cr@SD" http-referrer="https://bradmax.com/client/embed-player/c7c83ebb46fa89529a7383d933e2038729f8e4c9_13428?id=tv7&mediaUrl=https://cdn01.teletica.com/TeleticaLiveStream/Stream/playlist_dvr.m3u8&mediaUrl2=https://6zklxk9bdw9b-hls-live.5centscdn.com/TeleticaLiveStream/d072c3a8dde8622c607ecd258fd628e8.sdp/playlist_dvr.m3u8",Teletica 7 (720p) [Geo-blocked]
#EXTVLCOPT:http-referrer=https://bradmax.com/client/embed-player/c7c83ebb46fa89529a7383d933e2038729f8e4c9_13428?id=tv7&mediaUrl=https://cdn01.teletica.com/TeleticaLiveStream/Stream/playlist_dvr.m3u8&mediaUrl2=https://6zklxk9bdw9b-hls-live.5centscdn.com/TeleticaLiveStream/d072c3a8dde8622c607ecd258fd628e8.sdp/playlist_dvr.m3u8
https://cdn01.teletica.com/TeleticaLiveStream/Stream/playlist_dvr.m3u8
#EXTINF:-1 tvg-id="TicaVision.cr@SD",TicaVision

View File

@@ -510,3 +510,11 @@ https://viamotionhsi.netplus.ch/live/eds/deluxemusic/browser-HLS8/deluxemusic.m3
https://viamotionhsi.netplus.ch/live/eds/swrbw/browser-HLS8/swrbw.m3u8
#EXTINF:-1 tvg-id="KiKA.de@HD",KiKA HD
https://viamotionhsi.netplus.ch/live/eds/kikahd/browser-HLS8/kikahd.m3u8
#EXTINF:-1 tvg-id="RTL.de@SD",RTL
https://viamotionhsi.netplus.ch/live/eds/rtl/browser-HLS8/rtl.m3u8
#EXTINF:-1 tvg-id="NDRFernsehen.de@Hamburg",NDR Fernsehen
https://viamotionhsi.netplus.ch/live/eds/ndr/browser-HLS8/ndr.m3u8
#EXTINF:-1 tvg-id="MDRFernsehen.de@Thuringen",MDR Fernsehen Thuringen
https://viamotionhsi.netplus.ch/live/eds/mdr/browser-HLS8/mdr.m3u8
#EXTINF:-1 tvg-id="ARDalpha.de@HD",ARD-alpha HD
https://viamotionhsi.netplus.ch/live/eds/bralpha/browser-HLS8/bralpha.m3u8

View File

@@ -56,3 +56,5 @@ https://d35j504z0x2vu2.cloudfront.net/v1/master/0bc8e8376bd8417a1b6761138aa41c26
https://rotana.hibridcdn.net/rotananet/cinemamasr_net-7Y83PP5adWixDF93/playlist.m3u8
#EXTINF:-1 tvg-id="WatanTV.eg",Watan TV (1080p)
https://rp.tactivemedia.com/watantv_source/live/playlist.m3u8
#EXTINF:-1 tvg-id="AlMasriyah.eg@SD",Al Masriyah
https://viamotionhsi.netplus.ch/live/eds/almasriyah/browser-HLS8/almasriyah.m3u8

View File

@@ -48,7 +48,7 @@ https://d1ujfw1zyymzyd.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68
https://d82pyvmcw2kdc.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-swfivzrzwamaq/live/fast-channel-animevisionclassics-efc8dc6d/fast-channel-animevisionclassics-efc8dc6d.m3u8
#EXTINF:-1 tvg-id="ArabiTV.es",Arabí TV (1080p)
https://streamtv2.elitecomunicacion.cloud:3628/live/arabitv2025live.m3u8
#EXTINF:-1 tvg-id="AragonTV.es",Aragón TV (720p) [Not 24/7]
#EXTINF:-1 tvg-id="AragonTVInternacional.es@SD",Aragon TV Internacional (720p) [Not 24/7]
https://cartv.streaming.aranova.es/hls/live/aragontv_canal1.m3u8
#EXTINF:-1 tvg-id="BabyTV.uk@Spain",BabyTV (Spain) (1080p)
http://185.189.225.150:85/BabyTV/index.m3u8
@@ -396,8 +396,8 @@ https://open.http.mp.streamamg.com/p/3001314/sp/300131400/playManifest/entryId/0
https://d2glyu450vvghm.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-21u4g5cjglv02/sm.m3u8
#EXTINF:-1 tvg-id="SolidariaTV.es",Solidaria TV (720p)
https://canadaremar2.todostreaming.es/live/solidariatv-webhd.m3u8
#EXTINF:-1 tvg-id="SpektraTV.es",SpektraTV (720p)
https://cloudvideo.servers10.com:8081/8136/index.m3u8
#EXTINF:-1 tvg-id="SpektraTV.es@SD",SpektraTV (720p)
https://cloudvideo.servers10.com:8081/8026/tracks-v1a1/index.m3u8
#EXTINF:-1 tvg-id="STZTelebista.es",STZ Telebista (1080p)
https://cloudvideo.servers10.com:8081/stztelebista/index.m3u8
#EXTINF:-1 tvg-id="SX3.es",SX3 (1080p) [Geo-blocked]
@@ -517,12 +517,12 @@ https://janus.xpbroadcasting.com:8443/hls/xptv2.m3u8
#EXTINF:-1 tvg-id="XPTVUS.es",XPTV US (720p)
https://janus.xpbroadcasting.com:8443/hls/xptvUS.m3u8
#EXTINF:-1 tvg-id="AtreseriesInternacional.es@SD",Atreseries Internacional (480p)
http://181.78.208.254:8080/play/a0d5/index.m3u8
http://38.180.133.31:8000/play/a0ko/index.m3u8
#EXTINF:-1 tvg-id="BCNGospelTV.es",BCN Gospel TV (1080p)
https://live1.ovalcast.com:3641/live/bcngospeltvlive.m3u8
#EXTINF:-1 tvg-id="Antena3Internacional.es@SD",Antena 3 Internacional (480p)
http://38.180.133.31:8000/play/a0ki/index.m3u8
#EXTINF:-1 tvg-id="AragonTVInternacional.es@SD",Aragon TV Internacional
#EXTINF:-1 tvg-id="AragonTV.es@SD",Aragon TV (720p)
https://viamotionhsi.netplus.ch/live/eds/aragontv/browser-HLS8/aragontv.m3u8
#EXTINF:-1 tvg-id="24HorasInternacional.es@SD",24 Horas Internacional
https://viamotionhsi.netplus.ch/live/eds/canal24horas/browser-HLS8/canal24horas.m3u8

View File

@@ -287,3 +287,7 @@ https://cdn.gunadarma.ac.id/streams/ugtv/ingestugtv.m3u8
https://ams.juraganstreaming.com:5443/LiveApp/streams/wesaltv.m3u8
#EXTINF:-1 tvg-id="ZeeBioskop.id",Zee Bioskop (360p) [Geo-blocked]
http://vod.linknetott.swiftcontent.com/Content/HLS/Live/Channel(ch161)/index.m3u8
#EXTINF:-1 tvg-id="SurabayaTV.id@SD",Surabaya TV (1080p)
https://e.siar.us/live/surabayatv.m3u8
#EXTINF:-1 tvg-id="BanjarTV.id@SD",Banjar TV (720p) [Not 24/7]
https://banjartv.siar.us/banjartv/live/playlist.m3u8

View File

@@ -166,8 +166,8 @@ https://cdn-apse1-prod.tsv2.amagi.tv/linear/amg01448-samsungin-dabanggin-samsung
https://live-dangal.akamaized.net/liveabr/playlist.m3u8
#EXTINF:-1 tvg-id="DarshanaTV.in@SD",Darshana TV (720p)
https://cdn-2.pishow.tv/live/1453/master.m3u8
#EXTINF:-1 tvg-id="DDArunPrabha.in",DD Arun Prabha
https://d2lk5u59tns74c.cloudfront.net/out/v1/308556d9fd1246adb479ef012a39bbfe/index_3.m3u8
#EXTINF:-1 tvg-id="DDArunPrabha.in@SD",DD Arun Prabha (360p)
https://d2lk5u59tns74c.cloudfront.net/out/v1/308556d9fd1246adb479ef012a39bbfe/index.m3u8
#EXTINF:-1 tvg-id="DDAssam.in",DD Assam
https://d2lk5u59tns74c.cloudfront.net/out/v1/d380bf5c167b4319a46cdd8204bc26b2/index.m3u8
#EXTINF:-1 tvg-id="DDAssam.in",DD Assam
@@ -196,14 +196,14 @@ https://cdn-6.pishow.tv/live/9/master.m3u8
https://cdn-1.pishow.tv/live/31/master.m3u8
#EXTINF:-1 tvg-id="DDMalayalam.in",DD Malayalam
https://d3eyhgoylams0m.cloudfront.net/v1/manifest/93ce20f0f52760bf38be911ff4c91ed02aa2fd92/ed7bd2c7-8d10-4051-b397-2f6b90f99acb/562ee8f9-9950-48a0-ba1d-effa00cf0478/2.m3u8
#EXTINF:-1 tvg-id="DDManipur.in",DD Manipur
https://ddmanipur.org/hls/stream1.m3u8
#EXTINF:-1 tvg-id="DDMeghalaya.in",DD Meghalaya
https://d3eyhgoylams0m.cloudfront.net/v1/manifest/93ce20f0f52760bf38be911ff4c91ed02aa2fd92/ed7bd2c7-8d10-4051-b397-2f6b90f99acb/dafc23f6-c3d9-44d7-8d31-27aa80efe0b7/2.m3u8
#EXTINF:-1 tvg-id="DDManipur.in@SD",DD Manipur (504p)
https://d2lk5u59tns74c.cloudfront.net/out/v1/8b75afc6576f450e8f554b6c877681d2/index.m3u8
#EXTINF:-1 tvg-id="DDMeghalaya.in@SD",DD Meghalaya (504p)
https://d3qs3d2rkhfqrt.cloudfront.net/out/v1/4f81bc8d13dd49b484da35988abb8729/index.m3u8
#EXTINF:-1 tvg-id="DDMizoram.in",DD Mizoram
https://d3eyhgoylams0m.cloudfront.net/v1/manifest/93ce20f0f52760bf38be911ff4c91ed02aa2fd92/ed7bd2c7-8d10-4051-b397-2f6b90f99acb/5f0e3651-3393-41d2-a137-a4513be8f3d5/2.m3u8
#EXTINF:-1 tvg-id="DDNagaland.in",DD Nagaland
https://d3eyhgoylams0m.cloudfront.net/v1/manifest/93ce20f0f52760bf38be911ff4c91ed02aa2fd92/ed7bd2c7-8d10-4051-b397-2f6b90f99acb/4437588d-6c41-4a61-91ca-33a6900617a6/2.m3u8
#EXTINF:-1 tvg-id="DDNagaland.in@SD",DD Nagaland (504p)
https://d2lk5u59tns74c.cloudfront.net/out/v1/29c92e0bef954a6d9b0908d1be29c1f0/index.m3u8
#EXTINF:-1 tvg-id="DDNational.in@HD",DD National HD (1080p)
https://d3qs3d2rkhfqrt.cloudfront.net/out/v1/40492a64c1db4a1385ba1a397d357d3a/index.m3u8
#EXTINF:-1 tvg-id="DDNews.in@SD",DD News (1080p)
@@ -308,8 +308,8 @@ http://akalmultimedia.net:1935/gdnslive/gdns-live/chunklist.m3u8
https://server.livelegitpro.in/globalpunjab/globalpunjab/index.m3u8
#EXTINF:-1 tvg-id="GlobalPunjab.in",Global Punjab (720p) [Not 24/7]
https://media.streambrothers.com:1936/8522/8522/playlist.m3u8
#EXTINF:-1 tvg-id="Goa365.in",Goa365 (720p)
https://asia.mslivestream.net/mslive/f9fe659e19d111baf97526ad526b55b4.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="Goa365.in@SD",Goa365 (1080p)
https://ktismaservers.in:3086/live/goa365live.m3u8
#EXTINF:-1 tvg-id="GoodNewsToday.in@SD",Good News Today (720p)
https://aajtaklive.vgcdn.net/v1/master/611d79b11b77e2f571934fd80ca1413453772ac7/3196cced-ce29-4219-9809-f07ccdaa02b9/vglive-sk-848805/master.m3u8
#EXTINF:-1 tvg-id="GoodShepherdTV.in",Good Shepherd TV (720p)
@@ -511,12 +511,12 @@ https://cdn-3.pishow.tv/live/1481/master.m3u8
https://5dd3981940faa.streamlock.net/mercytv/mercytv/playlist.m3u8
#EXTINF:-1 tvg-id="MetroTV.in",Metro TV (576p)
https://2nbyjxw5l53k-hls-live.qezycdn.com/metrotv/live.stream/playlist.m3u8
#EXTINF:-1 tvg-id="Mh1Music.in",MH One Music (1080p)
https://mhlive.paramountinfosystem.com/mhonemusictest/d0dbe915091d400bd8ee7f27f0791303.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="Mh1News.in",MH One News (1080p)
https://mhlive.paramountinfosystem.com/mhonetest/d0dbe915091d400bd8ee7f27f0791303.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="MHOneShraddha.in",MH One Shraddha (1080p)
https://mhlive.paramountinfosystem.com/mhoneshraddhatest/d0dbe915091d400bd8ee7f27f0791303.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="Mh1Music.in@SD",Mh 1 Music (720p)
https://mhonemusic.com/hls/1/stream.m3u8
#EXTINF:-1 tvg-id="Mh1News.in@SD",Mh 1 News (1080p)
https://mhonenews.in/hls/stream.m3u8
#EXTINF:-1 tvg-id="MHOneShraddha.in@SD",MH One Shraddha (720p)
https://mhoneshaddha.com/hls/1/stream.m3u8
#EXTINF:-1 tvg-id="MirrorNow.in",Mirror Now (720p)
https://pubads.g.doubleclick.net/ssai/event/DXkHhH2QSnma-HnE3QJqlA/master.m3u8
#EXTINF:-1 tvg-id="MKSix.in@SD",MK Six (720p) [Not 24/7]
@@ -803,8 +803,8 @@ https://cdn-1.pishow.tv/live/276/master.m3u8
https://yuppftalive.akamaized.net/080823/subhartitv/playlist.m3u8
#EXTINF:-1 tvg-id="SubhavaarthaTV.in",Subhavaartha TV (720p)
https://2mk9qae4rwyb-hls-live.wmncdn.net/shubhavartha/live.stream/playlist.m3u8
#EXTINF:-1 tvg-id="SudarshanNews.in",Sudarshan News (720p)
https://ott.livelegitpro.in/pusa/sudarshantv/index.m3u8
#EXTINF:-1 tvg-id="SudarshanNews.in@SD",Sudarshan News (1080p)
https://ott.livelegitpro.in/sudarshannews/sudarshannews/tracks-v1/index.fmp4.m3u8
#EXTINF:-1 tvg-id="SVBC2.in@SD",SVBC 2 (576p)
https://yuppftalive.akamaized.net/080823/svbc2tamil/playlist.m3u8
#EXTINF:-1 tvg-id="SVBC3.in",SVBC 3 (720p)
@@ -976,8 +976,8 @@ https://vg-zeefta.akamaized.net/ptnr-yupptv/title-zeepunjabharyanahima/v1/master
https://vg-zeefta.akamaized.net/ptnr-yupptv/title-zeerajashthannews/v1/master/611d79b11b77e2f571934fd80ca1413453772ac7/8e864b9a-1681-41a0-99a6-387490bc5b24/main.m3u8
#EXTINF:-1 tvg-id="ZeeSalaam.in",Zee Salaam (720p)
https://d3i8oqsdv88b3m.cloudfront.net/out/v1/08f6360f9104421f90319460c0e03f11/index.m3u8
#EXTINF:-1 tvg-id="ZeeUttarPradeshUttarakhand.in",Zee Uttar Pradesh/Uttarakhand (720p)
https://livetv-channels.b-cdn.net/8076/playlist.m3u8
#EXTINF:-1 tvg-id="ZeeUttarPradeshUttarakhand.in@SD",Zee Uttar Pradesh/Uttarakhand (720p)
https://duw35ict5q7th.cloudfront.net/index_3.m3u8
#EXTINF:-1 tvg-id="ZillarBartaNews.in",ZillarBarta News (720p)
https://live-stream.utkalbongo.com/utkalbongo/stream18/hls/zillarbartalive.m3u8
#EXTINF:-1 tvg-id="ZillarBartaNews.in",ZillarBarta News
@@ -996,3 +996,19 @@ https://d35j504z0x2vu2.cloudfront.net/v1/master/0bc8e8376bd8417a1b6761138aa41c26
http://217.20.112.199/asianet/index.m3u8
#EXTINF:-1 tvg-id="ChumbakTV.in@SD",Chumbak TV (720p)
https://cdn-1.pishow.tv/live/1451/master.m3u8
#EXTINF:-1 tvg-id="DDHimachalPradesh.in@SD",DD Himachal Pradesh (504p)
https://d3qs3d2rkhfqrt.cloudfront.net/out/v1/afd2e335b0ba40eb9bdf1096118c6ede/index.m3u8
#EXTINF:-1 tvg-id="RajPariwar.in@SD",Raj Pariwar (1080p) [Not 24/7]
https://livestream.rajtvnet.in/hlslive/Admin/px08241089/live/Raj_Pariwar/master_1.m3u8
#EXTINF:-1 tvg-id="RajNewsTelugu.in@SD",Raj News Telugu (1080p) [Not 24/7]
https://livestream.rajtvnet.in/hlslive/Admin/px08241089/live/Raj_News_Telugu/master_1.m3u8
#EXTINF:-1 tvg-id="DDTamil.in@SD",DD Tamil (1080p)
https://d2lk5u59tns74c.cloudfront.net/out/v1/abf46b14847e45499f4a47f3a9afe93d/index.m3u8
#EXTINF:-1 tvg-id="KolkataTV.in@SD",Kolkata TV (1080p)
https://d35j504z0x2vu2.cloudfront.net/v1/master/0bc8e8376bd8417a1b6761138aa41c26c7309312/kolkata-tv/index.m3u8
#EXTINF:-1 tvg-id="HNN24x7.in@SD",HNN 24x7 (576p)
https://ott.livelegitpro.in:9899/hnnnews/hnnnews/tracks-v1/index.fmp4.m3u8
#EXTINF:-1 tvg-id="BharatExpress.in@SD",Bharat Express (480p)
https://stream1.livebox.co.in/VCAREhls/live.m3u8
#EXTINF:-1 tvg-id="MunsifTV.in@SD",Munsif TV (720p)
https://d35j504z0x2vu2.cloudfront.net/v1/manifest/0bc8e8376bd8417a1b6761138aa41c26c7309312/munsif-tv/e5ae862b-c65c-4b17-b9a8-038853525c64/0.m3u8

View File

@@ -21,8 +21,6 @@ https://familyhls.avatv.live/hls/stream.m3u8
https://live20.bozztv.com/dvrfl05/gin-ayeneh/index.m3u8
#EXTINF:-1 tvg-id="CaltexTV.ir",Caltex Music (720p)
https://video.caltexmusic.com/hls/caltextv.m3u8
#EXTINF:-1 tvg-id="",Digi Movie [Not 24/7]
https://fastdehost.com/live/digimovie.m3u8
#EXTINF:-1 tvg-id="HispanTV.ir",Hispan TV
https://cdnlive.presstv.ir/live/smil:live.smil/playlist.m3u8
#EXTINF:-1 tvg-id="HodHodFarsiTV.ir@SD",HodHod Farsi TV
@@ -59,8 +57,6 @@ https://ca-rt.onetv.app:8443/ITN/index-0.m3u8
https://ca1.buximedia.com/itv/life/tracks-v1a1/mono.m3u8
#EXTINF:-1 tvg-id="ITVPersianMusic.ir",ITV Persian Music (1080p)
https://ca1.buximedia.com/itv/persian/tracks-v1a1/mono.m3u8
#EXTINF:-1 tvg-id="",King Movie [Not 24/7]
https://fastdehost.com/live/kingmovie.m3u8
#EXTINF:-1 tvg-id="MihanTV.ir",Mihan TV (720p)
https://iptv.mihantv.com/mihantv/playlist.m3u8
#EXTINF:-1 tvg-id="MohabatTV.ir",Mohabat TV (540p)
@@ -96,16 +92,6 @@ https://live20.bozztv.com/gin-36bay3/gin-saharafgh/tracks-v1a1/mono.m3u8
https://live20.bozztv.com/dvrfl05/gin-saharurdu/index.m3u8
#EXTINF:-1 tvg-id="SalamatTV.ir@SD",Salamat TV
https://live20.bozztv.com/dvrfl05/gin-iribsalamat/index.m3u8
#EXTINF:-1 tvg-id="",Serial Baran1 [Not 24/7]
https://fastdehost.com/live/serialbaran1.m3u8
#EXTINF:-1 tvg-id="",Serial Baran2 [Not 24/7]
https://server3.fastdehost.com/live/serialbaran2.m3u8
#EXTINF:-1 tvg-id="",Serial Baran3 [Not 24/7]
https://server3.fastdehost.com/live/serialbaran3.m3u8
#EXTINF:-1 tvg-id="",Serial Baran4 [Not 24/7]
https://server3.fastdehost.com/live/serialbaran4.m3u8
#EXTINF:-1 tvg-id="",Serial Baran5 [Not 24/7]
https://server4.fastdehost.com/live/serialbaran5.m3u8
#EXTINF:-1 tvg-id="SNNTV.ir",SNN TV (720p) [Not 24/7]
https://live2.snn.ir/hls/snn2_hd720/index.m3u8
#EXTINF:-1 tvg-id="TBNNejatTV.ir",TBN Nejat TV (720p)

View File

@@ -751,3 +751,7 @@ https://5db313b643fd8.streamlock.net/ZerounoTVEventi/ZerounoTVEventi/playlist.m3
https://5f22d76e220e1.streamlock.net/iuniortv/iuniortv/chunklist_w774879328.m3u8
#EXTINF:-1 tvg-id="BergamoTV.it@SD",Bergamo TV (1080p)
https://db142859fd5541b09de25d6507f1f2d3.msvdn.net/live/S17501676/oIxAsgEEA46M/playlist_dvr.m3u8
#EXTINF:-1 tvg-id="AntennaSudExtra.it@SD",Antenna Sud Extra (720p)
https://live.antennasudwebtv.it:9443/hls/vod92.m3u8
#EXTINF:-1 tvg-id="AntennaSud.it@SD",Antenna Sud (720p)
https://live.antennasudwebtv.it:9443/hls/vod.m3u8

View File

@@ -54,3 +54,7 @@ http://171.244.62.178/jptv2/get.php?id=4SlJSS46Vw5igmOdvfKMww==
http://171.244.62.178/jptv2/get.php?id=hnsnBqHDt2EXQupW2soBjw==
#EXTINF:-1 tvg-id="JOAKDTV.jp",JOAK-DTV
http://171.244.62.178/jptv2/get.php?id=mCOs5Hrdk31FTwR6IJj_hA==
#EXTINF:-1 tvg-id="JOIXDTV.jp@HD",JOIX-DTV (720p)
https://mt01.utako.moe/ytv/index.m3u8
#EXTINF:-1 tvg-id="NHKWorldJapan.jp@HD",NHK World-Japan HD
https://viamotionhsi.netplus.ch/live/eds/nhk/browser-HLS8/nhk.m3u8

View File

@@ -111,3 +111,9 @@ https://cdn4.skygo.mn/live/disk1/UlziiTV/HLSv3-FTA/UlziiTV.m3u8
https://cdn4.skygo.mn/live/disk1/SoyonGegeeruulegch/HLSv3-FTA/SoyonGegeeruulegch.m3u8
#EXTINF:-1 tvg-id="",Хөгжим (720p)
https://cdn4.skygo.mn/live/disk1/Khugjim/HLSv3-FTA/Khugjim.m3u8
#EXTINF:-1 tvg-id="SevenChannel.mn@SD",Seven Channel (480p)
https://cdn4.skygo.mn/live/disk1/TV7/HLS-FTA/TV7.m3u8
#EXTINF:-1 tvg-id="Cinema.mn@SD",Cinema
https://cdn4.skygo.mn/live/disk1/CinemaTV/HLSv3-FTA/CinemaTV.m3u8
#EXTINF:-1 tvg-id="GlobalTV.mn@SD",Global TV
https://cdn4.skygo.mn/live/disk1/GlobalTV/HLSv3-FTA/GlobalTV.m3u8

View File

@@ -402,3 +402,7 @@ https://stream.oursnetworktv.com/latin/encoder73/playlist.m3u8
https://stream8.mexiserver.com:1936/xtinetwork/xtinetwork/playlist.m3u8
#EXTINF:-1 tvg-id="ZAZ.mx",ZAZ
https://cloud.fastchannel.es/mic/manifiest/hls/zaztv/zaztv.m3u8
#EXTINF:-1 tvg-id="FoxSportsPremium.mx",Fox Sports Premium (1080p)
https://live20.bozztv.com/akamaissh101/ssh101/foxsports/playlist.m3u8
#EXTINF:-1 tvg-id="Canal5.mx",Canal 5 (720p)
http://104.238.205.28:8989/278329_.m3u8

View File

@@ -3,16 +3,6 @@
https://cdn6.163189.xyz/live/8tv/stream.m3u8
#EXTINF:-1 tvg-id="8TV.my",8TV
https://tonton-live-switch-ssar.akamaized.net/stream-8tv/master.m3u8?bpkio_serviceid=6c0958d82a830a02ca0936d9cfab8311
#EXTINF:-1 tvg-id="AstroAwani.my",Astro Awani (720p)
https://d2idp3hzkhjpih.cloudfront.net/out/v1/4b85d9c2bf97413eb0c9fd875599b837/index.m3u8
#EXTINF:-1 tvg-id="AstroBoxOfficeThangathirai.my",Astro Box Office Thangathirai (720p)
https://live20.bozztv.com/akamaissh101/ssh101/sungo546/playlist.m3u8
#EXTINF:-1 tvg-id="AstroVaanavil.my@SD",Astro Vaanavil
https://live20.bozztv.com/akamaissh101/ssh101/sungo543/playlist.m3u8
#EXTINF:-1 tvg-id="AstroVaanavil.my@SD",Astro Vaanavil
https://live20.bozztv.com/akamaissh101/ssh101/sungo545/playlist.m3u8
#EXTINF:-1 tvg-id="AstroVinmeen.my@SD",Astro Vinmeen
https://live20.bozztv.com/akamaissh101/ssh101/sungo544/playlist.m3u8
#EXTINF:-1 tvg-id="AwesomeTV.my",Awesome TV [Geo-blocked]
https://488b9e074624.ap-south-1.playback.live-video.net/api/video/v1/ap-south-1.533267421985.channel.B7bB1wHJRCnw.m3u8
#EXTINF:-1 tvg-id="BeritaRTM.my" http-referrer="https://rtm-player.glueapi.io/",Berita RTM [Geo-blocked]

View File

@@ -19,20 +19,6 @@ https://primetv-prod.akamaized.net/v1/prime-freeview-aes128.m3u8
https://tv.wyatts-server.com/stream/channelid/1977627680?auth=Lo47lPuhjUwYZIPv+NymH3qAyhMe1svINVM4Kac2fvA=&profile=pass
#EXTINF:-1 tvg-id="SkyOpen.nz@Plus1",Sky open +1 (576p) [Geo-blocked]
https://linear-p.media.skyone.co.nz/primeplus1.clear.m3u8
#EXTINF:-1 tvg-id="SkySport1.nz",Sky Sport 1 (1080p)
http://primestreams.tv:826/live/SF11/vulwBvtfo9/118585.ts
#EXTINF:-1 tvg-id="SkySport2.nz",Sky Sport 2 (1080p)
http://primestreams.tv:826/live/SF11/vulwBvtfo9/118586.ts
#EXTINF:-1 tvg-id="SkySport3.nz",Sky Sport 3 (1080p)
https://hls.sheepland.xyz/play/0/15?proxy=0
#EXTINF:-1 tvg-id="SkySport4.nz",Sky Sport 4 (1080p)
https://hls.sheepland.xyz/play/0/36?proxy=0
#EXTINF:-1 tvg-id="SkySport5.nz",Sky Sport 5 (1080p)
http://primestreams.tv:826/live/SF11/vulwBvtfo9/118589.ts
#EXTINF:-1 tvg-id="SkySport6.nz",Sky Sport 6 (1080p)
https://hls.sheepland.xyz/play/0/70?proxy=0
#EXTINF:-1 tvg-id="SkySport7.nz",Sky Sport 7 (1080p)
https://hls.sheepland.xyz/play/0/66?proxy=0
#EXTINF:-1 tvg-id="TeReo.nz",Te Reo
https://i.mjh.nz/.r/te-reo.m3u8
#EXTINF:-1 tvg-id="TVNZ1.nz@SD",TVNZ 1

View File

@@ -37,3 +37,5 @@ https://rds3gen.desdeparaguay.net/trecetv/trecetv_alta/playlist.m3u8
https://tigocloud.desdeparaguay.net/800tv/800tv/playlist.m3u8
#EXTINF:-1 tvg-id="VenusMedia.py",Venus Media (720p)
https://rds3gen.desdeparaguay.net/venusmedia/venusmedia/.m3u8
#EXTINF:-1 tvg-id="SucesoTV.py",Suceso TV [Not 24/7]
https://live.enhdtv.com:8081/8060/index.m3u8

View File

@@ -1,10 +1,10 @@
#EXTM3U
#EXTINF:-1 tvg-id="AlArabyTV.qa",Al Araby TV (1080p)
https://alarabyta.cdn.octivid.com/alaraby/smil:alaraby.stream.smil/chunklist.m3u8
#EXTINF:-1 tvg-id="AlArabyTV.qa@SD",Al Araby TV (1080p)
https://live.kwikmotion.com/alaraby1live/alaraby_abr/playlist.m3u8
#EXTINF:-1 tvg-id="AlArabyTV.qa",Al Araby TV (1080p)
https://stream.ads.ottera.tv/playlist.m3u8?network_id=5616
#EXTINF:-1 tvg-id="AlArabyTV2.qa",Al Araby TV 2 (1080p)
https://alarabyta.cdn.octivid.com/alaraby2n/smil:alaraby2n.stream.smil/chunklist.m3u8
#EXTINF:-1 tvg-id="AlArabyTV2.qa@SD",Al Araby TV 2 (1080p)
https://live.kwikmotion.com/alaraby2live/alaraby2.smil/playlist.m3u8
#EXTINF:-1 tvg-id="AlArabyTV2.qa",Al Araby TV 2 (1080p)
https://stream.ads.ottera.tv/playlist.m3u8?network_id=5617
#EXTINF:-1 tvg-id="AlJazeera.qa",Al Jazeera (1080p)
@@ -111,3 +111,5 @@ https://qatartv.akamaized.net/hls/live/2026574/qtv2/master.m3u8
https://streamer1.qna.org.qa/148133344_live/148133344_63.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="AlJazeera.qa@English",Al Jazeera English
https://viamotionhsi.netplus.ch/live/eds/aljazeera/browser-HLS8/aljazeera.m3u8
#EXTINF:-1 tvg-id="AlJazeeraDocumentary.qa@HD",Al Jazeera Documentary (1080p)
http://213.57.91.138:8000/play/a06h

View File

@@ -199,3 +199,5 @@ http://89.38.8.130:39443
https://viamotionhsi.netplus.ch/live/eds/tvrinternational/browser-HLS8/tvrinternational.m3u8
#EXTINF:-1 tvg-id="TVRInternational.ro@SD",TVR International
https://viamotionhsi.netplus.ch/live/eds/tvrinternational/browser-dash/tvrinternational.mpd
#EXTINF:-1 tvg-id="JimJam.ro" http-user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0",JimJam
https://saruman1.tharen.cfd/jimy/usergenq3n0lz7kr.m3u8

View File

@@ -307,3 +307,5 @@ http://hls.shansontv.cdnvideo.ru/shansontv/shansontv.sdp/playlist.m3u8
http://stream0.tv41.ru/live.m3u8
#EXTINF:-1 tvg-id="Yuvelirochka.ru",Ювелирочка ТВ (576p)
https://live-uvelirochka.cdnvideo.ru/uvelirochka/uvelirochka_720p3/playlist.m3u8
#EXTINF:-1 tvg-id="Home4K.ru",Home 4K (2160p)
http://178.217.72.66:8080/HOME_4K/index.m3u8

View File

@@ -32,12 +32,46 @@ https://kino-1.catcast.tv/content/37742/index.m3u8
#EXTINF:-1 tvg-id="MuzykaKino.ru@International",Музыка Кино International [Not 24/7]
https://kino-1.catcast.tv/content/37739/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoKlassika.ru",Сити Эдем КиноКлассика [Not 24/7]
https://v2.catcast.tv/content/34185/index.m3u8
https://cityeden.catcast.tv/content/34185/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoMistika.ru",Сити Эдем КиноМистика [Not 24/7]
https://v2.catcast.tv/content/40783/index.m3u8
https://cityeden.catcast.tv/content/40783/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoAction.ru",Сити Эдем КиноЭкшен [Not 24/7]
https://v2.catcast.tv/content/41333/index.m3u8
#EXTINF:-1 tvg-id="CityEdenTV.ru",Сити Эдем ТВ [Not 24/7]
https://v2.catcast.tv/content/34246/index.m3u8
https://cityeden.catcast.tv/content/41333/index.m3u8
#EXTINF:-1 tvg-id="CityEdenTV.ru",Сити Эдем ТВ Христианский [Not 24/7]
https://cityeden.catcast.tv/content/34246/index.m3u8
#EXTINF:-1 tvg-id="CityEdenTeleNovella.ru",Сити Эдем ТелеНовелла [Not 24/7]
https://v2.catcast.tv/content/46209/index.m3u8
https://cityeden.catcast.tv/content/46209/index.m3u8
#EXTINF:-1 tvg-id="CityEdenMedZdrav.ru",Сити Эдем МедЗдрав [Not 24/7]
https://cityeden.catcast.tv/content/47519/index.m3u8
#EXTINF:-1 tvg-id="CityEdenReceptyGurmana.ru",Сити Эдем Рецепты Гурмана [Not 24/7]
https://cityeden.catcast.tv/content/47516/index.m3u8
#EXTINF:-1 tvg-id="CityEdenAutoGid.ru",Сити Эдем АвтоГид [Not 24/7]
https://cityeden.catcast.tv/content/47515/index.m3u8
#EXTINF:-1 tvg-id="CityEdenMeditationMusic.ru",Сити Эдем Meditation Music [Not 24/7]
https://cityeden.catcast.tv/content/47410/index.m3u8
#EXTINF:-1 tvg-id="CityEdenClassicMusic.ru",Сити Эдем Классическая Музыка [Not 24/7]
https://cityeden.catcast.tv/content/47400/index.m3u8
#EXTINF:-1 tvg-id="CityEdenSirtakiTV.ru",Сити Эдем Сиртаки ТВ [Not 24/7]
https://cityeden.catcast.tv/content/46421/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoDrama.ru",Сити Эдем КиноДрама [Not 24/7]
https://cityeden.catcast.tv/content/45269/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoFantastika.ru",Сити Эдем КиноФантастика [Not 24/7]
https://cityeden.catcast.tv/content/45268/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoKomediya.ru",Сити Эдем КиноКомедия [Not 24/7]
https://cityeden.catcast.tv/content/41331/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoDetektiv.ru",Сити Эдем КиноДетектив [Not 24/7]
https://cityeden.catcast.tv/content/41327/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoArt.ru",Сити Эдем КиноАрт [Not 24/7]
https://cityeden.catcast.tv/content/38398/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoDok.ru",Сити Эдем КиноДок [Not 24/7]
https://cityeden.catcast.tv/content/38354/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoSemya.ru",Сити Эдем КиноСемья [Not 24/7]
https://v2.catcast.tv/content/38128/index.m3u8
#EXTINF:-1 tvg-id="CityEdenKinoAsia.ru",Сити Эдем КиноАзия [Not 24/7]
https://cityeden.catcast.tv/content/34393/index.m3u8
#EXTINF:-1 tvg-id="CityEdenBirmaPlay.ru",Сити Эдем Бирма Play [Not 24/7]
https://cityeden.catcast.tv/content/34364/index.m3u8
#EXTINF:-1 tvg-id="CityEdenPlay.ru",Сити Эдем Play Христианский Музыкальный [Not 24/7]
https://cityeden.catcast.tv/content/34100/index.m3u8
#EXTINF:-1 tvg-id="VHSTV.ru",VHS TV [Not 24/7]
https://v2.catcast.tv/content/47609/index.m3u8

View File

@@ -5,13 +5,5 @@ https://livetv.mylifeisgood.net.ru/channels/strwc.m3u8
https://livetv.mylifeisgood.net.ru/channels/strvf.m3u8
#EXTINF:-1 tvg-id="TERRA.ru",TERRA
https://livetv.mylifeisgood.net.ru/channels/terra.m3u8
#EXTINF:-1 tvg-id="MuzTV.ru",Муз-ТВ
https://livetv.mylifeisgood.net.ru/channels/muztvhd.m3u8
#EXTINF:-1 tvg-id="Friday.ru",Пятница!
https://livetv.mylifeisgood.net.ru/channels/fridayhd.m3u8
#EXTINF:-1 tvg-id="TV3.ru",ТВ-3
https://livetv.mylifeisgood.net.ru/channels/tv3hd.m3u8
#EXTINF:-1 tvg-id="TNT.ru",ТНТ
https://livetv.mylifeisgood.net.ru/channels/tnthd.m3u8
#EXTINF:-1 tvg-id="U.ru",Ю
https://livetv.mylifeisgood.net.ru/channels/u_ott_tv_hq.m3u8

View File

@@ -134,8 +134,6 @@ https://thaqafeyyah-ak.akamaized.net/out/v1/f6851f68ada94f82ae6b64a441eb5ab1/ind
https://live.kwikmotion.com/sbrksasaudiaradiolive/srpksasaudiaradio/playlist.m3u8
#EXTINF:-1 tvg-id="SBC.sa",SBC (1080p)
https://shd-gcp-live.edgenextcdn.net/live/bitmovin-sbc/90e09c0c28db26435799b4a14892a167/index.m3u8
#EXTINF:-1 tvg-id="SSCActionWaleed.sa",SSC Action Waleed (1080p) [Not 24/7]
https://shls-live-event2-prod-dub.shahid.net/out/v1/0456ede1a39145d98b3d8c8062ddc998/index.m3u8
#EXTINF:-1 tvg-id="Tarab.sa",Tarab (1080p)
https://shls-live-enc.edgenextcdn.net/out/v1/90143f040feb40589d18c57863d9e829/index.m3u8
#EXTINF:-1 tvg-id="Tarab.sa",Tarab (1080p)

View File

@@ -1,27 +1,19 @@
#EXTM3U
#EXTINF:-1 tvg-id="GMM25.th",GMM 25 (720p)
https://lb1-live-mv.v2h-cdn.com/hls/ffbf/gmm25/gmm25.m3u8
#EXTINF:-1 tvg-id="HappyTV65.th",Happy TV 65 (576p)
https://n-edge-1-th.v2h-cdn.com/happy/happy/playlist.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffbf/ugvhgvh/ugvhgvh.m3u8
#EXTINF:-1 tvg-id="JKN18.th",JKN 18 (1080p)
https://lb1-live-mv.v2h-cdn.com/hls/ffda/jkn18/jkn18.m3u8
#EXTINF:-1 tvg-id="LidoChannel.th",Lido Channel (720p)
https://n-edge-1-th.v2h-cdn.com/lido/lido/playlist.m3u8
#EXTINF:-1 tvg-id="DramaChannel.th",MV Mall ดี๊ดี (1080p)
https://n-edge-1-th.v2h-cdn.com/rama_m/rama/playlist.m3u8
#EXTINF:-1 tvg-id="DramaChannel.th",MV Mall DD (1080p)
https://lb1-live-mv.v2h-cdn.com/hls/fdee/mvmalldd/mvmalldd.m3u8
#EXTINF:-1 tvg-id="One31.th",ONE HD 31 (720p)
https://lb1-live-mv.v2h-cdn.com/hls/ffba/one/one.m3u8
#EXTINF:-1 tvg-id="SakalaChannel.th",Sakala Channel (1080p)
https://n-edge-1-th.v2h-cdn.com/scala/scala/playlist.m3u8
#EXTINF:-1 tvg-id="SiamChannel.th",Siam Channel (1080p)
https://n-edge-1-th.v2h-cdn.com/siam/siam/playlist.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffba/yogvfi/yogvfi.m3u8
#EXTINF:-1 tvg-id="TSports7.th",T Sports 7 (720p)
https://lb1-live-mv.v2h-cdn.com/hls/ffef/tsport/tsport.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffef/mulxvnghf/mulxvnghf.m3u8
#EXTINF:-1 tvg-id="Thaiban83.th",Thaiban 83 (576p)
https://n-edge-1-th.v2h-cdn.com/thaiban/thaiban/playlist.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffcd/thaibaan/thaibaan.m3u8
#EXTINF:-1 tvg-id="TNN16.th",TNN 16 (720p)
https://lb1-live-mv.v2h-cdn.com/hls/ffdc/tnn/tnn.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffdc/mugvhogvho/mugvhogvho.m3u8
#EXTINF:-1 tvg-id="True4U.th",True 4U (720)
https://lb1-live-mv.v2h-cdn.com/hls/ffca/true24/true24.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/ffca/mifainp/mifainp.m3u8
#EXTINF:-1 tvg-id="Channel5.th",TV5 HD (720p)
https://lb1-live-mv.v2h-cdn.com/hls/fffb/5hd/5hd.m3u8
https://lb1-live-mv.v2h-cdn.com/hls/fffb/muushk/muushk.m3u8

View File

@@ -1,4 +1,6 @@
#EXTM3U
#EXTINF:-1 tvg-id="FIFAPlus.uk@English",FIFA+ (720p)
https://a62dad94.wurl.com/master/f36d25e7e52f1ba8d7e56eb859c636563214f541/UmFrdXRlblRWLWV1X0ZJRkFQbHVzRW5nbGlzaF9ITFM/playlist.m3u8
#EXTINF:-1 tvg-id="AfghanistanInternational.uk",Afghanistan International (720p)
https://hls.afintl.com/hls/stream.m3u8
#EXTINF:-1 tvg-id="AfrobeatTVEntertainment.uk",Afrobeats (1080p)
@@ -310,3 +312,27 @@ https://viamotionhsi.netplus.ch/live/eds/cnbc/browser-HLS8/cnbc.m3u8
https://tv.ddns.vn/tv/bbcearth/index.m3u8
#EXTINF:-1 tvg-id="BBCLifestyle.uk@Asia",BBC Lifestyle Asia (1080p)
https://tv.ddns.vn/tv/bbclifestyle/index.m3u8
#EXTINF:-1 tvg-id="Manoto.uk",Manoto TV
https://m3u.iranvids.com/manoto/output.m3u8
#EXTINF:-1 tvg-id="More4.uk@HD",More4 HD
https://viamotionhsi.netplus.ch/live/eds/more4/browser-dash/more4.mpd
#EXTINF:-1 tvg-id="Film4.uk@HD",Film4 HD
https://viamotionhsi.netplus.ch/live/eds/film4/browser-dash/film4.mpd
#EXTINF:-1 tvg-id="BBCFourCBeebies.uk@HD",BBC Four/CBeebies
https://viamotionhsi.netplus.ch/live/eds/bbc4cbeebies/browser-dash/bbc4cbeebies.mpd
#EXTINF:-1 tvg-id="BBCThreeCBBC.uk@HD",BBC Three/CBBC
https://viamotionhsi.netplus.ch/live/eds/bbc3cbbc/browser-dash/bbc3cbbc.mpd
#EXTINF:-1 tvg-id="BBCTwo.uk@HD",BBC Two HD
https://viamotionhsi.netplus.ch/live/eds/bbc2/browser-dash/bbc2.mpd
#EXTINF:-1 tvg-id="ITV4.uk@SD",ITV4
https://viamotionhsi.netplus.ch/live/eds/itv4/browser-dash/itv4.mpd
#EXTINF:-1 tvg-id="ITV3.uk@SD",ITV3
https://viamotionhsi.netplus.ch/live/eds/itv3/browser-dash/itv3.mpd
#EXTINF:-1 tvg-id="ITV2.uk@SD",ITV2
https://viamotionhsi.netplus.ch/live/eds/itv2/browser-dash/itv2.mpd
#EXTINF:-1 tvg-id="Channel4.uk@UKHD",Channel 4 UK HD
https://viamotionhsi.netplus.ch/live/eds/channel4/browser-dash/channel4.mpd
#EXTINF:-1 tvg-id="Channel5.uk@HD",Channel 5 HD
https://viamotionhsi.netplus.ch/live/eds/channel5/browser-dash/channel5.mpd
#EXTINF:-1 tvg-id="BBCNews.uk@Europe",BBC News Europe
https://viamotionhsi.netplus.ch/live/eds/bbcworld/browser-HLS8/bbcworld.m3u8

View File

@@ -11,5 +11,3 @@ https://pac12-sportstribal.amagi.tv/playlist.m3u8
https://d2xeo83q8fcni6.cloudfront.net/v1/master/9d062541f2ff39b5c0f48b743c6411d25f62fc25/SkiTV-SportsTribal/193.m3u8
#EXTINF:-1 tvg-id="SportsGrid.us",SportsGrid (1080p)
https://sportsgrid-tribal.amagi.tv/playlist.m3u8
#EXTINF:-1 tvg-id="WorldPokerTour.us",World Poker Tour (1080p) [Not 24/7]
https://d3w4n3hhseniak.cloudfront.net/v1/master/9d062541f2ff39b5c0f48b743c6411d25f62fc25/WPT-SportsTribal/120.m3u8

View File

@@ -125,8 +125,8 @@ https://2nbyjjx7y53k-hls-live.5centscdn.com/cls040318/b0d2763968fd0bdd2dc0d44ba2
https://streams2.sofast.tv/v1/master/611d79b11b77e2f571934fd80ca1413453772ac7/be6f9eac-280e-4748-b866-2eb2463c1844/manifest.m3u8
#EXTINF:-1 tvg-id="BanningCityTV.us",Banning CityTV (Banning CA) (1080p)
https://vbfast-c.viebit.com/072e341f-100d-4da1-9c18-65370ebf35c6/playlist.m3u8
#EXTINF:-1 tvg-id="BBCAmerica.us",BBC America
https://dvrfl04.tulix.tv/teleup-bbca/index.m3u8
#EXTINF:-1 tvg-id="BBCAmerica.us@East",BBC America
https://bcovlive-a.akamaihd.net/7f5ec16d102f4b5d92e8e27bc95ff424/us-east-1/6240731308001/playlist.m3u8
#EXTINF:-1 tvg-id="BeachTVCSULB.us",Beach TV CSULB (160p) [Not 24/7]
http://stream04.amp.csulb.edu:1935/Beach_TV/smil:BeachTV.smil/playlist.m3u8
#EXTINF:-1 tvg-id="BeachTVFloridaAlabama.us",Beach TV Florida & Alabama (720p)
@@ -1042,3 +1042,7 @@ https://livechannel.mdc.akamaized.net/stitch/livechannel/1341/master1400000.m3u8
https://cineverse.g-mana.live/media/ac7cff3c-5bc3-4745-ac4d-56aadb586d00/profile/1/profileManifest.m3u8
#EXTINF:-1 tvg-id="BloombergTV.us@Europe",Bloomberg TV Europe
https://viamotionhsi.netplus.ch/live/eds/bloomberg/browser-HLS8/bloomberg.m3u8
#EXTINF:-1 tvg-id="P3TV.us",P3TV [Not 24/7]
https://5790d294af2dc.streamlock.net/8042/8042/playlist.m3u8
#EXTINF:-1 tvg-id="FilmRiseClassicTV.us@SD",FilmRise Classic TV (720p)
https://d2tv4k5moji5m7.cloudfront.net/v1/master/3722c60a815c199d9c0ef36c5b73da68a62b09d1/cc-lu4pzh9l4b57p/master.m3u8

View File

@@ -79,8 +79,6 @@ https://tvpass.org/live/HallmarkMoviesMysteriesEast/sd
https://tvpass.org/live/IFCEast/hd
#EXTINF:-1 tvg-id="IFC.us@East",IFC East (360p)
https://tvpass.org/live/IFCEast/sd
#EXTINF:-1 tvg-id="KABCDT1.us",KABC-DT1 (720p)
https://tvpass.org/live/abc-kabc-los-angeles-ca/hd
#EXTINF:-1 tvg-id="KABCDT1.us",KABC-DT1 (360p)
https://tvpass.org/live/abc-kabc-los-angeles-ca/sd
#EXTINF:-1 tvg-id="KCBSDT1.us",KCBS-DT1 (1080p)

View File

@@ -137,3 +137,9 @@ https://vod2live.univtec.com/manifest/4c41c0d8-e2e4-43cc-bd43-79afe715e1b3.m3u8
https://cloud.fastchannel.es/manifiest/hls/prog9/vepacotv.m3u8
#EXTINF:-1 tvg-id="VPItv.ve",VPItv (1080p)
https://ott3.streann.com/loadbalancer/services/public/channels/5d23d5882cdce61dae029fd8/playlist.m3u8
#EXTINF:-1 tvg-id="FortunaTV.ve",Fortuna TV (1080p)
https://streamtv.intervenhosting.net:3355/live/fortunatvlive.m3u8
#EXTINF:-1 tvg-id="LaraenRedes.ve",Lara en Redes TV (1080p)
https://streamtv.intervenhosting.net:3763/hybrid/play.m3u8
#EXTINF:-1 tvg-id="LGDTelevision.ve@SD",LGD Television (720p)
https://streamtv.intervenhosting.net:3403/hybrid/play.m3u8

View File

@@ -43,8 +43,6 @@ https://sabctretalh.cdn.mangomolo.com/lehae/smil:lehae.stream.smil/master.m3u8
https://sabconetanw.cdn.mangomolo.com/news/smil:news.stream.smil/master.m3u8
#EXTINF:-1 tvg-id="SeraphimTV.za",Seraphim TV [Not 24/7]
https://restream.churchtv247.co.za/Apostle/Hggc@24/1.m3u8
#EXTINF:-1 tvg-id="SuperSportRugby.za@SD",SuperSport Rugby
https://live20.bozztv.com/trn03/gin-ssrugby/index.m3u8
#EXTINF:-1 tvg-id="TBNAfrica.za",TBN Africa (1080p)
https://tbn-jw.cdn.vustreams.com/live/tbn-africa/live.isml/master.m3u8
#EXTINF:-1 tvg-id="ZeeBollymovies.za@SD",Zee Bollymovies (1080p)

View File

@@ -1,5 +1,3 @@
#EXTM3U
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/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

View File

@@ -0,0 +1,9 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8

View File

@@ -1,26 +1,16 @@
#EXTM3U
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Andorra",ATV
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Canada",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/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="Canada",Meteomedia
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Kazakhstan",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Kyrgyzstan",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Russia",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Tajikistan",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Turkmenistan",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Uzbekistan",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#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="International",BBC News HD
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="International",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="International",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="International",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#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

View File

@@ -1,53 +0,0 @@
#EXTM3U
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Americas",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/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="Americas",Meteomedia
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Asia",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Asia",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Central Asia",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Commonwealth of Independent States",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Commonwealth of Independent States",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Europe",ATV
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Europe",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Europe",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Europe, the Middle East and Africa",ATV
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="Europe, the Middle East and Africa",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="Europe, the Middle East and Africa",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="North America",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/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="North America",Meteomedia
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Northern America",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/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="Northern America",Meteomedia
http://encodercdn1.frontline.ca/encoder181/output/Meteo_Media_720p/playlist.m3u8
#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="International",BBC News HD
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index.m3u8
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="International",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#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
#KODIPROP:inputstream=inputstream.adaptive
#KODIPROP:inputstream.adaptive.manifest_type=mpd
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=13f2e056-53fe-4469-ba6d-999970dbe549&userToken=v9ZVSksv4S7rT55o10dmYNRa4asye3z05eWCFxD%2FFYIlTJEpuf6tF8asPcyQOFq0h5opS%2B6WoMxnshWkihpHq5qrdrBEZ69piE94J9Feh385snGOqK3PYO7tLLjxmsCAe%2B9%2BNnurSSO5RCAIRsL125nSj1eOR%2F1GSKOgGH80HK2FDLiePxPkeaAxuWzacNBB%2FqnIGGxfe3GlmN65cU9F8WEpKFDlaxW%2Fv3ZSLAp3%2BZEq1aZXJ6Oz%2Fi0diD0EybH7|Content-Type=application/octet-stream|R{SSM}|
http://1111296894.rsc.cdn77.org/LS-ATL-54548-6/index2.m3u8|Referer="https://referer.xyz/"|User-Agent="Mozilla/5.0 (iPhone; CPU iPhone OS 17_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"|Origin="https://origin.xyz"
#EXTINF:-1 tvg-id="AndorraTV.ad@HD" tvg-logo="https://i.imgur.com/CnhTn8i.png" group-title="Undefined",ATV HD
https://iptv-all.lanesh4d0w.repl.co/andorra/atv_hd
#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@HD" tvg-logo="https://i.imgur.com/ciTJrnl.png" group-title="Undefined",Zoo (720p)
https://iptv-all.lanesh4d0w.repl.co/andorra/zoo

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1,5 +1,11 @@
#EXTM3U
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.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="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1,4 +1,8 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1,3 +1,7 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]
http://gohoski.fvds.ru:3000/mediabay/162/index.m3u8

View File

@@ -0,0 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1,4 +1,8 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]

View File

@@ -1,6 +1,10 @@
#EXTM3U
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Undefined",ATV
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]

View File

@@ -1,6 +1,10 @@
#EXTM3U
#EXTINF:-1 tvg-id="AndorraTV.ad@SD" tvg-logo="https://i.imgur.com/BnhTn8i.png" group-title="Undefined",ATV
https://iptv-all.lanesh4d0w.repl.co/andorra/atv
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8
#EXTINF:-1 tvg-id="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8
#EXTINF:-1 tvg-id="ElTR.kg" tvg-logo="https://i.ibb.co/r6czQwQ/365049798-774721644658455-5702658175909463406-n-2.png" group-title="General",ЭлТР (480p) [Not 24/7]

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1,5 +1,11 @@
#EXTM3U
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.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="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8

View File

@@ -1,5 +1,11 @@
#EXTM3U
#EXTINF:-1 tvg-id="5AABTV.ca" tvg-logo="" group-title="Undefined",5AAB TV
http://158.69.124.9:1935/5aabtv/5aabtv/playlist.m3u8
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.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="LDPRTV.ru" tvg-logo="https://iptvx.one/icn/ldpr-tv.png" group-title="General",ЛДПР ТВ (1080p)
http://46.46.143.222:1935/live/mp4:ldpr.stream/blocked.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

View File

@@ -1 +1,5 @@
#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
#EXTINF:-1 tvg-id="DunaWorld.hu" tvg-logo="https://i.imgur.com/uOBQJZS.png" group-title="Undefined",Duna World (576i)
http://146.59.85.40:89/dunaworld/index.m3u8

Some files were not shown because too many files have changed in this diff Show More