From c60088bc097b23cb3ce6fee3cf5a86ae7140c140 Mon Sep 17 00:00:00 2001 From: boomski Date: Tue, 29 Oct 2019 20:55:59 +0100 Subject: [PATCH 1/4] Update tr.m3u --- channels/tr.m3u | 2 ++ 1 file changed, 2 insertions(+) diff --git a/channels/tr.m3u b/channels/tr.m3u index 23e48c746..7d0291b5b 100644 --- a/channels/tr.m3u +++ b/channels/tr.m3u @@ -1,4 +1,6 @@ #EXTM3U x-tvg-url="http://195.154.221.171/epg/guideturkey.xml.gz" +#EXTINF:-1 tvg-logo="https://i.imgur.com/aJDmVr3.png",Teve 2 +https://teve2.dogannet.tv/S2/HLS_LIVE/teve2np/track_4_1000/playlist.m3u8 #EXTINF:-1 tvg-logo="https://i.imgur.com/z8D2zT1.png",Kanal 5 https://59cba4d34b678.streamlock.net/canlitv/kanal5/chunklist.m3u8 #EXTINF:-1 tvg-id="A Haber TR" tvg-name="A Haber TR" tvg-logo="https://i.imgur.com/SmCjRrW.jpg" group-title="News",A Haber From fc39bcebce646c81a0485430343aae900e827ba7 Mon Sep 17 00:00:00 2001 From: freearhey Date: Wed, 30 Oct 2019 18:44:26 +0300 Subject: [PATCH 2/4] Installed epg-parser package --- helpers/format.js | 28 +++++++++++++++------------- helpers/util.js | 34 ++++++++-------------------------- package-lock.json | 24 ++++++++++++++++++++++++ package.json | 1 + 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/helpers/format.js b/helpers/format.js index bf3c48dd0..421788da3 100644 --- a/helpers/format.js +++ b/helpers/format.js @@ -87,14 +87,16 @@ async function main() { for(let channel of channels) { for(let channelId in buffer[epgUrl].channels) { let c = buffer[epgUrl].channels[channelId] - for(let epgName of c.names) { - epgName = escapeStringRegexp(epgName) - channelTitle = channel.title.replace(/(fhd|hd|sd|高清)$/i, '').trim() - let regexp = new RegExp(`^${epgName}$`, 'i') - if(regexp.test(channelTitle)) { - if(!channel.id) { - channel.id = c.id - continue + for(let epgName of c.name) { + if(epgName.value) { + let escaped = escapeStringRegexp(epgName.value) + channelTitle = channel.title.replace(/(fhd|hd|sd|高清)$/i, '').trim() + let regexp = new RegExp(`^${escaped}$`, 'i') + if(regexp.test(channelTitle)) { + if(!channel.id) { + channel.id = c.id + continue + } } } } @@ -111,16 +113,16 @@ async function main() { if(!c) continue let updated = false - if(!channel.name && c.names[0]) { - channel.name = c.names[0] + if(!channel.name && c.name.length) { + channel.name = c.name[0].value updated = true if(verbose) { - console.log(`Added name '${c.names[0]}' to '${channel.id}'`) + console.log(`Added name '${c.name[0].value}' to '${channel.id}'`) } } - if(!channel.logo && c.icon) { - const icon = c.icon.split('|')[0] + if(!channel.logo && c.icon.length) { + const icon = c.icon[0].split('|')[0] channel.logo = icon updated = true if(verbose) { diff --git a/helpers/util.js b/helpers/util.js index d982de91b..f815a8afd 100644 --- a/helpers/util.js +++ b/helpers/util.js @@ -3,7 +3,7 @@ const path = require('path') const parser = require('iptv-playlist-parser') const axios = require('axios') const zlib = require("zlib") -const DOMParser = require('xmldom').DOMParser +const epgParser = require('epg-parser') const urlParser = require('url') const supportedCategories = [ 'Auto','Business', 'Classic','Comedy','Documentary','Education','Entertainment', 'Family','Fashion','Food', 'General', 'Health', 'History', 'Hobby', 'Kids', 'Legislative','Lifestyle','Local', 'Movies', 'Music', 'News', 'Quiz', 'Religious','Sci-Fi', 'Shop', 'Sport', 'Travel', 'Weather', 'XXX' ] @@ -78,38 +78,20 @@ function createChannel(data) { } async function loadEPG(url) { - const data = await getGzipped(url) - const doc = new DOMParser().parseFromString(data, 'text/xml') - const channelElements = doc.getElementsByTagName('channel') - let channels = {} - for(let i = 0; i < channelElements.length; i++) { - let channel = {} - let channelElement = channelElements[i] - channel.id = channelElement.getAttribute('id') - channel.names = [] - for(let nameElement of Object.values(channelElement.getElementsByTagName('display-name'))) { - if(nameElement.firstChild) { - channel.names.push(nameElement.firstChild.nodeValue) - } - } - channel.names = channel.names.filter(n => n) - const iconElements = channelElement.getElementsByTagName('icon') - if(iconElements.length) { - channel.icon = iconElements[0].getAttribute('src') - } - + const content = await getEPGFile(url) + const result = epgParser.parse(content) + const channels = {} + for(let channel of result.channels) { channels[channel.id] = channel } return Promise.resolve({ url, - channels + channels }) } -function getGzipped(url) { - const supportedTypes = ['application/x-gzip', 'application/octet-stream'] - +function getEPGFile(url) { return new Promise((resolve, reject) => { var buffer = [] axios({ @@ -118,7 +100,7 @@ function getGzipped(url) { responseType:'stream' }).then(res => { let stream - if(supportedTypes.indexOf(res.headers['content-type']) > -1) { + if(/\.gz$/i.test(url)) { let gunzip = zlib.createGunzip() res.data.pipe(gunzip) stream = gunzip diff --git a/package-lock.json b/package-lock.json index a439baefd..dc8562333 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,15 @@ "xregexp": "^4.2.4" } }, + "epg-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/epg-parser/-/epg-parser-0.1.1.tgz", + "integrity": "sha512-gzbrIcpoI+yzX2GK20Whuqp7DjbHTLX/NI9eY7Y82qqreJuZcFRs/SDXyeZ2Tp5CqcTgpFvD/Op3I1mDQG8NGQ==", + "dev": true, + "requires": { + "xml-js": "^1.6.11" + } + }, "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -133,6 +142,12 @@ "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", "dev": true }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -142,6 +157,15 @@ "isexe": "^2.0.0" } }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dev": true, + "requires": { + "sax": "^1.2.4" + } + }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index d7c905783..9dcfaa3be 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": {}, "devDependencies": { "axios": ">=0.18.1", + "epg-parser": "^0.1.1", "escape-string-regexp": "^2.0.0", "fluent-ffmpeg": "^2.1.2", "iptv-playlist-parser": "^0.2.2", From 3f0f9ae06639af92fb06a5e7f9a974db8e2be91d Mon Sep 17 00:00:00 2001 From: freearhey Date: Wed, 30 Oct 2019 20:19:54 +0300 Subject: [PATCH 3/4] Added support of tvg-language attribute --- helpers/format.js | 10 ++++++++++ helpers/util.js | 3 ++- package-lock.json | 24 +++++++++++++++--------- package.json | 3 ++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/helpers/format.js b/helpers/format.js index 421788da3..b18588a72 100644 --- a/helpers/format.js +++ b/helpers/format.js @@ -1,5 +1,6 @@ const util = require('./util') const escapeStringRegexp = require('escape-string-regexp') +const ISO6391 = require('iso-639-1') const debug = false const verbose = false @@ -121,6 +122,15 @@ async function main() { } } + if(!channel.language && c.name.length && c.name[0].lang) { + let language = ISO6391.getName(c.name[0].lang) + channel.language = language + updated = true + if(verbose) { + console.log(`Added language '${language}' to '${channel.id}'`) + } + } + if(!channel.logo && c.icon.length) { const icon = c.icon[0].split('|')[0] channel.logo = icon diff --git a/helpers/util.js b/helpers/util.js index f815a8afd..3ac8eec1f 100644 --- a/helpers/util.js +++ b/helpers/util.js @@ -39,6 +39,7 @@ class Channel { constructor(data) { this.id = data.tvg.id this.name = data.tvg.name + this.language = data.tvg.language this.logo = data.tvg.logo this.group = this._getGroup(data.group.title) this.url = data.url @@ -60,7 +61,7 @@ class Channel { } toString() { - const info = `-1 tvg-id="${this.id}" tvg-name="${this.name}" tvg-logo="${this.logo}" group-title="${this.group}",${this.title}` + const info = `-1 tvg-id="${this.id}" tvg-name="${this.name}" tvg-language="${this.language}" tvg-logo="${this.logo}" group-title="${this.group}",${this.title}` return '#EXTINF:' + info + '\n' + this.url + '\n' } diff --git a/package-lock.json b/package-lock.json index dc8562333..eb8dca9e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,9 +4,9 @@ "lockfileVersion": 1, "dependencies": { "@babel/runtime-corejs2": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.6.2.tgz", - "integrity": "sha512-wdyVKnTv9Be4YlwF/7pByYNfcl23qC21aAQ0aIaZOo2ZOvhFEyJdBLJClYZ9i+Pmrz7sUQgg/MwbJa2RZTkygg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.6.3.tgz", + "integrity": "sha512-nuA2o+rgX2+PrNTZ063ehncVcg7sn+tU71BB81SaWRVUbGwCOlb0+yQA1e0QqmzOfRSYOxfvf8cosYqFbJEiwQ==", "dev": true, "requires": { "core-js": "^2.6.5", @@ -30,9 +30,9 @@ } }, "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", "dev": true }, "debug": { @@ -88,9 +88,9 @@ } }, "iptv-playlist-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/iptv-playlist-parser/-/iptv-playlist-parser-0.2.2.tgz", - "integrity": "sha512-F0BoyFJNv2NxhAGU/lJnQJ5J6eDktmJdoOi06C4SEuBHv3y61eLNjcbFi/kE9TlAo8Lry4t4U0Io+MOQX3mXHw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/iptv-playlist-parser/-/iptv-playlist-parser-0.3.0.tgz", + "integrity": "sha512-FA9B+8Lh+0KtWWXDaxzFf1DY3QJI+mGCZP/E51XoJcfahnajyyqdfI1ClpQquFHok2CLNqnfbeW6rzJN9TCREg==", "dev": true, "requires": { "decamelize": "^3.2.0", @@ -109,6 +109,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "iso-639-1": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-2.1.0.tgz", + "integrity": "sha512-8CTinLimb9ncAJ11wpCETWZ51qsQ3LS4vMHF2wxRRtR3+b7bvIxUlXOGYIdq0413+baWnbyG5dBluVcezOG/LQ==", + "dev": true + }, "m3u8-file-parser": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/m3u8-file-parser/-/m3u8-file-parser-0.2.2.tgz", diff --git a/package.json b/package.json index 9dcfaa3be..14df31045 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "epg-parser": "^0.1.1", "escape-string-regexp": "^2.0.0", "fluent-ffmpeg": "^2.1.2", - "iptv-playlist-parser": "^0.2.2", + "iptv-playlist-parser": "^0.3.0", + "iso-639-1": "^2.1.0", "markdown-include": "^0.4.3", "xmldom": "^0.1.27" } From f671b5bfce232f6071b2cbca073a4131b5d6552b Mon Sep 17 00:00:00 2001 From: boomski Date: Wed, 30 Oct 2019 23:17:46 +0100 Subject: [PATCH 4/4] Update tr.m3u --- channels/tr.m3u | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channels/tr.m3u b/channels/tr.m3u index 7d0291b5b..ade7ad425 100644 --- a/channels/tr.m3u +++ b/channels/tr.m3u @@ -1,5 +1,5 @@ #EXTM3U x-tvg-url="http://195.154.221.171/epg/guideturkey.xml.gz" -#EXTINF:-1 tvg-logo="https://i.imgur.com/aJDmVr3.png",Teve 2 +#EXTINF:-1 tvg-logo="https://i.imgur.com/aJDmVr3.png",Teve 2 [NO VLC] https://teve2.dogannet.tv/S2/HLS_LIVE/teve2np/track_4_1000/playlist.m3u8 #EXTINF:-1 tvg-logo="https://i.imgur.com/z8D2zT1.png",Kanal 5 https://59cba4d34b678.streamlock.net/canlitv/kanal5/chunklist.m3u8