diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6f5ec2cee4..92f4f851a6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -90,13 +90,13 @@ streams/fr.m3u
│ 7 │ AlpedHuezTV.fr │ https://edge.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8 │ HTTP_NOT_FOUND │
```
-After that, all you have to do is report any broken streams you find.
+Also, if you add the `--fix` option to the command, the script will automatically remove all broken streams it finds from your local copy of playlists:
-### How to replace a broken stream?
+```sh
+npm run playlist:test streams/fr.m3u --- --fix
+```
-This can be done either by filling out this [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams%3Aedit&projects=&template=2_streams_edit.yml&title=Edit%3A+).
-
-Either by directly updating the files in the [/streams](/streams) folder and then creating a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests).
+After that, all you need to do is report the broken streams you found via the [form](https://github.com/iptv-org/iptv/issues/new?assignees=&labels=streams:remove&projects=&template=3_streams_report.yml&title=Broken%3A+) or create a [pull request](https://github.com/iptv-org/iptv/pulls) with updated playlists.
### How to remove my channel from playlist?
diff --git a/PLAYLISTS.md b/PLAYLISTS.md
index d6da28c5f2..ea6a5dd9e8 100644
--- a/PLAYLISTS.md
+++ b/PLAYLISTS.md
@@ -25,23 +25,23 @@ Same thing, but split up into separate files:
| Animation | 60 | https://iptv-org.github.io/iptv/categories/animation.m3u |
| Auto | 17 | https://iptv-org.github.io/iptv/categories/auto.m3u |
| Business | 68 | https://iptv-org.github.io/iptv/categories/business.m3u |
- | Classic | 49 | https://iptv-org.github.io/iptv/categories/classic.m3u |
+ | Classic | 50 | https://iptv-org.github.io/iptv/categories/classic.m3u |
| Comedy | 79 | https://iptv-org.github.io/iptv/categories/comedy.m3u |
| Cooking | 32 | https://iptv-org.github.io/iptv/categories/cooking.m3u |
- | Culture | 167 | https://iptv-org.github.io/iptv/categories/culture.m3u |
+ | Culture | 168 | https://iptv-org.github.io/iptv/categories/culture.m3u |
| Documentary | 109 | https://iptv-org.github.io/iptv/categories/documentary.m3u |
| Education | 180 | https://iptv-org.github.io/iptv/categories/education.m3u |
- | Entertainment | 607 | https://iptv-org.github.io/iptv/categories/entertainment.m3u |
+ | Entertainment | 609 | https://iptv-org.github.io/iptv/categories/entertainment.m3u |
| Family | 56 | https://iptv-org.github.io/iptv/categories/family.m3u |
- | General | 2421 | https://iptv-org.github.io/iptv/categories/general.m3u |
+ | General | 2436 | https://iptv-org.github.io/iptv/categories/general.m3u |
| Interactive | 1 | https://iptv-org.github.io/iptv/categories/interactive.m3u |
- | Kids | 247 | https://iptv-org.github.io/iptv/categories/kids.m3u |
+ | Kids | 248 | https://iptv-org.github.io/iptv/categories/kids.m3u |
| Legislative | 189 | https://iptv-org.github.io/iptv/categories/legislative.m3u |
| Lifestyle | 98 | https://iptv-org.github.io/iptv/categories/lifestyle.m3u |
| Movies | 376 | https://iptv-org.github.io/iptv/categories/movies.m3u |
- | Music | 624 | https://iptv-org.github.io/iptv/categories/music.m3u |
+ | Music | 630 | https://iptv-org.github.io/iptv/categories/music.m3u |
| News | 861 | https://iptv-org.github.io/iptv/categories/news.m3u |
- | Outdoor | 44 | https://iptv-org.github.io/iptv/categories/outdoor.m3u |
+ | Outdoor | 45 | https://iptv-org.github.io/iptv/categories/outdoor.m3u |
| Public | 41 | https://iptv-org.github.io/iptv/categories/public.m3u |
| Relax | 4 | https://iptv-org.github.io/iptv/categories/relax.m3u |
| Religious | 727 | https://iptv-org.github.io/iptv/categories/religious.m3u |
@@ -52,7 +52,7 @@ Same thing, but split up into separate files:
| Travel | 41 | https://iptv-org.github.io/iptv/categories/travel.m3u |
| Weather | 16 | https://iptv-org.github.io/iptv/categories/weather.m3u |
| XXX | 0 | https://iptv-org.github.io/iptv/categories/xxx.m3u |
- | Undefined | 3345 | https://iptv-org.github.io/iptv/categories/undefined.m3u |
+ | Undefined | 3343 | https://iptv-org.github.io/iptv/categories/undefined.m3u |
@@ -127,7 +127,7 @@ Same thing, but split up into separate files:
| Dutch | 180 | https://iptv-org.github.io/iptv/languages/nld.m3u |
| Dyula | 1 | https://iptv-org.github.io/iptv/languages/dyu.m3u |
| Egyptian Arabic | 1 | https://iptv-org.github.io/iptv/languages/arz.m3u |
- | English | 2360 | https://iptv-org.github.io/iptv/languages/eng.m3u |
+ | English | 2357 | https://iptv-org.github.io/iptv/languages/eng.m3u |
| Estonian | 9 | https://iptv-org.github.io/iptv/languages/est.m3u |
| Ewe | 1 | https://iptv-org.github.io/iptv/languages/ewe.m3u |
| Faroese | 3 | https://iptv-org.github.io/iptv/languages/fao.m3u |
@@ -135,7 +135,7 @@ Same thing, but split up into separate files:
| Filipino | 2 | https://iptv-org.github.io/iptv/languages/fil.m3u |
| Finnish | 16 | https://iptv-org.github.io/iptv/languages/fin.m3u |
| Fon | 2 | https://iptv-org.github.io/iptv/languages/fon.m3u |
- | French | 492 | https://iptv-org.github.io/iptv/languages/fra.m3u |
+ | French | 491 | https://iptv-org.github.io/iptv/languages/fra.m3u |
| Fulah | 2 | https://iptv-org.github.io/iptv/languages/ful.m3u |
| Gaelic | 2 | https://iptv-org.github.io/iptv/languages/gla.m3u |
| Galician | 2 | https://iptv-org.github.io/iptv/languages/glg.m3u |
@@ -177,7 +177,7 @@ Same thing, but split up into separate files:
| Konabéré | 1 | https://iptv-org.github.io/iptv/languages/bbo.m3u |
| Kongo | 2 | https://iptv-org.github.io/iptv/languages/kon.m3u |
| Konkani (macrolanguage) | 3 | https://iptv-org.github.io/iptv/languages/kok.m3u |
- | Korean | 88 | https://iptv-org.github.io/iptv/languages/kor.m3u |
+ | Korean | 89 | https://iptv-org.github.io/iptv/languages/kor.m3u |
| Kumam | 1 | https://iptv-org.github.io/iptv/languages/kdi.m3u |
| Kurdish | 32 | https://iptv-org.github.io/iptv/languages/kur.m3u |
| Lango (Uganda) | 1 | https://iptv-org.github.io/iptv/languages/laj.m3u |
@@ -221,7 +221,7 @@ Same thing, but split up into separate files:
| Pashto | 27 | https://iptv-org.github.io/iptv/languages/pus.m3u |
| Persian | 228 | https://iptv-org.github.io/iptv/languages/fas.m3u |
| Polish | 83 | https://iptv-org.github.io/iptv/languages/pol.m3u |
- | Portuguese | 252 | https://iptv-org.github.io/iptv/languages/por.m3u |
+ | Portuguese | 253 | https://iptv-org.github.io/iptv/languages/por.m3u |
| Pulaar | 4 | https://iptv-org.github.io/iptv/languages/fuc.m3u |
| Quechua | 1 | https://iptv-org.github.io/iptv/languages/que.m3u |
| Romanian | 105 | https://iptv-org.github.io/iptv/languages/ron.m3u |
@@ -238,7 +238,7 @@ Same thing, but split up into separate files:
| South African Sign Language | 1 | https://iptv-org.github.io/iptv/languages/sfs.m3u |
| South Ndebele | 1 | https://iptv-org.github.io/iptv/languages/nbl.m3u |
| Southern Samo | 1 | https://iptv-org.github.io/iptv/languages/sbd.m3u |
- | Spanish | 1692 | https://iptv-org.github.io/iptv/languages/spa.m3u |
+ | Spanish | 1716 | https://iptv-org.github.io/iptv/languages/spa.m3u |
| Standard Arabic | 1 | https://iptv-org.github.io/iptv/languages/arb.m3u |
| Sundanese | 3 | https://iptv-org.github.io/iptv/languages/sun.m3u |
| Swahili | 20 | https://iptv-org.github.io/iptv/languages/swa.m3u |
@@ -280,7 +280,7 @@ Same thing, but split up into separate files:
| Yue Chinese | 6 | https://iptv-org.github.io/iptv/languages/yue.m3u |
| Zarma | 1 | https://iptv-org.github.io/iptv/languages/dje.m3u |
| Zulu | 1 | https://iptv-org.github.io/iptv/languages/zul.m3u |
- | Undefined | 1852 | https://iptv-org.github.io/iptv/languages/undefined.m3u |
+ | Undefined | 1853 | https://iptv-org.github.io/iptv/languages/undefined.m3u |
@@ -513,10 +513,13 @@ Same thing, but split up into separate files:
- Neiva https://iptv-org.github.io/iptv/cities/conva.m3u
- Narino https://iptv-org.github.io/iptv/subdivisions/co-nar.m3u
- Pasto https://iptv-org.github.io/iptv/cities/copso.m3u
+ - Norte de Santander https://iptv-org.github.io/iptv/subdivisions/co-nsa.m3u
+ - Cúcuta https://iptv-org.github.io/iptv/cities/cocuc.m3u
- San Andres https://iptv-org.github.io/iptv/subdivisions/co-sap.m3u
- San Andrés https://iptv-org.github.io/iptv/cities/cosac.m3u
- Valle del Cauca https://iptv-org.github.io/iptv/subdivisions/co-vac.m3u
- Cali https://iptv-org.github.io/iptv/cities/coclo.m3u
+ - Tuluá https://iptv-org.github.io/iptv/cities/coulq.m3u
- 🇨🇷 Costa Rica https://iptv-org.github.io/iptv/countries/cr.m3u
- Cartago https://iptv-org.github.io/iptv/subdivisions/cr-c.m3u
- Puntarenas https://iptv-org.github.io/iptv/subdivisions/cr-p.m3u
diff --git a/scripts/commands/playlist/test.ts b/scripts/commands/playlist/test.ts
index 9446e8c4ad..d428aca167 100644
--- a/scripts/commands/playlist/test.ts
+++ b/scripts/commands/playlist/test.ts
@@ -4,13 +4,13 @@ import { ROOT_DIR, STREAMS_DIR } from '../../constants'
import { Logger, Collection } from '@freearhey/core'
import { program, OptionValues } from 'commander'
import { Storage } from '@freearhey/storage-js'
-import { Stream } from '../../models'
+import { Playlist, Stream } from '../../models'
+import { truncate } from '../../utils'
import { loadData } from '../../api'
import { eachLimit } from 'async'
import dns from 'node:dns'
import chalk from 'chalk'
import os from 'node:os'
-import { truncate } from '../../utils'
const LIVE_UPDATE_INTERVAL = 5000
const LIVE_UPDATE_MAX_STREAMS = 100
@@ -21,6 +21,7 @@ const results: { [key: string]: string } = {}
let interval: string | number | NodeJS.Timeout | undefined
let streams = new Collection()
let isLiveUpdateEnabled = true
+const errorStatusCodes = ['ENOTFOUND', 'HTTP_404_NOT_FOUND', 'HTTP_404_UNKONWN_ERROR']
program
.argument('[filepath...]', 'Path to file to test')
@@ -37,12 +38,14 @@ program
(value: string) => parseInt(value),
30000
)
+ .option('--fix', 'Remove all broken links found from files')
.parse(process.argv)
const options: OptionValues = program.opts()
const logger = new Logger()
const tester = new StreamTester({ options })
+const rootStorage = new Storage(ROOT_DIR)
async function main() {
if (await isOffline()) {
@@ -54,7 +57,6 @@ async function main() {
await loadData()
logger.info('loading streams...')
- const rootStorage = new Storage(ROOT_DIR)
const parser = new PlaylistParser({
storage: rootStorage
})
@@ -94,8 +96,9 @@ async function runTest(stream: Stream) {
const result: StreamTesterResult = await tester.test(stream)
+ stream.statusCode = result.status.code
+
let status = ''
- const errorStatusCodes = ['ENOTFOUND', 'HTTP_404_NOT_FOUND', 'HTTP_404_UNKONWN_ERROR']
if (result.status.ok) status = chalk.green('OK')
else if (errorStatusCodes.includes(result.status.code)) {
status = chalk.red(result.status.code)
@@ -144,7 +147,21 @@ function drawTable() {
}
}
-function onFinish(error: Error | null | undefined) {
+async function removeBrokenLinks() {
+ const streamsGrouped = streams.groupBy((stream: Stream) => stream.filepath)
+ for (const filepath of streamsGrouped.keys()) {
+ let streams: Collection = new Collection(streamsGrouped.get(filepath))
+
+ streams = streams.filter((stream: Stream) =>
+ !stream.statusCode ? true : !errorStatusCodes.includes(stream.statusCode)
+ )
+
+ const playlist = new Playlist(streams, { public: false })
+ await rootStorage.save(filepath, playlist.toString())
+ }
+}
+
+async function onFinish(error: Error | null | undefined) {
clearInterval(interval)
if (error) {
@@ -152,6 +169,10 @@ function onFinish(error: Error | null | undefined) {
process.exit(1)
}
+ if (options.fix) {
+ await removeBrokenLinks()
+ }
+
drawTable()
if (errors > 0 || warnings > 0) {
diff --git a/scripts/models/stream.ts b/scripts/models/stream.ts
index 002a6cc2e1..31b3926f80 100644
--- a/scripts/models/stream.ts
+++ b/scripts/models/stream.ts
@@ -13,6 +13,7 @@ export class Stream extends sdk.Models.Stream {
removed: boolean = false
tvgId?: string
label: string | null
+ statusCode?: string
updateWithIssue(issueData: IssueData): this {
const data = {
diff --git a/streams/br.m3u b/streams/br.m3u
index 8bce9e8b71..f5b0d6df94 100644
--- a/streams/br.m3u
+++ b/streams/br.m3u
@@ -414,3 +414,5 @@ http://unitvaovivo.ufrgs.br:8080/live.ogg
https://sistemavrt.vrtchannel.tv.br:3473/stream/play.m3u8
#EXTINF:-1 tvg-id="VV8TV.br@SD",VV8 TV (720p)
https://video01.kshost.com.br/seap8272/seap8272/playlist.m3u8
+#EXTINF:-1 tvg-id="Nickelodeon.br@SD",Nickelodeon (480p)
+http://45.235.0.78/Nickelodeon/playlist.m3u8
diff --git a/streams/ca.m3u b/streams/ca.m3u
index 0c2aba83ad..69fccdf3d1 100644
--- a/streams/ca.m3u
+++ b/streams/ca.m3u
@@ -293,3 +293,5 @@ https://5caf24a595d94.streamlock.net:1937/8132/8132/playlist.m3u8
https://wowzastream.westmancom.com/wcgtvlive/wcgtvPSA.stream/master.m3u8
#EXTINF:-1 tvg-id="TSN1.ca@SD",TSN1 (1080p)
https://fl1.moveonjoy.com/TSN_1/mpegts
+#EXTINF:-1 tvg-id="StingrayRememberthe80s.ca@SD",Stingray Remember the 80s
+https://d39g1vxj2ef6in.cloudfront.net/v1/manifest/3fec3e5cac39a52b2132f9c66c83dae043dc17d4/prod-rakuten-stitched/68cc5f97-cf6c-4ff7-9125-f56f272dbcb6/1.m3u8
diff --git a/streams/co.m3u b/streams/co.m3u
index 5a7e19daef..c0fabc1092 100644
--- a/streams/co.m3u
+++ b/streams/co.m3u
@@ -1,9 +1,11 @@
#EXTM3U
+#EXTINF:-1 tvg-id="ATNTelevision.co@SD",ATN Televisión (720p) [Not 24/7]
+https://streaming5.globalhostla.com/rtplive/atntelevision/playlist.m3u8
#EXTINF:-1 tvg-id="AvivamientoTV.co@SD",Avivamiento TV (1080p) [Not 24/7]
https://s1.abntelevision.com/avivamientoabr/stream/avivamientohd/avivamientohd/playlist.m3u8
-#EXTINF:-1 tvg-id="CanalVisionDorada.co@SD",Bum Televisión (720p) [Not 24/7]
+#EXTINF:-1 tvg-id="BUMTelevision.co@SD",BUM Televisión (720p) [Not 24/7]
https://movil.ejeserver.com/live/visiondorada.m3u8
-#EXTINF:-1 tvg-id="CanalVisionDorada.co@SD",Bum Televisión (720p) [Not 24/7]
+#EXTINF:-1 tvg-id="BUMTelevision.co@SD",BUM Televisión (720p) [Not 24/7]
https://video.ejeserver.com/live/visiondorada.m3u8
#EXTINF:-1 tvg-id="Cablenoticias.co@SD",Cablenoticias (1080p)
https://5ea86ddd14ce7.streamlock.net/live/cable09061970/playlist.m3u8
@@ -25,10 +27,16 @@ https://eu1.servers10.com:8081/8056/index.m3u8
http://canal.mediaserver.com.co/live/telemorisco.m3u8
#EXTINF:-1 tvg-id="CanalDos.co@SD",Canal Dos Yopal (720p)
http://131.221.41.94/hls/canal2.m3u8
+#EXTINF:-1 tvg-id="CanalCalimaTV.co@SD",Canal Calima TV (720p)
+https://cdn.amelbasoluciones.co:8081/calimalive/index.m3u8
#EXTINF:-1 tvg-id="CanalMasTelevision.co@SD",Canal Más Televisión (720p)
https://movil.ejeserver.com/live/teledoradahd.m3u8
#EXTINF:-1 tvg-id="CanalMasTelevision.co@SD",Canal Más Televisión (720p)
https://video.ejeserver.com/live/teledoradahd.m3u8
+#EXTINF:-1 tvg-id="CanalMundoVision.co@SD",Canal Mundo Visión (720p) [Not 24/7]
+https://movil.ejeserver.com/live/mundovisiontv.m3u8
+#EXTINF:-1 tvg-id="CanalMundoVision.co@SD",Canal Mundo Visión (720p) [Not 24/7]
+https://video.ejeserver.com/live/mundovisiontv.m3u8
#EXTINF:-1 tvg-id="CanalNets.co@SD",Canal Nets (720p) [Not 24/7]
https://movil.ejeserver.com/live/nets.m3u8
#EXTINF:-1 tvg-id="CanalNets.co@SD",Canal Nets (720p) [Not 24/7]
@@ -37,6 +45,8 @@ https://video.ejeserver.com/live/nets.m3u8
https://canal.mediaserver.com.co/live/oracionconson.m3u8
#EXTINF:-1 tvg-id="CanalRCN.co@SD",Canal RCN (480p)
http://38.183.182.166:8000/play/a10i/index.m3u8
+#EXTINF:-1 tvg-id="CanalSantaMartaTV.co@SD",Canal Santa Marta TV (720p) [Not 24/7]
+https://cdn.amelbasoluciones.co:8081/santamartalive/index.m3u8
#EXTINF:-1 tvg-id="CanalTelefamilia.co@SD",Canal Telefamilia (360p) [Not 24/7]
https://stmv2.voxtvhd.com.br/telefamilia/telefamilia/playlist.m3u8
#EXTINF:-1 tvg-id="CanalTRO.co@SD",Canal TRO (1080p)
@@ -45,50 +55,72 @@ https://liveingesta118.cdnmedia.tv/canaltro2live/smil:live.smil/playlist.m3u8
#EXTINF:-1 tvg-id="CanalTROPlus.co@SD",Canal TRO Plus (1080p) [Geo-blocked]
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 CrKey/1.44.191160
https://liveingesta118.cdnmedia.tv/canaltro2live/smil:troplus.smil/playlist.m3u8
-#EXTINF:-1 tvg-id="",Caracol Noticias Ahora (720p)
-https://mdstrm.com/live-stream-playlist/632391734be92a791e2750e6.m3u8
-#EXTINF:-1 tvg-id="CaracolTV.co@SD",Caracol TV [Not 24/7]
+#EXTINF:-1 tvg-id="",Canal TV3 (720p) [Not 24/7]
+https://streaming.telenetdigital.net.co:8086/canal3tv/stream.m3u8
+#EXTINF:-1 tvg-id="CanicaTV.co@SD",Canica TV (240p)
+https://stmv4.voxtvhd.com.br/canicatv/canicatv/playlist.m3u8
+#EXTINF:-1 tvg-id="CaracolTV.co@SD",Caracol TV (1080p) [Not 24/7]
http://170.244.209.135:8000/play/a0cz/index.m3u8
#EXTINF:-1 tvg-id="ChampionTV.co@SD",Champion TV (1080p)
https://canal.mediaserver.com.co/live/ChampionTv.m3u8
-#EXTINF:-1 tvg-id="CMBTelevision.co@SD",CMB Television (1080p)
+#EXTINF:-1 tvg-id="CMBTelevision.co@SD",CMB Televisión (1080p)
https://catv.cmbcolombia.tv/bethesda/bethesda/chunklist.m3u8
+#EXTINF:-1 tvg-id="CNCBugavision.co@SD",CNC Bugavisión (720p)
+https://movil.ejeserver.com/live/cncbuga.m3u8
+#EXTINF:-1 tvg-id="CNCBugavision.co@SD",CNC Bugavisión (720p)
+https://video.ejeserver.com/live/cncbuga.m3u8
+#EXTINF:-1 tvg-id="CNCChoco.co@SD",CNC Chocó (720p) [Not 24/7]
+https://hvtraficonew.ddns.net/corescomunicaciones/index.fmp4.m3u8
#EXTINF:-1 tvg-id="CNCHDOnline.co@SD",CNC HD Online (1080p) [Geo-blocked]
https://hvtraficonew.ddns.net/pastocnc6/cnc6/playlist.m3u8
+#EXTINF:-1 tvg-id="CNCLaUnion.co@SD",CNC La Unión (720p) [Not 24/7]
+https://cdn.streamtech.com.co/cnclaunion/streams/xqujjFzO6xsKIDbS1371921740891.m3u8
#EXTINF:-1 tvg-id="CNCPasto.co@SD",CNC Pasto (720p) [Geo-blocked]
https://hvtraficonew.ddns.net/pastocnc9/cnc9/playlist.m3u8
+#EXTINF:-1 tvg-id="CNCPereira.co@SD",CNC Pereira (720p)
+https://cloudpro.servidoresdestream.com:19360/latinchanel/latinchanel.m3u8
#EXTINF:-1 tvg-id="CNCSantanderdeQuilichao.co@SD",CNC Santander de Quilichao (480p)
https://movil.ejeserver.com/live/cncsantander.m3u8
#EXTINF:-1 tvg-id="CNCSantanderdeQuilichao.co@SD",CNC Santander de Quilichao (480p)
https://video.ejeserver.com/live/cncsantander.m3u8
-#EXTINF:-1 tvg-id="Cosmovision.co@SD",Cosmovision (720p)
+#EXTINF:-1 tvg-id="CNCTulua.co@SD",CNC Tuluá (720p)
+https://cdn.amelbasoluciones.co:8081/cnctulualive/index.m3u8
+#EXTINF:-1 tvg-id="Cosmovision.co@SD",Cosmovision (720p) [Geo-blocked]
https://videohls2.cosmovision.tv/hls/sd.m3u8
#EXTINF:-1 tvg-id="Cristovision.co@SD",Cristovisión (480p)
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 CrKey/1.44.191160
https://liveingesta118.cdnmedia.tv/cristovisiontvlive/smil:rtmp01.smil/playlist.m3u8
#EXTINF:-1 tvg-id="CTV.co@SD",CTV Barranquilla (1080p) [Not 24/7]
https://59a564764e2b6.streamlock.net/ctvbarranquilla/ctv/playlist.m3u8
+#EXTINF:-1 tvg-id="CucutaRetroTV.co@SD",Cúcuta Retro TV [Not 24/7]
+https://mist01.homestream.fun/hls/ntvlive/0_1/index.m3u8
#EXTINF:-1 tvg-id="Eduvision.co@SD",Eduvision (1080p)
https://stmv3.voxtvhd.com.br/conex2/conex2/playlist.m3u8
-#EXTINF:-1 tvg-id="EnlaceTelevision.co@SD",Enlace Television
-https://edge.teveo.net/live/AeAAAgAFAADLA1IAyADIQCAAAAAAAAAAAmg0131AIAByAAAA/playlist.m3u8
#EXTINF:-1 tvg-id="Eureka.co@SD",Eureka
https://cdns.livewave.co:19360/eurekatv/eurekatv.m3u8
#EXTINF:-1 tvg-id="FrecuenciaFTV.co@SD",Frecuencia F TV (1080p)
https://tv.frecuenciaf.com/live/envivo.m3u8
+#EXTINF:-1 tvg-id="HeliconiaRadioTV.co@SD",Heliconia Radio TV (720p)
+https://rtv.fullhd-streaming.com:19360/heliconiaradiotv/heliconiaradiotv.m3u8
+#EXTINF:-1 tvg-id="KaluTV.co@SD",Kalu TV (720p)
+https://tv.kaludecolombia.com/memfs/800a956d-5ada-4bf1-ac15-0d11e689179c.m3u8
+#EXTINF:-1 tvg-id="LaMoradaRadioTV.co@SD",La Morada Radio TV (720p)
+https://movil.ejeserver.com/live/lamoradatv.m3u8
#EXTINF:-1 tvg-id="LaHermandadSalsera.co@SD",La Hermandad Salsera (1080p) [Not 24/7]
https://streamlov.alsolnet.com/hermandadsalsera/live/playlist.m3u8
#EXTINF:-1 tvg-id="LaKalle.co@SD",La Kalle (720p)
https://mdstrm.com/live-stream-playlist/58d191f07290fbb058025843.m3u8
#EXTINF:-1 tvg-id="LunaEstereo1064FM.co@SD",Luna Estéreo 106.4 FM (720p) [Not 24/7]
https://servervideo.intermediacolombia.com:19360/kychbbfhdz/kychbbfhdz.m3u8
+#EXTINF:-1 tvg-id="MasNorteTV.co@SD",Mas Norte TV [Not 24/7]
+https://live.arnoproducciones.com/hls/norte.m3u8
#EXTINF:-1 tvg-id="MasMusicaFM.co@SD",MasMusica FM (720p)
https://movil.ejeserver.com/live/masmusica.m3u8
#EXTINF:-1 tvg-id="MasMusicaFM.co@SD",MasMusica FM (720p)
https://video.ejeserver.com/live/masmusica.m3u8
#EXTINF:-1 tvg-id="MaxTV.co@HD",MaxTV [Not 24/7]
https://inliveserver.com:1936/8078/8078/playlist.m3u8
-#EXTINF:-1 tvg-id="MCITelevision.co@SD",MCI Television
+#EXTINF:-1 tvg-id="MCITelevision.co@SD",MCI Televisión (1080p)
https://video.ejeserver.com/live/mcitelevision.m3u8
#EXTINF:-1 tvg-id="MiGenteTV.co@SD",Mi Gente TV (720p) [Geo-blocked]
https://byecableiptvnew3.ddns.net/ENVIVOMIGENTE/video.m3u8
@@ -104,21 +136,35 @@ https://stmv4.voxtvhd.com.br/nstv/nstv/playlist.m3u8
https://5e85d90130e77.streamlock.net/6020/6020/playlist.m3u8
#EXTINF:-1 tvg-id="OndambientalTV.co@SD",Ondambiental TV (360p)
https://stmv4.voxtvhd.com.br/ondastereo/ondastereo/playlist.m3u8
+#EXTINF:-1 tvg-id="ParrandaVallenata.co@SD",Parranda Vallenata (720p)
+https://backupmaxmedia.hvmultiplay.com/hls/stream3/parrandavallenata.m3u8
+#EXTINF:-1 tvg-id="RCNMas.co@SD",RCN Mas
+https://uvotv-aniview.global.ssl.fastly.net/hls/live/2119960/rcnmas/playlist.m3u8
#EXTINF:-1 tvg-id="RedPlus.co@SD",Red+ (1080p)
https://inforedvos.lcdn.claro.net.co/Content/HLS_HLS_DIR/Live/channel(REDMASHDWEB)/master.m3u8
#EXTINF:-1 tvg-id="Reyali.co@SD",Reyali (614p)
https://eu1.servers10.com:8081/8090/index.m3u8
+#EXTINF:-1 tvg-id="RioTelevision.co@SD",Río Televisión [Geo-blocked]
+https://cdn.amelbasoluciones.co:8081/riotv/index.fmp4.m3u8
+#EXTINF:-1 tvg-id="RTCTelevision.co@SD",RTC Televisión Urabá (720p)
+https://cdn.amelbasoluciones.co:8081/rtcurabalive/index.m3u8
#EXTINF:-1 tvg-id="SalsaGordaTelevision.co@SD",Salsa Gorda Television (1080p) [Not 24/7]
https://live20.bozztv.com/akamaissh101/ssh101/qMUAZEy/playlist.m3u8
#EXTINF:-1 tvg-id="SalsaGordaTelevision.co@SD",Salsa Gorda Television (1080p) [Not 24/7]
https://www.televinterserver.com:19360/salsagordatv/salsagordatv.m3u8
+#EXTINF:-1 tvg-id="SupermusicaTV.co@SD",Supermúsica TV (720p)
+https://backupmaxmedia.hvmultiplay.com/hls/stream4/supermusica.m3u8
#EXTINF:-1 tvg-id="SuramTV.co@SD",Suram TV (1080p)
https://livetv.305streamhd.com:3111/live/suramtvlive.m3u8
-#EXTINF:-1 tvg-id="SuramTV.co@SD",Suram TV
+#EXTINF:-1 tvg-id="SuramTV.co@SD",Suram TV (720p)
https://us.streaminghd.cl/suramtv/index.m3u8
#EXTINF:-1 tvg-id="TeleAmiga.co@SD",Tele Amiga (480p) [Not 24/7]
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 CrKey/1.44.191160
https://liveingesta118.cdnmedia.tv/teleamigatvlive/smil:dvrlive.smil/playlist.m3u8
+#EXTINF:-1 tvg-id="Telebolivar.co@SD",Telebolívar (720p)
+https://live20.bozztv.com/akamaissh101/ssh101/telebolivar/playlist.m3u8
+#EXTINF:-1 tvg-id="TeleCesar.co@SD",TeleCesar (432p)
+https://eu1.servers10.com:8081/8020/index.m3u8
#EXTINF:-1 tvg-id="TeleSanJacinto.co@SD",Tele San Jacinto (720p)
https://movil.ejeserver.com/live/telesanjacinto.m3u8
#EXTINF:-1 tvg-id="TeleSanJacinto.co@SD",Tele San Jacinto (720p)
@@ -143,22 +189,34 @@ https://liveingesta118.cdnmedia.tv/telecaribetvlive/smil:rtmp01.smil/playlist.m3
https://liveingesta118.cdnmedia.tv/telecaribetvlive/smil:rtmp02.smil/playlist.m3u8
#EXTINF:-1 tvg-id="Teleislas.co@SD",Teleislas (486p) [Not 24/7]
https://5ab772334c39c.streamlock.net/live-teleislas/teleislas/playlist.m3u8
-#EXTINF:-1 tvg-id="Telepacifico.co@SD",Telepacifico (1080p)
+#EXTINF:-1 tvg-id="TeleMocoaCanal10.co@SD",Tele Mocoa Canal 10 (1080p)
+https://cdn.amelbasoluciones.co:8081/telemocoalive/index.m3u8
+#EXTINF:-1 tvg-id="Telepacifico.co@SD",Telepacífico (1080p) [Geo-blocked]
https://play.cdn.enetres.net/6E5C615AA5FF4123ACAF0DAB57B7B8DC021/022/playlist.m3u8
-#EXTINF:-1 tvg-id="Telepetroleo.co@SD",Telepetroleo
-https://edge.teveo.net/live/AeAAAgAIAAE7A1IAyADIUCAAAAAAAAAAAmg0285AIAByAAAA/playlist.m3u8
+#EXTINF:-1 tvg-id="",TeveColombia (720p) [Not 24/7]
+https://cloud6.livescast.com:3900/live/tevecolombialive.m3u8
#EXTINF:-1 tvg-id="Trece.co@SD",Trece (720p)
https://stream.logicideas.media/canaltrece-live/smil:live.smil/playlist.m3u8
-#EXTINF:-1 tvg-id="TrecePlus.co@SD",Trece + (720p)
+#EXTINF:-1 tvg-id="TrecePlus.co@SD",Trece+ (720p)
https://stream.logicideas.media/canaltreceplus-live/smil:live1plus.smil/playlist.m3u8
#EXTINF:-1 tvg-id="TrecePlus.co@SD",Trece+ (480p)
http://190.2.212.209:8050/play/a0nf
#EXTINF:-1 tvg-id="TuUniversoTV.co@SD",Tu Universo TV (720p)
https://5bf8041cb3fed.streamlock.net/TUUNIVERSOTV/TUUNIVERSOTV/playlist.m3u8
+#EXTINF:-1 tvg-id="TV3LaPlata.co@SD",TV3 La Plata (720p)
+https://cdn.amelbasoluciones.co:8081/teleopitalive/index.m3u8
#EXTINF:-1 tvg-id="TVPenol.co@SD",TV Peñol (720p)
https://stmv1.voxtvhd.com.br/tvpenol/tvpenol/playlist.m3u8
+#EXTINF:-1 tvg-id="TVRivera.co@SD",TV Rivera [Not 24/7]
+https://movil.ejeserver.com/live/tvrivera.m3u8
+#EXTINF:-1 tvg-id="TVRivera.co@SD",TV Rivera [Not 24/7]
+https://video.ejeserver.com/live/tvrivera.m3u8
#EXTINF:-1 tvg-id="TVSanJorge.co@SD",TV San Jorge (1080p) [Not 24/7]
https://asucap.com/livestream/asucap_envivo.m3u8
+#EXTINF:-1 tvg-id="UltraCasanareTV.co@SD",Ultra Casanare TV (1080p) [Not 24/7]
+https://eu1.servers10.com:8081/8072/index.m3u8
+#EXTINF:-1 tvg-id="UMCTV.co@SD",UMC TV (720p)
+https://streaming5.globalhostla.com/rtplive/unamirad/playlist.m3u8
#EXTINF:-1 tvg-id="ViveTV.co@SD",Vive TV Colombia (1080p)
http://192.144.113.132:1935/live/ViveTV/playlist.m3u8
#EXTINF:-1 tvg-id="Zoom.co@SD",Zoom (1080p)
diff --git a/streams/fr.m3u b/streams/fr.m3u
index 0eba1c816c..b1c2ffa092 100644
--- a/streams/fr.m3u
+++ b/streams/fr.m3u
@@ -361,3 +361,5 @@ https://viamotionhsi.netplus.ch/live/eds/w9/browser-HLS8/w9.m3u8
https://viamotionhsi.netplus.ch/live/eds/w9/browser-dash/w9.mpd
#EXTINF:-1 tvg-id="T18.fr@HD",T18
https://viamotionhsi.netplus.ch/live/eds/t18/browser-HLS8/t18.m3u8
+#EXTINF:-1 tvg-id="TV5MondeAsia.fr@SD",TV5Monde Asia (720p)
+https://liveh12.vtvprime.vn/hls/TV5/03.m3u8
diff --git a/streams/gh.m3u b/streams/gh.m3u
index 817e9fa199..c3b43efeee 100644
--- a/streams/gh.m3u
+++ b/streams/gh.m3u
@@ -3,8 +3,6 @@
https://mediagh.us:19360/deliverancetv/deliverancetv.m3u8
#EXTINF:-1 tvg-id="AdinkraTV.gh@SD",Adinkra TV (1080p)
https://59d39900ebfb8.streamlock.net/adinkratvny/adinkratvny/playlist.m3u8
-#EXTINF:-1 tvg-id="AtinkaTV.gh@SD",Atinka TV
-https://g2qd3exjy7an-hls-live.5centscdn.com/atinkkatv/ghanaweb.stream/playlist.m3u8
#EXTINF:-1 tvg-id="Channel247.gh@SD",Channel247 (1080p)
https://tv.localstreamgh.com/Channel247/index.m3u8
#EXTINF:-1 tvg-id="FacultyTV.gh@SD",Faculty TV (720p)
@@ -13,24 +11,14 @@ https://stream-server9-jupiter.muxlive.com/hls/facultytv/index.m3u8
https://tv.localstreamgh.com/fishtv/index.m3u8
#EXTINF:-1 tvg-id="",G-eye TV
https://online.geyetv.com/hls/stream.m3u8
-#EXTINF:-1 tvg-id="GhOneTV.gh@SD",Gh One TV
-https://g2qd3exjy7an-hls-live.5centscdn.com/ghonetv/ghanaweb.stream/playlist.m3u8
-#EXTINF:-1 tvg-id="GTV.gh@SD",GTV
-https://g2qd3exjy7an-hls-live.5centscdn.com/gtvghana/ghanaweb.stream/playlist.m3u8
-#EXTINF:-1 tvg-id="GTVSportsPlus.gh@SD",GTV Sports +
-https://g2qd3exjy7an-hls-live.5centscdn.com/gtvsport/ghanaweb.stream/playlist.m3u8
#EXTINF:-1 tvg-id="Hope4LifeTV.us@SD",Hope4Life TV (720p)
http://144.217.14.88/hls/hope4life.m3u8
#EXTINF:-1 tvg-id="HopeChannelGhana.gh@SD",Hope Channel Ghana (480p)
https://videodelivery.net/dfbdca87f2a6291aa4fdc8fe3290769b/manifest/video.m3u8
-#EXTINF:-1 tvg-id="JoyPrime.gh@SD",Joy Prime
-https://g2qd3exjy7an-hls-live.5centscdn.com/joyprim/ghanaweb.stream/playlist.m3u8
#EXTINF:-1 tvg-id="MaranathaTV.gh@SD",Maranatha TV
https://media.streambrothers.com:1936/8298/8298/playlist.m3u8
#EXTINF:-1 tvg-id="MaxTV.gh@SD",Max TV
https://tv.qixapps.com/hls/006bea00-06e8-440e-babe-0a588e1138f2.m3u8
-#EXTINF:-1 tvg-id="MetroTV.gh@SD",Metro TV
-https://g2qd3exjy7an-hls-live.5centscdn.com/metrotvg/ghanaweb.stream/playlist.m3u8
#EXTINF:-1 tvg-id="MOGPATV.gh@SD",MOGPA TV (720p)
https://livestream.anojed.com/ablazetv/f7b44cfafd5c52223d5498196c8a2e7b.sdp/playlist.m3u8
#EXTINF:-1 tvg-id="MOGPATV.gh@SD",MOGPA TV
@@ -43,11 +31,5 @@ https://5dcabf026b188.streamlock.net/OceansTV/livestream/playlist.m3u8
https://iptv-trans.ecntv.net/live/penttv.m3u8
#EXTINF:-1 tvg-id="ResurrectionTV.gh@SD",Resurrection TV (720p)
https://1681360479.rsc.cdn77.org/1681360479/index.m3u8
-#EXTINF:-1 tvg-id="TV3.gh@SD",TV3 (720p) [Not 24/7]
-https://live.mediageneral.digital/live/livestream.m3u8
-#EXTINF:-1 tvg-id="TV3.gh@SD",TV3
-https://g2qd3exjy7an-hls-live.5centscdn.com/webtv3/ghanatv.stream/playlist.m3u8
-#EXTINF:-1 tvg-id="UnitedTV.gh@SD",United TV
-https://g2qd3exjy7an-hls-live.5centscdn.com/utvgha/ghanaweb.stream/playlist.m3u8
#EXTINF:-1 tvg-id="TV3.gh@SD",TV3
https://adesa.tv/live/tv3_AdesaAdb.m3u8
diff --git a/streams/jp.m3u b/streams/jp.m3u
index 12d21a4577..2a1c4f1041 100644
--- a/streams/jp.m3u
+++ b/streams/jp.m3u
@@ -48,8 +48,6 @@ https://media-tyo.hls.nhkworld.jp/hls/w/live/master.m3u8
https://nhkworld-tv.akamaized.net/hls/live/2115640/nhkworld-tv/index_1M.m3u8
#EXTINF:-1 tvg-id="NHKWorldJapan.jp@SD",NHK World-Japan
https://cdn4.skygo.mn/live/disk1/NHK_World/HLSv3-FTA/NHK_World.m3u8
-#EXTINF:-1 tvg-id="NHKWorldJapan.jp@HD",NHK World-Japan HD (1080i)
-https://hls.mskycdn.online/tv/nhkworld/index.m3u8
#EXTINF:-1 tvg-id="NHKWorldJapan.jp@HD",NHK World-Japan HD
https://nhk.lls.pbs.org/index.m3u8
#EXTINF:-1 tvg-id="NHKWorldJapan.jp@HD",NHK World-Japan HD
diff --git a/streams/uk.m3u b/streams/uk.m3u
index 3e3f49b542..2105262809 100644
--- a/streams/uk.m3u
+++ b/streams/uk.m3u
@@ -338,3 +338,5 @@ https://jmp2.uk/stvp-GB340000289
https://4bc5d2b3.wurl.com/v1/asia_tv_limited_zeeworld_1/ohlscdn_us/V00000001/7200/HLS/playlist.m3u8
#EXTINF:-1 tvg-id="FaithWorldTV.uk@SD",Faith World TV
https://faithworldtv.abs.tv/1826926230/index.m3u8
+#EXTINF:-1 tvg-id="FIFAPlusWomen.uk@English",FIFA+ Women (720p)
+https://cffda8ff.wurl.com/master/f36d25e7e52f1ba8d7e56eb859c636563214f541/U2Ftc3VuZy1nYl9GSUZBUGx1c3dvbWVuX0hMUw/playlist.m3u8
diff --git a/streams/us.m3u b/streams/us.m3u
index ec0d3def27..8106274027 100644
--- a/streams/us.m3u
+++ b/streams/us.m3u
@@ -1313,3 +1313,7 @@ https://video1.getstreamhosting.com:1936/8560/8560/playlist.m3u8
https://2-fss-1.streamhoster.com/pl_122/202676-1357858-1/playlist.m3u8
#EXTINF:-1 tvg-id="COStv.us@SD",COStv
https://irctv.cablecast.tv/live/stream-1/live.m3u8
+#EXTINF:-1 tvg-id="MBCAmerica.us@SD",MBC America (1080p)
+https://cdn-us-east-prod-ingest-infra-dacast-com.akamaized.net/624ff8f9-db18-da92-4d42-896fa2ff3eb3/source/index.m3u8
+#EXTINF:-1 tvg-id="StingrayGreatestHolidayHits.us@SD",Stingray Greatest Holiday Hits
+https://d39g1vxj2ef6in.cloudfront.net/v1/manifest/3fec3e5cac39a52b2132f9c66c83dae043dc17d4/prod-rakuten-stitched/54947915-6504-4548-aaef-eabd451f8607/1.m3u8
diff --git a/tests/__data__/expected/playlist_test/ag.m3u b/tests/__data__/expected/playlist_test/ag.m3u
new file mode 100644
index 0000000000..16dc963ff6
--- /dev/null
+++ b/tests/__data__/expected/playlist_test/ag.m3u
@@ -0,0 +1,3 @@
+#EXTM3U
+#EXTINF:-1 tvg-id="ABSTV.ag",ABS TV
+https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145
diff --git a/tests/__data__/input/playlist_test/results.js b/tests/__data__/input/playlist_test/results.js
index 1899543830..58ecd5e05e 100644
--- a/tests/__data__/input/playlist_test/results.js
+++ b/tests/__data__/input/playlist_test/results.js
@@ -3,7 +3,7 @@ module.exports = {
{
url: 'https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3',
http: { referrer: '', 'user-agent': '' },
- status: { ok: false, code: 'HTTP_NOT_FOUND', message: 'HTTP 404 Not Found' }
+ status: { ok: false, code: 'HTTP_404_NOT_FOUND', message: 'HTTP 404 Not Found' }
},
'https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145':
{
diff --git a/tests/__data__/input/playlist_test/ag.m3u b/tests/__data__/input/playlist_test/streams/ag.m3u
similarity index 90%
rename from tests/__data__/input/playlist_test/ag.m3u
rename to tests/__data__/input/playlist_test/streams/ag.m3u
index f4716e013b..71345f8cc4 100644
--- a/tests/__data__/input/playlist_test/ag.m3u
+++ b/tests/__data__/input/playlist_test/streams/ag.m3u
@@ -2,4 +2,4 @@
#EXTINF:-1 tvg-id="ABSTV.ag",ABS TV
https://tego-cdn2a.sibercdn.com/Live_TV-ABSTV-10/tracks-v3a1/rewind-7200.m3u8?token=e5f61e7be8363eb781b4bdfe591bf917dd529c1a-SjY3NzRTbDZQNnFQVkZaNkZja2RxV3JKc1VBa05zQkdMNStJakRGV0VTTzNrOEVGVUlIQmxta1NLV0o3bzdVdQ-1736094545-1736008145
#EXTINF:-1 tvg-id="ABSTV.ag@HD",ABS TV (1080p) [Not 24/7]
-https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3
\ No newline at end of file
+https://query-streamlink.herokuapp.com/iptv-query?streaming-ip=https://www.twitch.tv/absliveantigua3
diff --git a/tests/commands/playlist/test.test.ts b/tests/commands/playlist/test.test.ts
index 1bf978b016..1deeacda75 100644
--- a/tests/commands/playlist/test.test.ts
+++ b/tests/commands/playlist/test.test.ts
@@ -1,21 +1,62 @@
-import { execSync } from 'child_process'
+import child_process from 'node:child_process'
+import { pathToFileURL } from 'node:url'
+import { promisify } from 'node:util'
+import * as fs from 'fs-extra'
+import { glob } from 'glob'
+
+const exec = promisify(child_process.exec)
type ExecError = {
status: number
stdout: string
}
-const ENV_VAR = 'cross-env ROOT_DIR=tests/__data__/input DATA_DIR=tests/__data__/input/data'
+const ENV_VAR = 'cross-env DATA_DIR=tests/__data__/input/data ROOT_DIR=tests/__data__/output'
+
+beforeEach(() => {
+ fs.emptyDirSync('tests/__data__/output')
+ fs.copySync('tests/__data__/input/playlist_test/streams', 'tests/__data__/output/streams')
+})
describe('playlist:test', () => {
- it('shows an error if the playlist contains a broken link', () => {
- const cmd = `${ENV_VAR} npm run playlist:test playlist_test/ag.m3u`
+ it('shows an error if the playlist contains a broken link', async () => {
+ const cmd = `${ENV_VAR} npm run playlist:test streams/ag.m3u`
+
try {
- execSync(cmd, { encoding: 'utf8' })
+ await exec(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd)
+ process.exit(0)
} catch (error) {
if (process.env.DEBUG === 'true') console.log(cmd, error)
- expect((error as ExecError).stdout).toContain('playlist_test/ag.m3u')
+ expect((error as ExecError).stdout).toContain('streams/ag.m3u')
expect((error as ExecError).stdout).toContain('2 problems (1 errors, 1 warnings)')
}
})
+
+ it('it can remove all broken links from the playlist', async () => {
+ const cmd = `${ENV_VAR} npm run playlist:test streams/ag.m3u --- --fix`
+ try {
+ await exec(cmd, { encoding: 'utf8' })
+ if (process.env.DEBUG === 'true') console.log(cmd)
+ process.exit(0)
+ } catch (error) {
+ if (process.env.DEBUG === 'true') console.log(cmd, error)
+ const files = glob.sync('tests/__data__/expected/playlist_test/*.m3u').map(filepath => {
+ const fileUrl = pathToFileURL(filepath).toString()
+ const pathToRemove = pathToFileURL('tests/__data__/expected/playlist_test/').toString()
+
+ return fileUrl.replace(pathToRemove, '')
+ })
+
+ files.forEach(filepath => {
+ expect(content(`tests/__data__/output/streams/${filepath}`)).toBe(
+ content(`tests/__data__/expected/playlist_test/${filepath}`)
+ )
+ })
+ }
+ })
})
+
+function content(filepath: string) {
+ return fs.readFileSync(pathToFileURL(filepath), { encoding: 'utf8' })
+}